From 38b9aa4ec4c81e288b4a6606a064bd4eb04c69be Mon Sep 17 00:00:00 2001 From: Slava Barinov Date: Tue, 4 Dec 2018 17:23:42 +0300 Subject: [PATCH] Imported Upstream version 5.18.16 --- AUTHORS | 36 + COPYING | 674 + ChangeLog | 0 INSTALL | 47 + Makefile.am | 95 + Makefile.in | 1007 ++ NEWS | 6 + README | 115 + THANKS | 16 + TODO | 4 + VERSION | 69 + aclocal.m4 | 1291 ++ agen5/Makefile.am | 232 + agen5/Makefile.in | 1147 ++ agen5/ag-text.c | 753 + agen5/ag-text.def | 954 + agen5/ag-text.h | 864 + agen5/agCgi.c | 169 + agen5/agDep.c | 469 + agen5/agInit.c | 371 + agen5/agShell.c | 679 + agen5/agUtils.c | 563 + agen5/autogen.1 | 577 + agen5/autogen.c | 632 + agen5/autogen.h | 640 + agen5/bootstrap.dir | 125 + agen5/cgi-fsm.c | 346 + agen5/cgi-fsm.h | 92 + agen5/cgi.def | 50 + agen5/defDirect.c | 934 + agen5/defFind.c | 941 + agen5/defLex.c | 731 + agen5/defLoad.c | 581 + agen5/defParse-fsm.c | 404 + agen5/defParse-fsm.h | 93 + agen5/defParse.def | 106 + agen5/defParse.x | 251 + agen5/directive.c | 298 + agen5/directive.h | 95 + agen5/expExtract.c | 367 + agen5/expFormat.c | 1006 ++ agen5/expGperf.c | 160 + agen5/expGuile.c | 566 + agen5/expMake.c | 433 + agen5/expOutput.c | 954 + agen5/expPrint.c | 342 + agen5/expState.c | 818 + agen5/expString.c | 997 ++ agen5/expr.h | 170 + agen5/expr.ini | 286 + agen5/fmemopen.c | 725 + agen5/fsm-macro.tlib | 402 + agen5/fsm-trans.tlib | 359 + agen5/fsm.tpl | 289 + agen5/funcCase.c | 1331 ++ agen5/funcDef.c | 893 + agen5/funcEval.c | 768 + agen5/funcFor.c | 957 + agen5/funcIf.c | 507 + agen5/functions.c | 549 + agen5/functions.h | 315 + agen5/guile-iface.def | 65 + agen5/guile-iface.h | 24 + agen5/guile-iface.tpl | 135 + agen5/invoke-autogen.texi | 859 + agen5/loadPseudo.c | 487 + agen5/mk-stamps.sh | 384 + agen5/opts.c | 1590 ++ agen5/opts.def | 863 + agen5/opts.h | 350 + agen5/proto.h | 658 + agen5/pseudo-fsm.h | 228 + agen5/pseudo.def | 67 + agen5/schemedef.scm | 404 + agen5/scribble.c | 171 + agen5/scribble.h | 30 + agen5/snarf.tpl | 331 + agen5/test/Makefile.am | 69 + agen5/test/Makefile.in | 917 + agen5/test/alist.test | 78 + agen5/test/case.test | 135 + agen5/test/columns.test | 55 + agen5/test/daemon.test | 126 + agen5/test/debug.test | 186 + agen5/test/define.test | 160 + agen5/test/defref.test | 123 + agen5/test/directives.test | 147 + agen5/test/dynref.test | 81 + agen5/test/endmac.test | 72 + agen5/test/error.test | 233 + agen5/test/expr.test | 106 + agen5/test/extract.test | 79 + agen5/test/for.test | 111 + agen5/test/forfrom.test | 78 + agen5/test/forin.test | 85 + agen5/test/format.test | 103 + agen5/test/get.test | 94 + agen5/test/gperf.test | 94 + agen5/test/heredef.test | 101 + agen5/test/html.test | 129 + agen5/test/in.test | 94 + agen5/test/include.test | 79 + agen5/test/leave.test | 104 + agen5/test/license.test | 113 + agen5/test/line.test | 67 + agen5/test/loop.test | 77 + agen5/test/make.test | 90 + agen5/test/match.test | 71 + agen5/test/opts.test | 90 + agen5/test/output.test | 119 + agen5/test/pseudo.test | 102 + agen5/test/reorder.test | 106 + agen5/test/return.test | 72 + agen5/test/shell.test | 164 + agen5/test/snarf.test | 278 + agen5/test/stack.test | 92 + agen5/test/str2m.test | 415 + agen5/test/stress.test | 67 + agen5/test/string.test | 248 + agen5/test/strtable.test | 96 + agen5/test/strxform.test | 86 + agen5/test/suffix.test | 89 + agen5/test/time.test | 63 + agen5/tpLoad.c | 560 + agen5/tpParse.c | 412 + agen5/tpProcess.c | 444 + autoopts/Makefile.am | 244 + autoopts/Makefile.in | 1323 ++ autoopts/_Noreturn.h | 10 + autoopts/ag-char-map.h | 526 + autoopts/alias.c | 116 + autoopts/ao-strs.c | 379 + autoopts/ao-strs.def | 545 + autoopts/ao-strs.h | 338 + autoopts/ao_string_tokenize.3 | 86 + autoopts/autogen.map | 81 + autoopts/autoopts-config.1 | 161 + autoopts/autoopts-config.in | 113 + autoopts/autoopts.c | 391 + autoopts/autoopts.h | 494 + autoopts/autoopts.m4 | 223 + autoopts/autoopts/options.h | 1263 ++ autoopts/autoopts/usage-txt.h | 651 + autoopts/boolean.c | 95 + autoopts/bootstrap.dir | 259 + autoopts/check.c | 177 + autoopts/configFileLoad.3 | 50 + autoopts/configfile.c | 1337 ++ autoopts/cook.c | 320 + autoopts/enum.c | 628 + autoopts/env.c | 261 + autoopts/file.c | 201 + autoopts/find.c | 765 + autoopts/funcs.def | 1666 ++ autoopts/genshell.c | 848 + autoopts/genshell.def | 83 + autoopts/genshell.h | 224 + autoopts/gettext.h | 294 + autoopts/init.c | 289 + autoopts/install-hook.sh | 137 + autoopts/intprops.h | 453 + autoopts/load.c | 578 + autoopts/makeshell.c | 918 + autoopts/mk-autoopts-pc.in | 77 + autoopts/mk-tpl-config.sh | 256 + autoopts/nested.c | 905 + autoopts/numeric.c | 180 + autoopts/option-value-type.c | 156 + autoopts/option-value-type.h | 60 + autoopts/option-xat-attribute.c | 148 + autoopts/option-xat-attribute.h | 57 + autoopts/optionFileLoad.3 | 52 + autoopts/optionFindNextValue.3 | 50 + autoopts/optionFindValue.3 | 46 + autoopts/optionFree.3 | 31 + autoopts/optionGetValue.3 | 47 + autoopts/optionLoadLine.3 | 45 + autoopts/optionMemberList.3 | 30 + autoopts/optionNextValue.3 | 47 + autoopts/optionOnlyUsage.3 | 31 + autoopts/optionPrintVersion.3 | 29 + autoopts/optionPrintVersionAndReturn.3 | 32 + autoopts/optionProcess.3 | 55 + autoopts/optionRestore.3 | 35 + autoopts/optionSaveFile.3 | 44 + autoopts/optionSaveState.3 | 41 + autoopts/optionUnloadNested.3 | 28 + autoopts/optionVersion.3 | 27 + autoopts/parse-duration.c | 604 + autoopts/parse-duration.h | 90 + autoopts/pgusage.c | 187 + autoopts/po/usage-txt.pot | 353 + autoopts/project.h | 81 + autoopts/proto.h | 620 + autoopts/putshell.c | 495 + autoopts/reset.c | 141 + autoopts/restore.c | 223 + autoopts/save-flags.c | 248 + autoopts/save-flags.h | 68 + autoopts/save.c | 916 + autoopts/sort.c | 326 + autoopts/stack.c | 267 + autoopts/stdnoreturn.in.h | 60 + autoopts/strequate.3 | 32 + autoopts/streqvcmp.3 | 39 + autoopts/streqvcmp.c | 284 + autoopts/streqvmap.3 | 48 + autoopts/strneqvcmp.3 | 43 + autoopts/strtransform.3 | 37 + autoopts/test/Makefile.am | 55 + autoopts/test/Makefile.in | 901 + autoopts/test/alias.test | 119 + autoopts/test/argument.test | 237 + autoopts/test/cfg-edit.test | 330 + autoopts/test/cond.test | 193 + autoopts/test/config.test | 200 + autoopts/test/defs.in | 392 + autoopts/test/doc.test | 854 + autoopts/test/enums.test | 309 + autoopts/test/equiv.test | 273 + autoopts/test/errors.test | 231 + autoopts/test/getopt.test | 674 + autoopts/test/handler.test | 261 + autoopts/test/immediate.test | 122 + autoopts/test/keyword.test | 506 + autoopts/test/library.test | 169 + autoopts/test/main.test | 123 + autoopts/test/nested.test | 265 + autoopts/test/nls.test | 164 + autoopts/test/rc.test | 261 + autoopts/test/shell.test | 502 + autoopts/test/stdopts.def | 107 + autoopts/test/stdopts.test | 169 + autoopts/test/time.test | 100 + autoopts/test/usage.test | 655 + autoopts/test/vendor.test | 170 + autoopts/test/vers.test | 106 + autoopts/text_mmap.c | 382 + autoopts/time.c | 145 + autoopts/tokenize.c | 322 + autoopts/tpl/Mdoc.pm | 542 + autoopts/tpl/aginfo.tpl | 12 + autoopts/tpl/aginfo3.tpl | 126 + autoopts/tpl/agman-cmd.tpl | 63 + autoopts/tpl/agman-file.tpl | 90 + autoopts/tpl/agman.tlib | 98 + autoopts/tpl/agman1.tpl | 12 + autoopts/tpl/agman3.tpl | 145 + autoopts/tpl/agmdoc-cmd.tpl | 52 + autoopts/tpl/agmdoc-file.tpl | 76 + autoopts/tpl/agpl.lic | 19 + autoopts/tpl/agtexi-cmd.tpl | 970 ++ autoopts/tpl/agtexi-file.tpl | 327 + autoopts/tpl/bits.tpl | 717 + autoopts/tpl/cmd-doc.tlib | 1182 ++ autoopts/tpl/def2pot.tpl | 144 + autoopts/tpl/getopt.tpl | 510 + autoopts/tpl/gpl.lic | 19 + autoopts/tpl/gplv2.lic | 19 + autoopts/tpl/lgpl.lic | 19 + autoopts/tpl/lgplv2.lic | 20 + autoopts/tpl/man2mdoc.pl | 304 + autoopts/tpl/man2texi.sh | 27 + autoopts/tpl/mbsd.lic | 31 + autoopts/tpl/mdoc2man.pl | 219 + autoopts/tpl/mdoc2texi.pl | 185 + autoopts/tpl/optcode.tlib | 869 + autoopts/tpl/opthead.tlib | 709 + autoopts/tpl/options.tpl | 73 + autoopts/tpl/optlib.tlib | 1344 ++ autoopts/tpl/optmain.tlib | 1441 ++ autoopts/tpl/perlopt.tpl | 188 + autoopts/tpl/rc-sample.tpl | 125 + autoopts/tpl/stdoptions.def | 427 + autoopts/tpl/str2enum.tpl | 856 + autoopts/tpl/str2init.tlib | 149 + autoopts/tpl/str2mask.tpl | 458 + autoopts/tpl/strings.tpl | 171 + autoopts/tpl/texi2man.sh | 75 + autoopts/tpl/texi2mdoc.sh | 195 + autoopts/tpl/tpl-config-tlib.in | 82 + autoopts/tpl/usage.tlib | 245 + autoopts/usage.c | 1285 ++ autoopts/version.c | 240 + build-aux/run-ag.sh | 89 + columns/Makefile.am | 74 + columns/Makefile.in | 831 + columns/columns.c | 741 + columns/opts.c | 1106 ++ columns/opts.def | 362 + columns/opts.h | 251 + compat/Makefile.am | 51 + compat/Makefile.in | 534 + compat/bootstrap.dir | 32 + compat/chmod.c | 4 + compat/compat.h | 383 + compat/pathfind.c | 283 + compat/snprintf.c | 62 + compat/strchr.c | 66 + compat/strdup.c | 22 + compat/strftime.c | 1049 ++ compat/strsignal.c | 119 + compat/strsignal.def | 151 + compat/strsignal.h | 96 + compat/strsignal.tpl | 126 + compat/unlocked-io.h | 137 + compat/windows-config.h | 144 + config-h.in | 759 + config/ag_macros.m4 | 605 + config/asm-underscore.m4 | 72 + config/bootstrap | 209 + config/bootstrap.local | 277 + config/bootstrap.shlib | 256 + config/compile | 348 + config/config.guess | 1476 ++ config/config.rpath | 684 + config/config.sub | 1801 ++ config/depcomp | 791 + config/extensions.m4 | 189 + config/gendocs.sh | 510 + config/gnulib-cache.m4 | 73 + config/gnulib-comp.m4 | 230 + config/guile.m4 | 394 + config/host-cpu-c-abi.m4 | 456 + config/install-defs.sh | 17 + config/install-sh | 518 + config/lib-ld.m4 | 168 + config/lib-link.m4 | 777 + config/lib-prefix.m4 | 255 + config/libopts.m4 | 448 + config/liboptschk.m4 | 27 + config/libtool.m4 | 8369 +++++++++ config/ltmain.sh | 11147 ++++++++++++ config/ltoptions.m4 | 437 + config/ltsugar.m4 | 124 + config/ltversion.m4 | 23 + config/lt~obsolete.m4 | 99 + config/missing | 215 + config/mk-shdefs.in | 138 + config/onceonly.m4 | 104 + config/pkg.m4 | 275 + config/snprintfv.m4 | 98 + config/stdnoreturn.m4 | 51 + config/test-driver | 148 + config/texinfo.tex | 11727 +++++++++++++ config/unlocked-io.m4 | 41 + configure | 21317 +++++++++++++++++++++++ configure.ac | 247 + doc/Makefile.am | 71 + doc/Makefile.in | 873 + doc/agdoc.texi | 13580 +++++++++++++++ doc/auto-opts.tlib | 469 + doc/auto_gen-tpl.in | 679 + doc/autogen-intro.texi | 819 + doc/autogen-texi.txt | 6114 +++++++ doc/autogen.info | 523 + doc/autogen.info-1 | 7363 ++++++++ doc/autogen.info-2 | 7358 ++++++++ doc/autogen.texi | 7 + doc/bitmaps.texi | 348 + doc/fdl.texi | 505 + doc/gendocs_template | 91 + doc/invoke-autogen.texi | 859 + doc/invoke-bitmaps.texi | 348 + doc/invoke-columns.texi | 415 + doc/invoke-getdefs.texi | 583 + doc/invoke-snprintfv.texi | 74 + doc/invoke-xml2ag.texi | 423 + doc/libopts.texi | 927 + doc/mk-agen-texi.sh | 315 + doc/snprintfv.texi | 74 + getdefs/Makefile.am | 102 + getdefs/Makefile.in | 976 ++ getdefs/gdemit.c | 586 + getdefs/gdinit.c | 456 + getdefs/getdefs.c | 1162 ++ getdefs/getdefs.h | 125 + getdefs/opts.def | 479 + getdefs/proto.h | 85 + getdefs/test/Makefile.am | 47 + getdefs/test/Makefile.in | 894 + getdefs/test/cfg.test | 108 + getdefs/test/defs | 392 + getdefs/test/index.test | 122 + getdefs/test/option.test | 100 + getdefs/test/subblock.test | 98 + pkg/Makefile.am | 51 + pkg/Makefile.in | 537 + pkg/gnudir.tpl | 142 + pkg/gnudoc.tpl | 142 + pkg/libopts/COPYING.gplv3 | 674 + pkg/libopts/COPYING.lgplv3 | 165 + pkg/libopts/COPYING.mbsd | 27 + pkg/libopts/README | 122 + pkg/libopts/libopts-add.m4 | 138 + pkg/libopts/mklibsrc.sh | 149 + pkg/libopts/stdnoreturn.mk | 30 + pkg/lsm.tpl | 68 + pkg/mkpkg.linux | 91 + pkg/mkpkg.sh | 45 + pkg/mkpkg.sun | 150 + pkg/pkg-env.in | 45 + pkg/spec.tpl | 149 + snprintfv/AUTHORS | 8 + snprintfv/Makefile.am | 47 + snprintfv/Makefile.in | 686 + snprintfv/README | 30 + snprintfv/THANKS | 13 + snprintfv/compat.h | 329 + snprintfv/custom.c | 181 + snprintfv/filament.c | 231 + snprintfv/filament.h | 256 + snprintfv/filament.in | 196 + snprintfv/filament.stamp | 0 snprintfv/format.c | 1282 ++ snprintfv/mem.c | 81 + snprintfv/mem.h | 119 + snprintfv/printf.c | 1572 ++ snprintfv/printf.h | 845 + snprintfv/printf.in | 317 + snprintfv/printf.stamp | 0 snprintfv/stream.c | 225 + snprintfv/stream.h | 191 + snprintfv/stream.in | 95 + snprintfv/stream.stamp | 0 xml2ag/Makefile.am | 111 + xml2ag/Makefile.in | 985 ++ xml2ag/fork.c | 315 + xml2ag/fork.tpl | 259 + xml2ag/test/Makefile.am | 40 + xml2ag/test/Makefile.in | 887 + xml2ag/test/convert.test | 101 + xml2ag/xml2ag.c | 462 + xml2ag/xmlopts.c | 1118 ++ xml2ag/xmlopts.def | 180 + 435 files changed, 227262 insertions(+) create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 ChangeLog create mode 100644 INSTALL create mode 100644 Makefile.am create mode 100644 Makefile.in create mode 100644 NEWS create mode 100644 README create mode 100644 THANKS create mode 100644 TODO create mode 100644 VERSION create mode 100644 aclocal.m4 create mode 100644 agen5/Makefile.am create mode 100644 agen5/Makefile.in create mode 100644 agen5/ag-text.c create mode 100644 agen5/ag-text.def create mode 100644 agen5/ag-text.h create mode 100644 agen5/agCgi.c create mode 100644 agen5/agDep.c create mode 100644 agen5/agInit.c create mode 100644 agen5/agShell.c create mode 100644 agen5/agUtils.c create mode 100644 agen5/autogen.1 create mode 100644 agen5/autogen.c create mode 100644 agen5/autogen.h create mode 100644 agen5/bootstrap.dir create mode 100644 agen5/cgi-fsm.c create mode 100644 agen5/cgi-fsm.h create mode 100644 agen5/cgi.def create mode 100644 agen5/defDirect.c create mode 100644 agen5/defFind.c create mode 100644 agen5/defLex.c create mode 100644 agen5/defLoad.c create mode 100644 agen5/defParse-fsm.c create mode 100644 agen5/defParse-fsm.h create mode 100644 agen5/defParse.def create mode 100644 agen5/defParse.x create mode 100644 agen5/directive.c create mode 100644 agen5/directive.h create mode 100644 agen5/expExtract.c create mode 100644 agen5/expFormat.c create mode 100644 agen5/expGperf.c create mode 100644 agen5/expGuile.c create mode 100644 agen5/expMake.c create mode 100644 agen5/expOutput.c create mode 100644 agen5/expPrint.c create mode 100644 agen5/expState.c create mode 100644 agen5/expString.c create mode 100644 agen5/expr.h create mode 100644 agen5/expr.ini create mode 100644 agen5/fmemopen.c create mode 100644 agen5/fsm-macro.tlib create mode 100644 agen5/fsm-trans.tlib create mode 100644 agen5/fsm.tpl create mode 100644 agen5/funcCase.c create mode 100644 agen5/funcDef.c create mode 100644 agen5/funcEval.c create mode 100644 agen5/funcFor.c create mode 100644 agen5/funcIf.c create mode 100644 agen5/functions.c create mode 100644 agen5/functions.h create mode 100644 agen5/guile-iface.def create mode 100644 agen5/guile-iface.h create mode 100644 agen5/guile-iface.tpl create mode 100644 agen5/invoke-autogen.texi create mode 100644 agen5/loadPseudo.c create mode 100644 agen5/mk-stamps.sh create mode 100644 agen5/opts.c create mode 100644 agen5/opts.def create mode 100644 agen5/opts.h create mode 100644 agen5/proto.h create mode 100644 agen5/pseudo-fsm.h create mode 100644 agen5/pseudo.def create mode 100644 agen5/schemedef.scm create mode 100644 agen5/scribble.c create mode 100644 agen5/scribble.h create mode 100644 agen5/snarf.tpl create mode 100644 agen5/test/Makefile.am create mode 100644 agen5/test/Makefile.in create mode 100755 agen5/test/alist.test create mode 100755 agen5/test/case.test create mode 100755 agen5/test/columns.test create mode 100755 agen5/test/daemon.test create mode 100755 agen5/test/debug.test create mode 100755 agen5/test/define.test create mode 100755 agen5/test/defref.test create mode 100755 agen5/test/directives.test create mode 100755 agen5/test/dynref.test create mode 100755 agen5/test/endmac.test create mode 100755 agen5/test/error.test create mode 100755 agen5/test/expr.test create mode 100755 agen5/test/extract.test create mode 100755 agen5/test/for.test create mode 100755 agen5/test/forfrom.test create mode 100755 agen5/test/forin.test create mode 100755 agen5/test/format.test create mode 100755 agen5/test/get.test create mode 100755 agen5/test/gperf.test create mode 100755 agen5/test/heredef.test create mode 100755 agen5/test/html.test create mode 100755 agen5/test/in.test create mode 100755 agen5/test/include.test create mode 100755 agen5/test/leave.test create mode 100755 agen5/test/license.test create mode 100755 agen5/test/line.test create mode 100755 agen5/test/loop.test create mode 100755 agen5/test/make.test create mode 100755 agen5/test/match.test create mode 100755 agen5/test/opts.test create mode 100755 agen5/test/output.test create mode 100755 agen5/test/pseudo.test create mode 100755 agen5/test/reorder.test create mode 100755 agen5/test/return.test create mode 100755 agen5/test/shell.test create mode 100755 agen5/test/snarf.test create mode 100755 agen5/test/stack.test create mode 100755 agen5/test/str2m.test create mode 100755 agen5/test/stress.test create mode 100755 agen5/test/string.test create mode 100755 agen5/test/strtable.test create mode 100755 agen5/test/strxform.test create mode 100755 agen5/test/suffix.test create mode 100755 agen5/test/time.test create mode 100644 agen5/tpLoad.c create mode 100644 agen5/tpParse.c create mode 100644 agen5/tpProcess.c create mode 100644 autoopts/Makefile.am create mode 100644 autoopts/Makefile.in create mode 100644 autoopts/_Noreturn.h create mode 100644 autoopts/ag-char-map.h create mode 100644 autoopts/alias.c create mode 100644 autoopts/ao-strs.c create mode 100644 autoopts/ao-strs.def create mode 100644 autoopts/ao-strs.h create mode 100644 autoopts/ao_string_tokenize.3 create mode 100644 autoopts/autogen.map create mode 100644 autoopts/autoopts-config.1 create mode 100644 autoopts/autoopts-config.in create mode 100644 autoopts/autoopts.c create mode 100644 autoopts/autoopts.h create mode 100644 autoopts/autoopts.m4 create mode 100644 autoopts/autoopts/options.h create mode 100644 autoopts/autoopts/usage-txt.h create mode 100644 autoopts/boolean.c create mode 100644 autoopts/bootstrap.dir create mode 100644 autoopts/check.c create mode 100644 autoopts/configFileLoad.3 create mode 100644 autoopts/configfile.c create mode 100644 autoopts/cook.c create mode 100644 autoopts/enum.c create mode 100644 autoopts/env.c create mode 100644 autoopts/file.c create mode 100644 autoopts/find.c create mode 100644 autoopts/funcs.def create mode 100644 autoopts/genshell.c create mode 100644 autoopts/genshell.def create mode 100644 autoopts/genshell.h create mode 100644 autoopts/gettext.h create mode 100644 autoopts/init.c create mode 100644 autoopts/install-hook.sh create mode 100644 autoopts/intprops.h create mode 100644 autoopts/load.c create mode 100644 autoopts/makeshell.c create mode 100644 autoopts/mk-autoopts-pc.in create mode 100755 autoopts/mk-tpl-config.sh create mode 100644 autoopts/nested.c create mode 100644 autoopts/numeric.c create mode 100644 autoopts/option-value-type.c create mode 100644 autoopts/option-value-type.h create mode 100644 autoopts/option-xat-attribute.c create mode 100644 autoopts/option-xat-attribute.h create mode 100644 autoopts/optionFileLoad.3 create mode 100644 autoopts/optionFindNextValue.3 create mode 100644 autoopts/optionFindValue.3 create mode 100644 autoopts/optionFree.3 create mode 100644 autoopts/optionGetValue.3 create mode 100644 autoopts/optionLoadLine.3 create mode 100644 autoopts/optionMemberList.3 create mode 100644 autoopts/optionNextValue.3 create mode 100644 autoopts/optionOnlyUsage.3 create mode 100644 autoopts/optionPrintVersion.3 create mode 100644 autoopts/optionPrintVersionAndReturn.3 create mode 100644 autoopts/optionProcess.3 create mode 100644 autoopts/optionRestore.3 create mode 100644 autoopts/optionSaveFile.3 create mode 100644 autoopts/optionSaveState.3 create mode 100644 autoopts/optionUnloadNested.3 create mode 100644 autoopts/optionVersion.3 create mode 100644 autoopts/parse-duration.c create mode 100644 autoopts/parse-duration.h create mode 100644 autoopts/pgusage.c create mode 100644 autoopts/po/usage-txt.pot create mode 100644 autoopts/project.h create mode 100644 autoopts/proto.h create mode 100644 autoopts/putshell.c create mode 100644 autoopts/reset.c create mode 100644 autoopts/restore.c create mode 100644 autoopts/save-flags.c create mode 100644 autoopts/save-flags.h create mode 100644 autoopts/save.c create mode 100644 autoopts/sort.c create mode 100644 autoopts/stack.c create mode 100644 autoopts/stdnoreturn.in.h create mode 100644 autoopts/strequate.3 create mode 100644 autoopts/streqvcmp.3 create mode 100644 autoopts/streqvcmp.c create mode 100644 autoopts/streqvmap.3 create mode 100644 autoopts/strneqvcmp.3 create mode 100644 autoopts/strtransform.3 create mode 100644 autoopts/test/Makefile.am create mode 100644 autoopts/test/Makefile.in create mode 100755 autoopts/test/alias.test create mode 100755 autoopts/test/argument.test create mode 100755 autoopts/test/cfg-edit.test create mode 100755 autoopts/test/cond.test create mode 100755 autoopts/test/config.test create mode 100644 autoopts/test/defs.in create mode 100755 autoopts/test/doc.test create mode 100755 autoopts/test/enums.test create mode 100755 autoopts/test/equiv.test create mode 100755 autoopts/test/errors.test create mode 100755 autoopts/test/getopt.test create mode 100755 autoopts/test/handler.test create mode 100755 autoopts/test/immediate.test create mode 100755 autoopts/test/keyword.test create mode 100755 autoopts/test/library.test create mode 100755 autoopts/test/main.test create mode 100755 autoopts/test/nested.test create mode 100755 autoopts/test/nls.test create mode 100755 autoopts/test/rc.test create mode 100755 autoopts/test/shell.test create mode 100644 autoopts/test/stdopts.def create mode 100755 autoopts/test/stdopts.test create mode 100755 autoopts/test/time.test create mode 100755 autoopts/test/usage.test create mode 100755 autoopts/test/vendor.test create mode 100755 autoopts/test/vers.test create mode 100644 autoopts/text_mmap.c create mode 100644 autoopts/time.c create mode 100644 autoopts/tokenize.c create mode 100644 autoopts/tpl/Mdoc.pm create mode 100644 autoopts/tpl/aginfo.tpl create mode 100644 autoopts/tpl/aginfo3.tpl create mode 100644 autoopts/tpl/agman-cmd.tpl create mode 100644 autoopts/tpl/agman-file.tpl create mode 100644 autoopts/tpl/agman.tlib create mode 100644 autoopts/tpl/agman1.tpl create mode 100644 autoopts/tpl/agman3.tpl create mode 100644 autoopts/tpl/agmdoc-cmd.tpl create mode 100644 autoopts/tpl/agmdoc-file.tpl create mode 100644 autoopts/tpl/agpl.lic create mode 100644 autoopts/tpl/agtexi-cmd.tpl create mode 100644 autoopts/tpl/agtexi-file.tpl create mode 100644 autoopts/tpl/bits.tpl create mode 100644 autoopts/tpl/cmd-doc.tlib create mode 100644 autoopts/tpl/def2pot.tpl create mode 100644 autoopts/tpl/getopt.tpl create mode 100644 autoopts/tpl/gpl.lic create mode 100644 autoopts/tpl/gplv2.lic create mode 100644 autoopts/tpl/lgpl.lic create mode 100644 autoopts/tpl/lgplv2.lic create mode 100755 autoopts/tpl/man2mdoc.pl create mode 100755 autoopts/tpl/man2texi.sh create mode 100644 autoopts/tpl/mbsd.lic create mode 100644 autoopts/tpl/mdoc2man.pl create mode 100644 autoopts/tpl/mdoc2texi.pl create mode 100644 autoopts/tpl/optcode.tlib create mode 100644 autoopts/tpl/opthead.tlib create mode 100644 autoopts/tpl/options.tpl create mode 100644 autoopts/tpl/optlib.tlib create mode 100644 autoopts/tpl/optmain.tlib create mode 100644 autoopts/tpl/perlopt.tpl create mode 100644 autoopts/tpl/rc-sample.tpl create mode 100644 autoopts/tpl/stdoptions.def create mode 100644 autoopts/tpl/str2enum.tpl create mode 100644 autoopts/tpl/str2init.tlib create mode 100644 autoopts/tpl/str2mask.tpl create mode 100644 autoopts/tpl/strings.tpl create mode 100755 autoopts/tpl/texi2man.sh create mode 100755 autoopts/tpl/texi2mdoc.sh create mode 100644 autoopts/tpl/tpl-config-tlib.in create mode 100644 autoopts/tpl/usage.tlib create mode 100644 autoopts/usage.c create mode 100644 autoopts/version.c create mode 100644 build-aux/run-ag.sh create mode 100644 columns/Makefile.am create mode 100644 columns/Makefile.in create mode 100644 columns/columns.c create mode 100644 columns/opts.c create mode 100644 columns/opts.def create mode 100644 columns/opts.h create mode 100644 compat/Makefile.am create mode 100644 compat/Makefile.in create mode 100644 compat/bootstrap.dir create mode 100644 compat/chmod.c create mode 100644 compat/compat.h create mode 100644 compat/pathfind.c create mode 100644 compat/snprintf.c create mode 100644 compat/strchr.c create mode 100644 compat/strdup.c create mode 100644 compat/strftime.c create mode 100644 compat/strsignal.c create mode 100644 compat/strsignal.def create mode 100644 compat/strsignal.h create mode 100644 compat/strsignal.tpl create mode 100644 compat/unlocked-io.h create mode 100644 compat/windows-config.h create mode 100644 config-h.in create mode 100644 config/ag_macros.m4 create mode 100644 config/asm-underscore.m4 create mode 100755 config/bootstrap create mode 100644 config/bootstrap.local create mode 100644 config/bootstrap.shlib create mode 100755 config/compile create mode 100755 config/config.guess create mode 100755 config/config.rpath create mode 100755 config/config.sub create mode 100755 config/depcomp create mode 100644 config/extensions.m4 create mode 100755 config/gendocs.sh create mode 100644 config/gnulib-cache.m4 create mode 100644 config/gnulib-comp.m4 create mode 100644 config/guile.m4 create mode 100644 config/host-cpu-c-abi.m4 create mode 100644 config/install-defs.sh create mode 100755 config/install-sh create mode 100644 config/lib-ld.m4 create mode 100644 config/lib-link.m4 create mode 100644 config/lib-prefix.m4 create mode 100644 config/libopts.m4 create mode 100644 config/liboptschk.m4 create mode 100644 config/libtool.m4 create mode 100644 config/ltmain.sh create mode 100644 config/ltoptions.m4 create mode 100644 config/ltsugar.m4 create mode 100644 config/ltversion.m4 create mode 100644 config/lt~obsolete.m4 create mode 100755 config/missing create mode 100644 config/mk-shdefs.in create mode 100644 config/onceonly.m4 create mode 100644 config/pkg.m4 create mode 100644 config/snprintfv.m4 create mode 100644 config/stdnoreturn.m4 create mode 100755 config/test-driver create mode 100644 config/texinfo.tex create mode 100644 config/unlocked-io.m4 create mode 100755 configure create mode 100644 configure.ac create mode 100644 doc/Makefile.am create mode 100644 doc/Makefile.in create mode 100644 doc/agdoc.texi create mode 100644 doc/auto-opts.tlib create mode 100644 doc/auto_gen-tpl.in create mode 100644 doc/autogen-intro.texi create mode 100644 doc/autogen-texi.txt create mode 100644 doc/autogen.info create mode 100644 doc/autogen.info-1 create mode 100644 doc/autogen.info-2 create mode 100644 doc/autogen.texi create mode 100644 doc/bitmaps.texi create mode 100644 doc/fdl.texi create mode 100644 doc/gendocs_template create mode 100644 doc/invoke-autogen.texi create mode 100644 doc/invoke-bitmaps.texi create mode 100644 doc/invoke-columns.texi create mode 100644 doc/invoke-getdefs.texi create mode 100644 doc/invoke-snprintfv.texi create mode 100644 doc/invoke-xml2ag.texi create mode 100644 doc/libopts.texi create mode 100755 doc/mk-agen-texi.sh create mode 100644 doc/snprintfv.texi create mode 100644 getdefs/Makefile.am create mode 100644 getdefs/Makefile.in create mode 100644 getdefs/gdemit.c create mode 100644 getdefs/gdinit.c create mode 100644 getdefs/getdefs.c create mode 100644 getdefs/getdefs.h create mode 100644 getdefs/opts.def create mode 100644 getdefs/proto.h create mode 100644 getdefs/test/Makefile.am create mode 100644 getdefs/test/Makefile.in create mode 100755 getdefs/test/cfg.test create mode 100644 getdefs/test/defs create mode 100755 getdefs/test/index.test create mode 100755 getdefs/test/option.test create mode 100755 getdefs/test/subblock.test create mode 100644 pkg/Makefile.am create mode 100644 pkg/Makefile.in create mode 100644 pkg/gnudir.tpl create mode 100644 pkg/gnudoc.tpl create mode 100644 pkg/libopts/COPYING.gplv3 create mode 100644 pkg/libopts/COPYING.lgplv3 create mode 100644 pkg/libopts/COPYING.mbsd create mode 100644 pkg/libopts/README create mode 100644 pkg/libopts/libopts-add.m4 create mode 100644 pkg/libopts/mklibsrc.sh create mode 100644 pkg/libopts/stdnoreturn.mk create mode 100644 pkg/lsm.tpl create mode 100644 pkg/mkpkg.linux create mode 100644 pkg/mkpkg.sh create mode 100644 pkg/mkpkg.sun create mode 100644 pkg/pkg-env.in create mode 100644 pkg/spec.tpl create mode 100644 snprintfv/AUTHORS create mode 100644 snprintfv/Makefile.am create mode 100644 snprintfv/Makefile.in create mode 100644 snprintfv/README create mode 100644 snprintfv/THANKS create mode 100644 snprintfv/compat.h create mode 100644 snprintfv/custom.c create mode 100644 snprintfv/filament.c create mode 100644 snprintfv/filament.h create mode 100644 snprintfv/filament.in create mode 100644 snprintfv/filament.stamp create mode 100644 snprintfv/format.c create mode 100644 snprintfv/mem.c create mode 100644 snprintfv/mem.h create mode 100644 snprintfv/printf.c create mode 100644 snprintfv/printf.h create mode 100644 snprintfv/printf.in create mode 100644 snprintfv/printf.stamp create mode 100644 snprintfv/stream.c create mode 100644 snprintfv/stream.h create mode 100644 snprintfv/stream.in create mode 100644 snprintfv/stream.stamp create mode 100644 xml2ag/Makefile.am create mode 100644 xml2ag/Makefile.in create mode 100644 xml2ag/fork.c create mode 100644 xml2ag/fork.tpl create mode 100644 xml2ag/test/Makefile.am create mode 100644 xml2ag/test/Makefile.in create mode 100755 xml2ag/test/convert.test create mode 100644 xml2ag/xml2ag.c create mode 100644 xml2ag/xmlopts.c create mode 100644 xml2ag/xmlopts.def diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..594d24f --- /dev/null +++ b/AUTHORS @@ -0,0 +1,36 @@ +Original authors are also attributed in each source file... + +Bruce Korb: + +agen5/*, getdefs/*, autoopts/*, columns/*, rehacked compat/pathfind.c +to be SVR4 compatible. reworked compat/strsignal to use a shell script +to extract the local information and generate a static version. (It +uses autogen, so a generated version must be distributed also. :) + +Bruce Korb and Gary V. Vaughan: +In the directory config, regcomp.m4 and bootstrap. + +Gary V. Vaughan: +changes throughout to aid portability of C code. +wrote the autoconf files, Makefile.am and configure.in. +in the directory config; ctime.m4, make.m4 and release. +in the directory compat; basename.c, dirname.c, compat.h, + pathfind.c, libgen.h +in the directory tests; almost *.test +snprintfv/* + +Greg Harvey: +agen5/schemedef.scm, enabling Scheme syntax definitions + +Brian Fox, Chet Ramey: +sections of files borrowed from bash-2.0 incorporated into +compat/compat.h; (posixstat.h, posixjmp.h) + +Fred Fish, Gary V. Vaughan and Bruce Korb: +in the directory compat; strsignal.c + +James R. Van Zandt: +The Debianization of AutoGen + +Daniel Schregenberger +More GNU-ish usage text for AutoOpts. diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..e69de29 diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..98fa4fd --- /dev/null +++ b/INSTALL @@ -0,0 +1,47 @@ +This is the build instructions for autogen. If you're viewing it with +Emacs, try doing Ctl-C Ctl-t and browsing through the outline headers. +Ctl-C Ctl-a will unfold them again. + +** Building from a release tarball + +If you have downloaded a release tarball, + + configure; make; make install + +should do it. The usual configure options are available, notably inckuding +the --prefix option. The generated Makefile inckludes both "install" and +"uninstall" instructions. + +** Building from a repository clone + +To build from a repository clone, you must first have gperf (the GNU +Perfect Hash Function Generator) and gnulib (the GNU +Portability Library) installed. Then run + + bootstrap + +in the top-level directory. Note that for this to work, a precompiled +autogen binary needs to be in your $PATH. + +[To be continued]] + +** Known issues + +1. Whatever's going on with local-install + +2. autogen requiring itself to build is a problem we need to solve. + The standard way to solve this is check in its build products, + then rebuild those only when the *.def or *tpl files change. Of + course the INSTALL file needs to explicit about which stuff is + generated + +3. I'm going to want an easy, documented way to produce a *static* + build outogen so I can experiment with NTP builds without + colliding with an older shared library. bkorb replies: + '"cd $top_builddir/agen5 ; rm autogen ; make LDFLAGS=-static" + will do what you ask.'. + +Local variables: +mode: outline +paragraph-separate: "[ ]*$" +end: diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..3b0c433 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,95 @@ +## -*- Mode: Makefile -*- +## Makefile.am --- process this file with automake to produce Makefile.in +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . + +ACLOCAL_AMFLAGS = -I config + +SUBDIRS = compat snprintfv autoopts agen5 + +if DO_SHELL_CMDS +if HAVE_XML_LIB +SUBDIRS += columns getdefs xml2ag doc pkg +else +SUBDIRS += columns getdefs pkg +endif +else + +## Without shell commands, you cannot build docs or packages and the +## columns and getdefs commands are unworkable. +## +if HAVE_XML_LIB +SUBDIRS += xml2ag +endif +endif + +pkgdata_DATA = config/liboptschk.m4 +misc_extra = \ + VERSION autoopts/gettext.h \ + autoopts/parse-duration.c autoopts/parse-duration.h \ + config/ag_macros.m4 config/bootstrap \ + config/bootstrap.local config/bootstrap.shlib \ + config/config.rpath config/gnulib-cache.m4 \ + config/gnulib-cache.m4 config/gnulib-comp.m4 \ + config/guile.m4 config/install-defs.sh \ + config/lib-link.m4 config/libopts.m4 \ + config/liboptschk.m4 config/mk-shdefs.in \ + config/pkg.m4 config/snprintfv.m4 \ + config/unlocked-io.m4 build-aux/run-ag.sh + +EXTRA_DIST = $(misc_extra) $(pkgdata_DATA) +DISTCLEANFILES = stamp-h + +distcleancheck_listfiles = \ + find -type f -exec 'test -f $(srcdir)/{} || echo {} ;' + +configure : VERSION + +pkg : package +package : + cd pkg && $(MAKE) $@ pkgtype="$(pkgtype)" + +docs : gnudocs doxydocs +gnudoc : gnudocs +gnudocs : + cd doc && $(MAKE) gnudocs + +doxydocs : + test -f Doxyfile || cp ~/.Doxyfile ./Doxyfile ; \ + doxygen + +usage-txt.po: gettext +gettext : + cd autoopts && $(MAKE) usage-txt.po + +all : shdefs +shdefs : $(top_builddir)/config/shdefs +$(top_builddir)/config/shdefs: $(top_builddir)/config/mk-shdefs + $(SHELL) $< $@ + +if HAVE_XML_LIB +release : distcheck +else +release : + echo "Distributions cannot be made with a partial build" >&2 + exit 1 +endif + +.NOTPARALLEL: +.PHONY: all pkg package docs gnudoc gnudocs shdefs doxydocs gettext usage-txt.po + +## Makefile.am ends here diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..68bdd99 --- /dev/null +++ b/Makefile.in @@ -0,0 +1,1007 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 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. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +@DO_SHELL_CMDS_TRUE@@HAVE_XML_LIB_TRUE@am__append_1 = columns getdefs xml2ag doc pkg +@DO_SHELL_CMDS_TRUE@@HAVE_XML_LIB_FALSE@am__append_2 = columns getdefs pkg +@DO_SHELL_CMDS_FALSE@@HAVE_XML_LIB_TRUE@am__append_3 = xml2ag +subdir = . +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/ag_macros.m4 \ + $(top_srcdir)/config/asm-underscore.m4 \ + $(top_srcdir)/config/extensions.m4 \ + $(top_srcdir)/config/guile.m4 \ + $(top_srcdir)/config/host-cpu-c-abi.m4 \ + $(top_srcdir)/config/lib-ld.m4 \ + $(top_srcdir)/config/lib-link.m4 \ + $(top_srcdir)/config/lib-prefix.m4 \ + $(top_srcdir)/config/libopts.m4 \ + $(top_srcdir)/config/libtool.m4 \ + $(top_srcdir)/config/ltoptions.m4 \ + $(top_srcdir)/config/ltsugar.m4 \ + $(top_srcdir)/config/ltversion.m4 \ + $(top_srcdir)/config/lt~obsolete.m4 \ + $(top_srcdir)/config/onceonly.m4 $(top_srcdir)/config/pkg.m4 \ + $(top_srcdir)/config/snprintfv.m4 \ + $(top_srcdir)/config/stdnoreturn.m4 \ + $(top_srcdir)/config/unlocked-io.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ + $(am__configure_deps) $(am__DIST_COMMON) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = autoopts/tpl/tpl-config.tlib config/mk-shdefs +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(pkgdatadir)" +DATA = $(pkgdata_DATA) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + cscope distdir distdir-am dist dist-all distcheck +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ + $(LISP)config-h.in +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +CSCOPE = cscope +DIST_SUBDIRS = compat snprintfv autoopts agen5 columns getdefs xml2ag \ + doc pkg +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config-h.in \ + $(top_srcdir)/autoopts/tpl/tpl-config-tlib.in \ + $(top_srcdir)/config/compile $(top_srcdir)/config/config.guess \ + $(top_srcdir)/config/config.rpath \ + $(top_srcdir)/config/config.sub \ + $(top_srcdir)/config/install-sh $(top_srcdir)/config/ltmain.sh \ + $(top_srcdir)/config/missing $(top_srcdir)/config/mk-shdefs.in \ + AUTHORS COPYING ChangeLog INSTALL NEWS README THANKS TODO \ + config/compile config/config.guess config/config.rpath \ + config/config.sub config/install-sh config/ltmain.sh \ + config/missing +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + if test -d "$(distdir)"; then \ + find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -rf "$(distdir)" \ + || { sleep 5 && rm -rf "$(distdir)"; }; \ + else :; fi +am__post_remove_distdir = $(am__remove_distdir) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.xz +GZIP_ENV = --best +DIST_TARGETS = dist-xz dist-gzip +distuninstallcheck_listfiles = find . -type f -print +am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ + | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' +ACLOCAL = @ACLOCAL@ +AGEN5_TESTS = @AGEN5_TESTS@ +AG_LDFLAGS = @AG_LDFLAGS@ +AG_MAJOR_VERSION = @AG_MAJOR_VERSION@ +AG_MINOR_VERSION = @AG_MINOR_VERSION@ +AG_STATIC_AUTOGEN = @AG_STATIC_AUTOGEN@ +AG_TIMEOUT = @AG_TIMEOUT@ +AG_VERSION = @AG_VERSION@ +AG_XML2 = @AG_XML2@ +AGexe = @AGexe@ +AGnam = @AGnam@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AO_AGE = @AO_AGE@ +AO_CURRENT = @AO_CURRENT@ +AO_REVISION = @AO_REVISION@ +AO_TEMPLATE_VERSION = @AO_TEMPLATE_VERSION@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLexe = @CLexe@ +CLnam = @CLnam@ +CONFIG_SHELL = @CONFIG_SHELL@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBUG_ENABLED = @DEBUG_ENABLED@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +DYNAMIC_AG = @DYNAMIC_AG@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_STATIC = @ENABLE_STATIC@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GDexe = @GDexe@ +GDnam = @GDnam@ +GO_AGE = @GO_AGE@ +GO_CURRENT = @GO_CURRENT@ +GO_REVISION = @GO_REVISION@ +GREP = @GREP@ +GUILE_CFLAGS = @GUILE_CFLAGS@ +GUILE_EFFECTIVE_VERSION = @GUILE_EFFECTIVE_VERSION@ +GUILE_LDFLAGS = @GUILE_LDFLAGS@ +GUILE_LIBS = @GUILE_LIBS@ +GUILE_LTLIBS = @GUILE_LTLIBS@ +HOST_CPU = @HOST_CPU@ +HOST_CPU_C_ABI = @HOST_CPU_C_ABI@ +INCLIST = @INCLIST@ +INCSNPRINTFV = @INCSNPRINTFV@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSNPRINTFV = @LIBSNPRINTFV@ +LIBTOOL = @LIBTOOL@ +LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ +LIBXML2_LIBS = @LIBXML2_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +M4_SRC = @M4_SRC@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPTS_TESTDIR = @OPTS_TESTDIR@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSIX_SHELL = @POSIX_SHELL@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STDNORETURN_H = @STDNORETURN_H@ +STRIP = @STRIP@ +TEXI2HTML = @TEXI2HTML@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_aux_dir = @ac_aux_dir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +ACLOCAL_AMFLAGS = -I config +SUBDIRS = compat snprintfv autoopts agen5 $(am__append_1) \ + $(am__append_2) $(am__append_3) +pkgdata_DATA = config/liboptschk.m4 +misc_extra = \ + VERSION autoopts/gettext.h \ + autoopts/parse-duration.c autoopts/parse-duration.h \ + config/ag_macros.m4 config/bootstrap \ + config/bootstrap.local config/bootstrap.shlib \ + config/config.rpath config/gnulib-cache.m4 \ + config/gnulib-cache.m4 config/gnulib-comp.m4 \ + config/guile.m4 config/install-defs.sh \ + config/lib-link.m4 config/libopts.m4 \ + config/liboptschk.m4 config/mk-shdefs.in \ + config/pkg.m4 config/snprintfv.m4 \ + config/unlocked-io.m4 build-aux/run-ag.sh + +EXTRA_DIST = $(misc_extra) $(pkgdata_DATA) +DISTCLEANFILES = stamp-h +distcleancheck_listfiles = \ + find -type f -exec 'test -f $(srcdir)/{} || echo {} ;' + +all: config.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +am--refresh: Makefile + @: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): + +config.h: stamp-h1 + @test -f $@ || rm -f stamp-h1 + @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 + +stamp-h1: $(srcdir)/config-h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status config.h +$(srcdir)/config-h.in: $(am__configure_deps) + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f config.h stamp-h1 +autoopts/tpl/tpl-config.tlib: $(top_builddir)/config.status $(top_srcdir)/autoopts/tpl/tpl-config-tlib.in + cd $(top_builddir) && $(SHELL) ./config.status $@ +config/mk-shdefs: $(top_builddir)/config.status $(top_srcdir)/config/mk-shdefs.in + cd $(top_builddir) && $(SHELL) ./config.status $@ + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + -rm -f libtool config.lt +install-pkgdataDATA: $(pkgdata_DATA) + @$(NORMAL_INSTALL) + @list='$(pkgdata_DATA)'; test -n "$(pkgdatadir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkgdatadir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkgdatadir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgdatadir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgdatadir)" || exit $$?; \ + done + +uninstall-pkgdataDATA: + @$(NORMAL_UNINSTALL) + @list='$(pkgdata_DATA)'; test -n "$(pkgdatadir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkgdatadir)'; $(am__uninstall_files_from_dir) + +# 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. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscope: cscope.files + test ! -s cscope.files \ + || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) +clean-cscope: + -rm -f cscope.files +cscope.files: clean-cscope cscopelist +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + -rm -f cscope.out cscope.in.out cscope.po.out cscope.files + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @case `sed 15q $(srcdir)/NEWS` in \ + *"$(VERSION)"*) : ;; \ + *) \ + echo "NEWS not updated; not releasing" 1>&2; \ + exit 1;; \ + esac + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz + $(am__post_remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 + $(am__post_remove_distdir) + +dist-lzip: distdir + tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz + $(am__post_remove_distdir) +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz + $(am__post_remove_distdir) + +dist-tarZ: distdir + @echo WARNING: "Support for distribution archives compressed with" \ + "legacy program 'compress' is deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__post_remove_distdir) + +dist-shar: distdir + @echo WARNING: "Support for shar distribution archives is" \ + "deprecated." >&2 + @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 + shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz + $(am__post_remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__post_remove_distdir) + +dist dist-all: + $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' + $(am__post_remove_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 + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lz*) \ + lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir) + chmod u+w $(distdir) + mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build/sub \ + && ../../configure \ + $(AM_DISTCHECK_CONFIGURE_FLAGS) \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + --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) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__post_remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @test -n '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: trying to run $@ with an empty' \ + '$$(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + $(am__cd) '$(distuninstallcheck_dir)' || { \ + echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ + exit 1; \ + }; \ + test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-recursive +all-am: Makefile $(DATA) config.h +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(pkgdatadir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-hdr \ + distclean-libtool distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: install-pkgdataDATA + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-pkgdataDATA + +.MAKE: $(am__recursive_targets) all install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ + am--refresh check check-am clean clean-cscope clean-generic \ + clean-libtool cscope cscopelist-am ctags ctags-am dist \ + dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \ + dist-xz dist-zip distcheck distclean distclean-generic \ + distclean-hdr distclean-libtool distclean-tags distcleancheck \ + distdir distuninstallcheck dvi dvi-am html html-am info \ + info-am install install-am install-data install-data-am \ + install-dvi install-dvi-am install-exec install-exec-am \ + install-html install-html-am install-info install-info-am \ + install-man install-pdf install-pdf-am install-pkgdataDATA \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-pkgdataDATA + +.PRECIOUS: Makefile + + +configure : VERSION + +pkg : package +package : + cd pkg && $(MAKE) $@ pkgtype="$(pkgtype)" + +docs : gnudocs doxydocs +gnudoc : gnudocs +gnudocs : + cd doc && $(MAKE) gnudocs + +doxydocs : + test -f Doxyfile || cp ~/.Doxyfile ./Doxyfile ; \ + doxygen + +usage-txt.po: gettext +gettext : + cd autoopts && $(MAKE) usage-txt.po + +all : shdefs +shdefs : $(top_builddir)/config/shdefs +$(top_builddir)/config/shdefs: $(top_builddir)/config/mk-shdefs + $(SHELL) $< $@ + +@HAVE_XML_LIB_TRUE@release : distcheck +@HAVE_XML_LIB_FALSE@release : +@HAVE_XML_LIB_FALSE@ echo "Distributions cannot be made with a partial build" >&2 +@HAVE_XML_LIB_FALSE@ exit 1 + +.NOTPARALLEL: +.PHONY: all pkg package docs gnudoc gnudocs shdefs doxydocs gettext usage-txt.po + +# 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/NEWS b/NEWS new file mode 100644 index 0000000..f67e59a --- /dev/null +++ b/NEWS @@ -0,0 +1,6 @@ +New in 5.18.16 - August 2018 + +Bootstrap and configure code has been revamped to work with the +new flavors of the autotools. + +Guile 2.2 works like 2.0, so accept it, too. diff --git a/README b/README new file mode 100644 index 0000000..a2ba45e --- /dev/null +++ b/README @@ -0,0 +1,115 @@ +This is AutoGen, an automated text file generator. It was inspired out of +frustration and hassle with maintaining syncronization between option flag +lists, global variables and usage information. The desire for more than +#define macros came about when it became apparent that macros alone were +insufficient for reducing the maintenance into a single option list. The +impetus to actually start something finally came when I had to maintain a +large callout procedure table and associated lookup tables. + +Rev 1 of this utility was a set of #define macro expansions. +Rev 2 was a shell script that sort-of did a prototype. + Much better than just #defines, but still clearly lacking. +Rev 3 had a very kludgy macro definition syntax. +Rev 4 a reworking and simplification of the declarations +Rev 5 the addition of Guile expression processing + +Mailing lists can be found on SourceForge: + + autogen-users@lists.sourceforge.net + + +*** AutoGen requires: *** + +1. POSIX regular expression library. If not available by default, use + the --with-regex-* options to specify how to find, use and link to it. +2. an ANSI C compiler +3. The Guile version of a Scheme processing language. + + +*** Installation note: *** + +AutoGen does *NOT* contain any compiled-in configuration information. +Therefore, in order to use the templates that come bundled with it, +you must tell AutoGen how to find those templates when you build +applications that use those templates. + +1. by doing nothing. If you do not alter the default data directory, + AutoGen will search for templates in the directory ../share/autogen, + relative to the executable directory. That should generally work. + +2. You can tell AutoGen where to look with an environment variable: + + export AUTOGEN_TEMPL_DIR=$prefix/share/autogen + +3. You can use an RC file: + + autogen -L $prefix/share/autogen --save=$HOME/.autogenrc + +4. If you have an old Guile library, you will find that its error reporting + does not work so well. Consequently, you will see "make check" failures + in the output text where you would expect to find file name and line + number references for the invalid input. Please upgrade your Guile lib. + +5. You can build and install AutoGen, ensuring you have the + automake/autoconf/libtool-s needed, and then editing + agen5/opts.def thus: + + echo "homerc = $prefix/share/autogen;" >> agen5/opts.def + +and then rebuilding AutoGen. However, if you do this latter +"fix", you will have an immobile product. I hate that, others +like it. It is, however, up to you. + + +*** Build note: *** + +Sometimes, configure believes it has done a good job when it really hasn't. +It is possible to configure a system in such a way that the Guile headers and +libguile are linked against correctly, but the loader cannot find +libguile.so.xxx. This is because GCC will silently find the library for +linking, but not set the library dependencies correctly. The consequence is +that the configure script believes that standard links will produce working +executables. It won't. The simplest solution is: + + .../configure --disable-shared + +the best solution is to examine the output of ``guile-config link'', +duplicate the ``-L/path/to/lib'' argument, but changing the "-L" to +"-R" or "-Wl,-rpath," or "-rpath" or whatever it happens to be that +works for your platform, and hand that off to configure as the argument +to ``--with-libguile-link''. "libtool" won't fix it and it's too hard +for me. Sorry. Anyway, for example, assume: + + guile-config link + +produces: + + -L/opt/sfw/lib -lguile -lm + +now run configure as follows: + + .../configure \ + --with-libguile-link='-L/opt/sfw/lib -lguile -lm -R/opt/sfw/lib' + +Isn't that special? + + +*** Bootstrap note: *** + +I have some private tools referenced in the various bootstrap scripts. +Unless you have these tools, bootstrap won't work for you. I intend +to fix this as time permits. Meanwhile, there is also a tarball in CVS +of all the bootstrap-generated files: + noag-boot.sh + +*** Licensing: *** + + autogen is under GPL, but that does not cause the output produced by + autogen to be under GPL. The reason is that the output contains next to + nothing that comes directly from autogen's source code. Thus, the output + is not a "derivative work" of autogen (in the sense of U.S.@: copyright + law). The output is primarily a derivative of the input templates. + + On the other hand, the output produced by autogen contains essentially all + of the input template. Therefore the output is under the same license, + with the same copyright holder, as the input that was passed to autogen. diff --git a/THANKS b/THANKS new file mode 100644 index 0000000..c23af9f --- /dev/null +++ b/THANKS @@ -0,0 +1,16 @@ +AutoGen would not be what it is without the invaluable help of +many people: + +Everybody who was kind enough to spend time testing it, +using it with the GCC fixincludes and reporting bugs. + +The following people made especially gracious contributions of their +time and energy in helping to track down bugs, port to new systems, +and generally assist in the maintainership process: + +Gary V. Vaughan +Robert Lipe +Alexandre Oliva +James R. Van Zandt +Thomas Steudten +Harlan Stenn diff --git a/TODO b/TODO new file mode 100644 index 0000000..1e022b6 --- /dev/null +++ b/TODO @@ -0,0 +1,4 @@ +# -*- Mode: Outline -*- + +* add test for new license. +* add manywarnings gnulib module diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..ffc7bf0 --- /dev/null +++ b/VERSION @@ -0,0 +1,69 @@ +#! /bin/echo this_should_be_sourced +# -*- Mode: sh -*- +# VERSION --- Set version info for GNU-ish tool use + +MAINTAINER='Bruce Korb ' + +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . + +AG_MAJOR_VERSION=5 +AG_MINOR_VERSION=18 +AG_REVISION=$AG_MAJOR_VERSION.$AG_MINOR_VERSION +AG_PATCHLEVEL=.16 +AG_VERSION=$AG_REVISION$AG_PATCHLEVEL + +# AutoOpts versioning: +# +# AO_CURRENT represents the number of visible changes to the interface +# AO_REVISION represents the number of times the library has been +# modified with an unchanged interface. +# AO_AGE represents the number of older revisions the current library +# is capable of handling. +# +AO_LIBRARY=libopts.la +AO_CURRENT=42 +AO_REVISION=1 +AO_AGE=17 + +# For automake +# +VERSION=${AG_VERSION} +PACKAGE='GNU AutoGen' +EADDR=autogen-users@lists.sourceforge.net + +# Display version numbers banner for my sanity! +# +AO_SOVERS=${AO_CURRENT}:${AO_REVISION}:${AO_AGE} +AO_SONAME=${AO_LIBRARY}-${AO_SOVERS} +w=`expr \( ${COLUMNS:-80} - 1 \) / 2` +h=`expr $w \* 2` +h=`printf "*%${h}s" '' | sed 's/ /-*/g'` +ag=`echo AUTOGEN | sed 's/\(.\)/\1 /g;s/ *$//'` +ag_off=`printf "$ag"|wc -c` +ag_off=`expr $w - \( $ag_off / 2 \)` +ag=`printf "%${ag_off}s${ag}" ""` + +cat < + @%:@ifndef LLONG_MAX + @%:@ define HALF \ + (1LL << (sizeof (long long int) * CHAR_BIT - 2)) + @%:@ define LLONG_MAX (HALF - 1 + HALF) + @%:@endif]], + [[long long int n = 1; + int i; + for (i = 0; ; i++) + { + long long int m = n << i; + if (m >> i != n) + return 1; + if (LLONG_MAX / 2 < m) + break; + } + return 0;]])], + [], + [ac_cv_type_long_long_int=no], + [:]) + fi + fi]) + if test $ac_cv_type_long_long_int = yes; then + AC_DEFINE([HAVE_LONG_LONG_INT], [1], + [Define to 1 if the system has the type 'long long int'.]) + fi +]) + +# Define HAVE_UNSIGNED_LONG_LONG_INT if 'unsigned long long int' works. +# This fixes a bug in Autoconf 2.61, and can be faster +# than what's in Autoconf 2.62 through 2.68. + +# Note: If the type 'unsigned long long int' exists but is only 32 bits +# large (as on some very old compilers), AC_TYPE_UNSIGNED_LONG_LONG_INT +# will not be defined. In this case you can treat 'unsigned long long int' +# like 'unsigned long int'. + +AC_DEFUN([AC_TYPE_UNSIGNED_LONG_LONG_INT], +[ + AC_CACHE_CHECK([for unsigned long long int], + [ac_cv_type_unsigned_long_long_int], + [ac_cv_type_unsigned_long_long_int=yes + if test "x${ac_cv_prog_cc_c99-no}" = xno; then + AC_LINK_IFELSE( + [_AC_TYPE_LONG_LONG_SNIPPET], + [], + [ac_cv_type_unsigned_long_long_int=no]) + fi]) + if test $ac_cv_type_unsigned_long_long_int = yes; then + AC_DEFINE([HAVE_UNSIGNED_LONG_LONG_INT], [1], + [Define to 1 if the system has the type 'unsigned long long int'.]) + fi +]) + +# Expands to a C program that can be used to test for simultaneous support +# of 'long long' and 'unsigned long long'. We don't want to say that +# 'long long' is available if 'unsigned long long' is not, or vice versa, +# because too many programs rely on the symmetry between signed and unsigned +# integer types (excluding 'bool'). +AC_DEFUN([_AC_TYPE_LONG_LONG_SNIPPET], +[ + AC_LANG_PROGRAM( + [[/* For now, do not test the preprocessor; as of 2007 there are too many + implementations with broken preprocessors. Perhaps this can + be revisited in 2012. In the meantime, code should not expect + #if to work with literals wider than 32 bits. */ + /* Test literals. */ + long long int ll = 9223372036854775807ll; + long long int nll = -9223372036854775807LL; + unsigned long long int ull = 18446744073709551615ULL; + /* Test constant expressions. */ + typedef int a[((-9223372036854775807LL < 0 && 0 < 9223372036854775807ll) + ? 1 : -1)]; + typedef int b[(18446744073709551615ULL <= (unsigned long long int) -1 + ? 1 : -1)]; + int i = 63;]], + [[/* Test availability of runtime routines for shift and division. */ + long long int llmax = 9223372036854775807ll; + unsigned long long int ullmax = 18446744073709551615ull; + return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i) + | (llmax / ll) | (llmax % ll) + | (ull << 63) | (ull >> 63) | (ull << i) | (ull >> i) + | (ullmax / ull) | (ullmax % ull));]]) +]) + +# Copyright (C) 2002-2018 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.16' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.16.1], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.16.1])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001-2018 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to +# '$srcdir', '$srcdir/..', or '$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is '.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997-2018 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ([2.52])dnl + m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999-2018 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + + +# There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], + [$1], [CXX], [depcc="$CXX" am_compiler_list=], + [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], + [$1], [UPC], [depcc="$UPC" am_compiler_list=], + [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + am__universal=false + m4_case([$1], [CC], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac], + [CXX], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac]) + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES. +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE([dependency-tracking], [dnl +AS_HELP_STRING( + [--enable-dependency-tracking], + [do not reject slow dependency extractors]) +AS_HELP_STRING( + [--disable-dependency-tracking], + [speeds up one-time build])]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +AC_SUBST([am__nodep])dnl +_AM_SUBST_NOTMAKE([am__nodep])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999-2018 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[{ + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + # TODO: see whether this extra hack can be removed once we start + # requiring Autoconf 2.70 or later. + AS_CASE([$CONFIG_FILES], + [*\'*], [eval set x "$CONFIG_FILES"], + [*], [set x $CONFIG_FILES]) + shift + # Used to flag and report bootstrapping failures. + am_rc=0 + for am_mf + do + # Strip MF so we end up with the name of the file. + am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile which includes + # dependency-tracking related rules and includes. + # Grep'ing the whole file directly is not great: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ + || continue + am_dirpart=`AS_DIRNAME(["$am_mf"])` + am_filepart=`AS_BASENAME(["$am_mf"])` + AM_RUN_LOG([cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles]) || am_rc=$? + done + if test $am_rc -ne 0; then + AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments + for automatic dependency tracking. Try re-running configure with the + '--disable-dependency-tracking' option to at least be able to build + the package (albeit without support for automatic dependency tracking).]) + fi + AS_UNSET([am_dirpart]) + AS_UNSET([am_filepart]) + AS_UNSET([am_mf]) + AS_UNSET([am_rc]) + rm -f conftest-deps.mk +} +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking is enabled. +# This creates each '.Po' and '.Plo' makefile fragment that we'll need in +# order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"])]) + + +# Copyright (C) 1996-2018 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +AC_DEFUN([AM_WITH_DMALLOC], +[AC_MSG_CHECKING([if malloc debugging is wanted]) +AC_ARG_WITH([dmalloc], +[AS_HELP_STRING([--with-dmalloc], + [use dmalloc, as in http://www.dmalloc.com])], +[if test "$withval" = yes; then + AC_MSG_RESULT([yes]) + AC_DEFINE([WITH_DMALLOC], [1], + [Define if using the dmalloc debugging malloc package]) + LIBS="$LIBS -ldmalloc" + LDFLAGS="$LDFLAGS -g" +else + AC_MSG_RESULT([no]) +fi], [AC_MSG_RESULT([no])]) +]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996-2018 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# 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. + +dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. +m4_define([AC_PROG_CC], +m4_defn([AC_PROG_CC]) +[_AM_PROG_CC_C_O +]) + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.65])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[AC_DIAGNOSE([obsolete], + [$0: two- and three-arguments forms are deprecated.]) +m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if( + m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), + [ok:ok],, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) + AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) +AM_MISSING_PROG([AUTOCONF], [autoconf]) +AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) +AM_MISSING_PROG([AUTOHEADER], [autoheader]) +AM_MISSING_PROG([MAKEINFO], [makeinfo]) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# +# +AC_SUBST([mkdir_p], ['$(MKDIR_P)']) +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES([CC])], + [m4_define([AC_PROG_CC], + m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES([CXX])], + [m4_define([AC_PROG_CXX], + m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES([OBJC])], + [m4_define([AC_PROG_OBJC], + m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], + [_AM_DEPENDENCIES([OBJCXX])], + [m4_define([AC_PROG_OBJCXX], + m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl +]) +AC_REQUIRE([AM_SILENT_RULES])dnl +dnl The testsuite driver may need to know about EXEEXT, so add the +dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This +dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: . + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) + fi +fi +dnl The trailing newline in this macro's definition is deliberate, for +dnl backward compatibility and to allow trailing 'dnl'-style comments +dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. +]) + +dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001-2018 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST([install_sh])]) + +# Copyright (C) 2003-2018 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001-2018 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MAKE_INCLUDE() +# ----------------- +# Check whether make has an 'include' directive that can support all +# the idioms we need for our automatic dependency tracking code. +AC_DEFUN([AM_MAKE_INCLUDE], +[AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive]) +cat > confinc.mk << 'END' +am__doit: + @echo this is the am__doit target >confinc.out +.PHONY: am__doit +END +am__include="#" +am__quote= +# BSD make does it like this. +echo '.include "confinc.mk" # ignored' > confmf.BSD +# Other make implementations (GNU, Solaris 10, AIX) do it like this. +echo 'include confinc.mk # ignored' > confmf.GNU +_am_result=no +for s in GNU BSD; do + AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out]) + AS_CASE([$?:`cat confinc.out 2>/dev/null`], + ['0:this is the am__doit target'], + [AS_CASE([$s], + [BSD], [am__include='.include' am__quote='"'], + [am__include='include' am__quote=''])]) + if test "$am__include" != "#"; then + _am_result="yes ($s style)" + break + fi +done +rm -f confinc.* confmf.* +AC_MSG_RESULT([${_am_result}]) +AC_SUBST([am__include])]) +AC_SUBST([am__quote])]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997-2018 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it is modern enough. +# If it is, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + AC_MSG_WARN(['missing' script is too old or missing]) +fi +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001-2018 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# -------------------- +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), [1])]) + +# _AM_SET_OPTIONS(OPTIONS) +# ------------------------ +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Copyright (C) 1999-2018 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_PROG_CC_C_O +# --------------- +# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC +# to automatically call this. +AC_DEFUN([_AM_PROG_CC_C_O], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([compile])dnl +AC_LANG_PUSH([C])dnl +AC_CACHE_CHECK( + [whether $CC understands -c and -o together], + [am_cv_prog_cc_c_o], + [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i]) +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +AC_LANG_POP([C])]) + +# For backward compatibility. +AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) + +# Copyright (C) 2001-2018 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_RUN_LOG(COMMAND) +# ------------------- +# Run COMMAND, save the exit status in ac_status, and log it. +# (This has been adapted from Autoconf's _AC_RUN_LOG macro.) +AC_DEFUN([AM_RUN_LOG], +[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD + ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + (exit $ac_status); }]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996-2018 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; +esac + +# 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 ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $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 + if test "$[2]" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT([yes]) +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi +AC_CONFIG_COMMANDS_PRE( + [AC_MSG_CHECKING([that generated files are newer than configure]) + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + AC_MSG_RESULT([done])]) +rm -f conftest.file +]) + +# Copyright (C) 2009-2018 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_SILENT_RULES([DEFAULT]) +# -------------------------- +# Enable less verbose build rules; with the default set to DEFAULT +# ("yes" being less verbose, "no" or empty being verbose). +AC_DEFUN([AM_SILENT_RULES], +[AC_ARG_ENABLE([silent-rules], [dnl +AS_HELP_STRING( + [--enable-silent-rules], + [less verbose build output (undo: "make V=1")]) +AS_HELP_STRING( + [--disable-silent-rules], + [verbose build output (undo: "make V=0")])dnl +]) +case $enable_silent_rules in @%:@ ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; +esac +dnl +dnl A few 'make' implementations (e.g., NonStop OS and NextStep) +dnl do not support nested variable expansions. +dnl See automake bug#9928 and bug#10237. +am_make=${MAKE-make} +AC_CACHE_CHECK([whether $am_make supports nested variables], + [am_cv_make_support_nested_variables], + [if AS_ECHO([['TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi]) +if test $am_cv_make_support_nested_variables = yes; then + dnl Using '$V' instead of '$(V)' breaks IRIX make. + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AC_SUBST([AM_V])dnl +AM_SUBST_NOTMAKE([AM_V])dnl +AC_SUBST([AM_DEFAULT_V])dnl +AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl +AC_SUBST([AM_DEFAULT_VERBOSITY])dnl +AM_BACKSLASH='\' +AC_SUBST([AM_BACKSLASH])dnl +_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl +]) + +# Copyright (C) 2001-2018 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor 'install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in "make install-strip", and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006-2018 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# -------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004-2018 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of 'v7', 'ustar', or 'pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +# +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AC_SUBST([AMTAR], ['$${TAR-tar}']) + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' + +m4_if([$1], [v7], + [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], + + [m4_case([$1], + [ustar], + [# The POSIX 1988 'ustar' format is defined with fixed-size fields. + # There is notably a 21 bits limit for the UID and the GID. In fact, + # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 + # and bug#13588). + am_max_uid=2097151 # 2^21 - 1 + am_max_gid=$am_max_uid + # The $UID and $GID variables are not portable, so we need to resort + # to the POSIX-mandated id(1) utility. Errors in the 'id' calls + # below are definitely unexpected, so allow the users to see them + # (that is, avoid stderr redirection). + am_uid=`id -u || echo unknown` + am_gid=`id -g || echo unknown` + AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) + if test $am_uid -le $am_max_uid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi + AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) + if test $am_gid -le $am_max_gid; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + _am_tools=none + fi], + + [pax], + [], + + [m4_fatal([Unknown tar format])]) + + AC_MSG_CHECKING([how to create a $1 tar archive]) + + # Go ahead even if we have the value already cached. We do so because we + # need to set the values for the 'am__tar' and 'am__untar' variables. + _am_tools=${am_cv_prog_tar_$1-$_am_tools} + + for _am_tool in $_am_tools; do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works. + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi + done + rm -rf conftest.dir + + AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) + AC_MSG_RESULT([$am_cv_prog_tar_$1])]) + +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + +m4_include([config/ag_macros.m4]) +m4_include([config/asm-underscore.m4]) +m4_include([config/extensions.m4]) +m4_include([config/guile.m4]) +m4_include([config/host-cpu-c-abi.m4]) +m4_include([config/lib-ld.m4]) +m4_include([config/lib-link.m4]) +m4_include([config/lib-prefix.m4]) +m4_include([config/libopts.m4]) +m4_include([config/libtool.m4]) +m4_include([config/ltoptions.m4]) +m4_include([config/ltsugar.m4]) +m4_include([config/ltversion.m4]) +m4_include([config/lt~obsolete.m4]) +m4_include([config/onceonly.m4]) +m4_include([config/pkg.m4]) +m4_include([config/snprintfv.m4]) +m4_include([config/stdnoreturn.m4]) +m4_include([config/unlocked-io.m4]) diff --git a/agen5/Makefile.am b/agen5/Makefile.am new file mode 100644 index 0000000..cf2ed90 --- /dev/null +++ b/agen5/Makefile.am @@ -0,0 +1,232 @@ +## -*- Mode: Makefile -*- +## +## Makefile.am -- process this file with automake to produce Makefile.in +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . + +libdatadir = $(libdir)/@PACKAGE@ +SUBDIRS = test +AM_CPPFLAGS = @INCLIST@ +AM_CFLAGS = @WARN_CFLAGS@ +FSMTPL = fsm.tpl fsm-macro.tlib fsm-trans.tlib +templates = snarf.tpl $(FSMTPL) guile-iface.tpl +definitions = cgi.def opts.def pseudo.def guile-iface.def defParse.def \ + ag-text.def +ghdr = ag-text.h cgi-fsm.h defParse-fsm.h directive.h expr.h \ + functions.h guile-iface.h opts.h proto.h pseudo-fsm.h +gen_csrc = expr.ini defParse.x $(ghdr) +pkgdata_DATA = $(FSMTPL) +man_MANS = autogen.1 +DISTCLEANFILES = stamp-* ag.c +bin_PROGRAMS = autogen + +# The list of source files with AutoGen functions +# +FUNCLIST = funcCase.c funcDef.c funcEval.c funcFor.c funcIf.c functions.c + +# The list of source files with Guile expression functions defined, +# plus the parse/lex modules that must be in this order. +# +exprlist = defParse-fsm.c defLex.c directive.c $(FUNCLIST) \ + expExtract.c expFormat.c expGperf.c expGuile.c expMake.c \ + expOutput.c expPrint.c expState.c expString.c agShell.c + +csrc = autogen.c $(exprlist) \ + ag-text.c agCgi.c agDep.c agInit.c agUtils.c \ + cgi-fsm.c defDirect.c defFind.c defLoad.c fmemopen.c \ + loadPseudo.c opts.c scribble.c tpLoad.c tpParse.c \ + tpProcess.c + +all_src = $(csrc) $(gen_csrc) autogen.h scribble.h + +EXTRA_DIST = $(all_src) $(definitions) $(templates) $(man_MANS) \ + bootstrap.dir schemedef.scm \ + invoke-autogen.texi mk-stamps.sh + +LO_LIB = $(top_builddir)/autoopts/libopts.la +SNV_LIB = $(top_builddir)/snprintfv/libsnprintfv.la + +nodist_autogen_SOURCES = ag.c +autogen_SOURCES = $(gen_csrc) +autogen_LDADD = $(LO_LIB) $(SNV_LIB) $(GUILE_LIBS) +autogen_LDFLAGS = $(DYNAMIC_AG) $(AG_STATIC_AUTOGEN) -no-install +autogen_CFLAGS = $(GUILE_CFLAGS) +stamp_script = $(srcdir)/mk-stamps.sh + +AM_YFLAGS = -d + +ag.c : Makefile + exec > $@ ; \ + echo '#undef PKGDATADIR' ; \ + echo '#define PKGDATADIR "$(pkgdatadir)"' ; \ + echo '#undef LIBDATADIR' ; \ + echo '#define LIBDATADIR "$(libdatadir)"' ; \ + mk=`set -- $(MAKE) ; command -v $$1` ; \ + echo 'static char const make_prog[] = "'$$mk'";' ; \ + printf '\n#define DEFINING 1\n' ; \ + printf '#include "%s"\n' autoopts/project.h autogen.h ; \ + printf '#include "%s"\n' $(csrc) + +STAMPENV = top_srcdir="$(top_srcdir)" top_builddir="$(top_builddir)" \ + srcdir="$(srcdir)" AGexe="$(AGexe)" GDexe="$(GDexe)" CLexe="$(CLexe)" \ + DEPDIR="$(DEPDIR)" AG_TIMEOUT=$(AG_TIMEOUT) + +stamp-env : + $(STAMPENV) $(POSIX_SHELL) $(stamp_script) + +../snprintfv/snprintfv.h : + @if [ ! -f ../snprintfv/snprintfv.h ] ; then cd ../snprintfv ; \ + ln -s $(top_srcdir)/snprintfv/snprintfv/snprintfv.h . ; fi + +../snprintfv/libsnprintfv.la : + cd ../snprintfv ; $(MAKE) libsnprintfv.la + +.PHONY : stamp-env +.NOTPARALLEL: + +# start-generated-text + +if AMDEP +DEPFL_STAMP_OPTS= $(DEPDIR)/dep-stamp-opts.mk +$(DEPFL_STAMP_OPTS) : + $(SHELL) $(stamp_script) "$@" +include $(DEPFL_STAMP_OPTS) +DEPFL_STAMP_PROTO= $(DEPDIR)/dep-stamp-proto.mk +$(DEPFL_STAMP_PROTO) : + $(SHELL) $(stamp_script) "$@" +include $(DEPFL_STAMP_PROTO) +DEPFL_STAMP_PARSE= $(DEPDIR)/dep-stamp-parse.mk +$(DEPFL_STAMP_PARSE) : + $(SHELL) $(stamp_script) "$@" +include $(DEPFL_STAMP_PARSE) +DEPFL_STAMP_CGI= $(DEPDIR)/dep-stamp-cgi.mk +$(DEPFL_STAMP_CGI) : + $(SHELL) $(stamp_script) "$@" +include $(DEPFL_STAMP_CGI) +DEPFL_STAMP_PSEUDO= $(DEPDIR)/dep-stamp-pseudo.mk +$(DEPFL_STAMP_PSEUDO) : + $(SHELL) $(stamp_script) "$@" +include $(DEPFL_STAMP_PSEUDO) +DEPFL_STAMP_EXPRINI= $(DEPDIR)/dep-stamp-exprini.mk +$(DEPFL_STAMP_EXPRINI) : + $(SHELL) $(stamp_script) "$@" +include $(DEPFL_STAMP_EXPRINI) +DEPFL_STAMP_DIRECTIVE= $(DEPDIR)/dep-stamp-directive.mk +$(DEPFL_STAMP_DIRECTIVE) : + $(SHELL) $(stamp_script) "$@" +include $(DEPFL_STAMP_DIRECTIVE) +DEPFL_STAMP_TEXI= $(DEPDIR)/dep-stamp-texi.mk +$(DEPFL_STAMP_TEXI) : + $(SHELL) $(stamp_script) "$@" +include $(DEPFL_STAMP_TEXI) +DEPFL_STAMP_AG_TEXT= $(DEPDIR)/dep-stamp-ag_text.mk +$(DEPFL_STAMP_AG_TEXT) : + $(SHELL) $(stamp_script) "$@" +include $(DEPFL_STAMP_AG_TEXT) +DEPFL_STAMP_FMEM= $(DEPDIR)/dep-stamp-fmem.mk +$(DEPFL_STAMP_FMEM) : + $(SHELL) $(stamp_script) "$@" +include $(DEPFL_STAMP_FMEM) +DEPFL_STAMP_MAN= $(DEPDIR)/dep-stamp-man.mk +$(DEPFL_STAMP_MAN) : + $(SHELL) $(stamp_script) "$@" +include $(DEPFL_STAMP_MAN) +DEPFL_STAMP_FUNC= $(DEPDIR)/dep-stamp-func.mk +$(DEPFL_STAMP_FUNC) : + $(SHELL) $(stamp_script) "$@" +include $(DEPFL_STAMP_FUNC) +DEPFL_STAMP_GVER= $(DEPDIR)/dep-stamp-gver.mk +$(DEPFL_STAMP_GVER) : + $(SHELL) $(stamp_script) "$@" +include $(DEPFL_STAMP_GVER) +else +DEPFL_STAMP_OPTS= "$@" +DEPFL_STAMP_PROTO= "$@" +DEPFL_STAMP_PARSE= "$@" +DEPFL_STAMP_CGI= "$@" +DEPFL_STAMP_PSEUDO= "$@" +DEPFL_STAMP_EXPRINI= "$@" +DEPFL_STAMP_DIRECTIVE= "$@" +DEPFL_STAMP_TEXI= "$@" +DEPFL_STAMP_AG_TEXT= "$@" +DEPFL_STAMP_FMEM= "$@" +DEPFL_STAMP_MAN= "$@" +DEPFL_STAMP_FUNC= "$@" +DEPFL_STAMP_GVER= "$@" +endif +list_stamps = \ + stamp-opts stamp-proto stamp-parse stamp-cgi \ + stamp-pseudo stamp-exprini stamp-directive stamp-texi \ + stamp-ag_text stamp-fmem stamp-man stamp-func \ + stamp-gver + +stamp-opts: + @target="$(AUTOGEN_stamp_opts_TList)" \ + $(MAKE_STAMP) + +stamp-proto: + @target="$(AUTOGEN_stamp_proto_TList)" \ + $(MAKE_STAMP) + +stamp-parse: + @target="$(AUTOGEN_stamp_parse_TList)" \ + $(MAKE_STAMP) + +stamp-cgi: + @target="$(AUTOGEN_stamp_cgi_TList)" \ + $(MAKE_STAMP) + +stamp-pseudo: + @target="$(AUTOGEN_stamp_pseudo_TList)" \ + $(MAKE_STAMP) + +stamp-exprini: + @target="$(AUTOGEN_stamp_exprini_TList)" \ + $(MAKE_STAMP) + +stamp-directive: + @target="$(AUTOGEN_stamp_directive_TList)" \ + $(MAKE_STAMP) + +stamp-texi: + @target="$(AUTOGEN_stamp_texi_TList)" \ + $(MAKE_STAMP) + +stamp-ag_text: + @target="$(AUTOGEN_stamp_ag_text_TList)" \ + $(MAKE_STAMP) + +stamp-fmem: + @target="$(AUTOGEN_stamp_fmem_TList)" \ + $(MAKE_STAMP) + +stamp-man: + @target="$(AUTOGEN_stamp_man_TList)" \ + $(MAKE_STAMP) + +stamp-func: + @target="$(AUTOGEN_stamp_func_TList)" \ + $(MAKE_STAMP) + +stamp-gver: + @target="$(AUTOGEN_stamp_gver_TList)" \ + $(MAKE_STAMP) +.PHONY: stamps +stamps: $(list_stamps) + +# end-generated-text +# end of Makefile.am diff --git a/agen5/Makefile.in b/agen5/Makefile.in new file mode 100644 index 0000000..e423fb7 --- /dev/null +++ b/agen5/Makefile.in @@ -0,0 +1,1147 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 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. + +@SET_MAKE@ + + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +bin_PROGRAMS = autogen$(EXEEXT) +subdir = agen5 +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/ag_macros.m4 \ + $(top_srcdir)/config/asm-underscore.m4 \ + $(top_srcdir)/config/extensions.m4 \ + $(top_srcdir)/config/guile.m4 \ + $(top_srcdir)/config/host-cpu-c-abi.m4 \ + $(top_srcdir)/config/lib-ld.m4 \ + $(top_srcdir)/config/lib-link.m4 \ + $(top_srcdir)/config/lib-prefix.m4 \ + $(top_srcdir)/config/libopts.m4 \ + $(top_srcdir)/config/libtool.m4 \ + $(top_srcdir)/config/ltoptions.m4 \ + $(top_srcdir)/config/ltsugar.m4 \ + $(top_srcdir)/config/ltversion.m4 \ + $(top_srcdir)/config/lt~obsolete.m4 \ + $(top_srcdir)/config/onceonly.m4 $(top_srcdir)/config/pkg.m4 \ + $(top_srcdir)/config/snprintfv.m4 \ + $(top_srcdir)/config/stdnoreturn.m4 \ + $(top_srcdir)/config/unlocked-io.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" \ + "$(DESTDIR)$(pkgdatadir)" +PROGRAMS = $(bin_PROGRAMS) +am__objects_1 = +am__objects_2 = $(am__objects_1) +am_autogen_OBJECTS = $(am__objects_2) +nodist_autogen_OBJECTS = autogen-ag.$(OBJEXT) +autogen_OBJECTS = $(am_autogen_OBJECTS) $(nodist_autogen_OBJECTS) +am__DEPENDENCIES_1 = +autogen_DEPENDENCIES = $(LO_LIB) $(SNV_LIB) $(am__DEPENDENCIES_1) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +autogen_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(autogen_CFLAGS) \ + $(CFLAGS) $(autogen_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/config/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/autogen-ag.Po +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(autogen_SOURCES) $(nodist_autogen_SOURCES) +DIST_SOURCES = $(autogen_SOURCES) +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +man1dir = $(mandir)/man1 +NROFF = nroff +MANS = $(man_MANS) +DATA = $(pkgdata_DATA) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir distdir-am +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/config/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +AGEN5_TESTS = @AGEN5_TESTS@ +AG_LDFLAGS = @AG_LDFLAGS@ +AG_MAJOR_VERSION = @AG_MAJOR_VERSION@ +AG_MINOR_VERSION = @AG_MINOR_VERSION@ +AG_STATIC_AUTOGEN = @AG_STATIC_AUTOGEN@ +AG_TIMEOUT = @AG_TIMEOUT@ +AG_VERSION = @AG_VERSION@ +AG_XML2 = @AG_XML2@ +AGexe = @AGexe@ +AGnam = @AGnam@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AO_AGE = @AO_AGE@ +AO_CURRENT = @AO_CURRENT@ +AO_REVISION = @AO_REVISION@ +AO_TEMPLATE_VERSION = @AO_TEMPLATE_VERSION@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLexe = @CLexe@ +CLnam = @CLnam@ +CONFIG_SHELL = @CONFIG_SHELL@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBUG_ENABLED = @DEBUG_ENABLED@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +DYNAMIC_AG = @DYNAMIC_AG@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_STATIC = @ENABLE_STATIC@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GDexe = @GDexe@ +GDnam = @GDnam@ +GO_AGE = @GO_AGE@ +GO_CURRENT = @GO_CURRENT@ +GO_REVISION = @GO_REVISION@ +GREP = @GREP@ +GUILE_CFLAGS = @GUILE_CFLAGS@ +GUILE_EFFECTIVE_VERSION = @GUILE_EFFECTIVE_VERSION@ +GUILE_LDFLAGS = @GUILE_LDFLAGS@ +GUILE_LIBS = @GUILE_LIBS@ +GUILE_LTLIBS = @GUILE_LTLIBS@ +HOST_CPU = @HOST_CPU@ +HOST_CPU_C_ABI = @HOST_CPU_C_ABI@ +INCLIST = @INCLIST@ +INCSNPRINTFV = @INCSNPRINTFV@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSNPRINTFV = @LIBSNPRINTFV@ +LIBTOOL = @LIBTOOL@ +LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ +LIBXML2_LIBS = @LIBXML2_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +M4_SRC = @M4_SRC@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPTS_TESTDIR = @OPTS_TESTDIR@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSIX_SHELL = @POSIX_SHELL@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STDNORETURN_H = @STDNORETURN_H@ +STRIP = @STRIP@ +TEXI2HTML = @TEXI2HTML@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_aux_dir = @ac_aux_dir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +libdatadir = $(libdir)/@PACKAGE@ +SUBDIRS = test +AM_CPPFLAGS = @INCLIST@ +AM_CFLAGS = @WARN_CFLAGS@ +FSMTPL = fsm.tpl fsm-macro.tlib fsm-trans.tlib +templates = snarf.tpl $(FSMTPL) guile-iface.tpl +definitions = cgi.def opts.def pseudo.def guile-iface.def defParse.def \ + ag-text.def + +ghdr = ag-text.h cgi-fsm.h defParse-fsm.h directive.h expr.h \ + functions.h guile-iface.h opts.h proto.h pseudo-fsm.h + +gen_csrc = expr.ini defParse.x $(ghdr) +pkgdata_DATA = $(FSMTPL) +man_MANS = autogen.1 +DISTCLEANFILES = stamp-* ag.c + +# The list of source files with AutoGen functions +# +FUNCLIST = funcCase.c funcDef.c funcEval.c funcFor.c funcIf.c functions.c + +# The list of source files with Guile expression functions defined, +# plus the parse/lex modules that must be in this order. +# +exprlist = defParse-fsm.c defLex.c directive.c $(FUNCLIST) \ + expExtract.c expFormat.c expGperf.c expGuile.c expMake.c \ + expOutput.c expPrint.c expState.c expString.c agShell.c + +csrc = autogen.c $(exprlist) \ + ag-text.c agCgi.c agDep.c agInit.c agUtils.c \ + cgi-fsm.c defDirect.c defFind.c defLoad.c fmemopen.c \ + loadPseudo.c opts.c scribble.c tpLoad.c tpParse.c \ + tpProcess.c + +all_src = $(csrc) $(gen_csrc) autogen.h scribble.h +EXTRA_DIST = $(all_src) $(definitions) $(templates) $(man_MANS) \ + bootstrap.dir schemedef.scm \ + invoke-autogen.texi mk-stamps.sh + +LO_LIB = $(top_builddir)/autoopts/libopts.la +SNV_LIB = $(top_builddir)/snprintfv/libsnprintfv.la +nodist_autogen_SOURCES = ag.c +autogen_SOURCES = $(gen_csrc) +autogen_LDADD = $(LO_LIB) $(SNV_LIB) $(GUILE_LIBS) +autogen_LDFLAGS = $(DYNAMIC_AG) $(AG_STATIC_AUTOGEN) -no-install +autogen_CFLAGS = $(GUILE_CFLAGS) +stamp_script = $(srcdir)/mk-stamps.sh +AM_YFLAGS = -d +STAMPENV = top_srcdir="$(top_srcdir)" top_builddir="$(top_builddir)" \ + srcdir="$(srcdir)" AGexe="$(AGexe)" GDexe="$(GDexe)" CLexe="$(CLexe)" \ + DEPDIR="$(DEPDIR)" AG_TIMEOUT=$(AG_TIMEOUT) + +@AMDEP_FALSE@DEPFL_STAMP_OPTS = "$@" + +# start-generated-text +@AMDEP_TRUE@DEPFL_STAMP_OPTS = $(DEPDIR)/dep-stamp-opts.mk +@AMDEP_FALSE@DEPFL_STAMP_PROTO = "$@" +@AMDEP_TRUE@DEPFL_STAMP_PROTO = $(DEPDIR)/dep-stamp-proto.mk +@AMDEP_FALSE@DEPFL_STAMP_PARSE = "$@" +@AMDEP_TRUE@DEPFL_STAMP_PARSE = $(DEPDIR)/dep-stamp-parse.mk +@AMDEP_FALSE@DEPFL_STAMP_CGI = "$@" +@AMDEP_TRUE@DEPFL_STAMP_CGI = $(DEPDIR)/dep-stamp-cgi.mk +@AMDEP_FALSE@DEPFL_STAMP_PSEUDO = "$@" +@AMDEP_TRUE@DEPFL_STAMP_PSEUDO = $(DEPDIR)/dep-stamp-pseudo.mk +@AMDEP_FALSE@DEPFL_STAMP_EXPRINI = "$@" +@AMDEP_TRUE@DEPFL_STAMP_EXPRINI = $(DEPDIR)/dep-stamp-exprini.mk +@AMDEP_FALSE@DEPFL_STAMP_DIRECTIVE = "$@" +@AMDEP_TRUE@DEPFL_STAMP_DIRECTIVE = $(DEPDIR)/dep-stamp-directive.mk +@AMDEP_FALSE@DEPFL_STAMP_TEXI = "$@" +@AMDEP_TRUE@DEPFL_STAMP_TEXI = $(DEPDIR)/dep-stamp-texi.mk +@AMDEP_FALSE@DEPFL_STAMP_AG_TEXT = "$@" +@AMDEP_TRUE@DEPFL_STAMP_AG_TEXT = $(DEPDIR)/dep-stamp-ag_text.mk +@AMDEP_FALSE@DEPFL_STAMP_FMEM = "$@" +@AMDEP_TRUE@DEPFL_STAMP_FMEM = $(DEPDIR)/dep-stamp-fmem.mk +@AMDEP_FALSE@DEPFL_STAMP_MAN = "$@" +@AMDEP_TRUE@DEPFL_STAMP_MAN = $(DEPDIR)/dep-stamp-man.mk +@AMDEP_FALSE@DEPFL_STAMP_FUNC = "$@" +@AMDEP_TRUE@DEPFL_STAMP_FUNC = $(DEPDIR)/dep-stamp-func.mk +@AMDEP_FALSE@DEPFL_STAMP_GVER = "$@" +@AMDEP_TRUE@DEPFL_STAMP_GVER = $(DEPDIR)/dep-stamp-gver.mk +list_stamps = \ + stamp-opts stamp-proto stamp-parse stamp-cgi \ + stamp-pseudo stamp-exprini stamp-directive stamp-texi \ + stamp-ag_text stamp-fmem stamp-man stamp-func \ + stamp-gver + +all: all-recursive + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu agen5/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu agen5/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p \ + || test -f $$p1 \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' \ + `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +autogen$(EXEEXT): $(autogen_OBJECTS) $(autogen_DEPENDENCIES) $(EXTRA_autogen_DEPENDENCIES) + @rm -f autogen$(EXEEXT) + $(AM_V_CCLD)$(autogen_LINK) $(autogen_OBJECTS) $(autogen_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/autogen-ag.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +autogen-ag.o: ag.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(autogen_CFLAGS) $(CFLAGS) -MT autogen-ag.o -MD -MP -MF $(DEPDIR)/autogen-ag.Tpo -c -o autogen-ag.o `test -f 'ag.c' || echo '$(srcdir)/'`ag.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/autogen-ag.Tpo $(DEPDIR)/autogen-ag.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ag.c' object='autogen-ag.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(autogen_CFLAGS) $(CFLAGS) -c -o autogen-ag.o `test -f 'ag.c' || echo '$(srcdir)/'`ag.c + +autogen-ag.obj: ag.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(autogen_CFLAGS) $(CFLAGS) -MT autogen-ag.obj -MD -MP -MF $(DEPDIR)/autogen-ag.Tpo -c -o autogen-ag.obj `if test -f 'ag.c'; then $(CYGPATH_W) 'ag.c'; else $(CYGPATH_W) '$(srcdir)/ag.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/autogen-ag.Tpo $(DEPDIR)/autogen-ag.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ag.c' object='autogen-ag.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(autogen_CFLAGS) $(CFLAGS) -c -o autogen-ag.obj `if test -f 'ag.c'; then $(CYGPATH_W) 'ag.c'; else $(CYGPATH_W) '$(srcdir)/ag.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-man1: $(man_MANS) + @$(NORMAL_INSTALL) + @list1=''; \ + list2='$(man_MANS)'; \ + test -n "$(man1dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.1[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ + done; } + +uninstall-man1: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man1dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.1[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) +install-pkgdataDATA: $(pkgdata_DATA) + @$(NORMAL_INSTALL) + @list='$(pkgdata_DATA)'; test -n "$(pkgdatadir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkgdatadir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkgdatadir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgdatadir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgdatadir)" || exit $$?; \ + done + +uninstall-pkgdataDATA: + @$(NORMAL_UNINSTALL) + @list='$(pkgdata_DATA)'; test -n "$(pkgdatadir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkgdatadir)'; $(am__uninstall_files_from_dir) + +# 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. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile $(PROGRAMS) $(MANS) $(DATA) +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(pkgdatadir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f ./$(DEPDIR)/autogen-ag.Po + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: install-man install-pkgdataDATA + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: install-binPROGRAMS + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: install-man1 + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f ./$(DEPDIR)/autogen-ag.Po + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-man \ + uninstall-pkgdataDATA + +uninstall-man: uninstall-man1 + +.MAKE: $(am__recursive_targets) install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ + am--depfiles check check-am clean clean-binPROGRAMS \ + clean-generic clean-libtool cscopelist-am ctags ctags-am \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-binPROGRAMS \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-man1 \ + install-pdf install-pdf-am install-pkgdataDATA install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am uninstall-binPROGRAMS \ + uninstall-man uninstall-man1 uninstall-pkgdataDATA + +.PRECIOUS: Makefile + + +ag.c : Makefile + exec > $@ ; \ + echo '#undef PKGDATADIR' ; \ + echo '#define PKGDATADIR "$(pkgdatadir)"' ; \ + echo '#undef LIBDATADIR' ; \ + echo '#define LIBDATADIR "$(libdatadir)"' ; \ + mk=`set -- $(MAKE) ; command -v $$1` ; \ + echo 'static char const make_prog[] = "'$$mk'";' ; \ + printf '\n#define DEFINING 1\n' ; \ + printf '#include "%s"\n' autoopts/project.h autogen.h ; \ + printf '#include "%s"\n' $(csrc) + +stamp-env : + $(STAMPENV) $(POSIX_SHELL) $(stamp_script) + +../snprintfv/snprintfv.h : + @if [ ! -f ../snprintfv/snprintfv.h ] ; then cd ../snprintfv ; \ + ln -s $(top_srcdir)/snprintfv/snprintfv/snprintfv.h . ; fi + +../snprintfv/libsnprintfv.la : + cd ../snprintfv ; $(MAKE) libsnprintfv.la + +.PHONY : stamp-env +.NOTPARALLEL: +@AMDEP_TRUE@$(DEPFL_STAMP_OPTS) : +@AMDEP_TRUE@ $(SHELL) $(stamp_script) "$@" +@AMDEP_TRUE@include $(DEPFL_STAMP_OPTS) +@AMDEP_TRUE@$(DEPFL_STAMP_PROTO) : +@AMDEP_TRUE@ $(SHELL) $(stamp_script) "$@" +@AMDEP_TRUE@include $(DEPFL_STAMP_PROTO) +@AMDEP_TRUE@$(DEPFL_STAMP_PARSE) : +@AMDEP_TRUE@ $(SHELL) $(stamp_script) "$@" +@AMDEP_TRUE@include $(DEPFL_STAMP_PARSE) +@AMDEP_TRUE@$(DEPFL_STAMP_CGI) : +@AMDEP_TRUE@ $(SHELL) $(stamp_script) "$@" +@AMDEP_TRUE@include $(DEPFL_STAMP_CGI) +@AMDEP_TRUE@$(DEPFL_STAMP_PSEUDO) : +@AMDEP_TRUE@ $(SHELL) $(stamp_script) "$@" +@AMDEP_TRUE@include $(DEPFL_STAMP_PSEUDO) +@AMDEP_TRUE@$(DEPFL_STAMP_EXPRINI) : +@AMDEP_TRUE@ $(SHELL) $(stamp_script) "$@" +@AMDEP_TRUE@include $(DEPFL_STAMP_EXPRINI) +@AMDEP_TRUE@$(DEPFL_STAMP_DIRECTIVE) : +@AMDEP_TRUE@ $(SHELL) $(stamp_script) "$@" +@AMDEP_TRUE@include $(DEPFL_STAMP_DIRECTIVE) +@AMDEP_TRUE@$(DEPFL_STAMP_TEXI) : +@AMDEP_TRUE@ $(SHELL) $(stamp_script) "$@" +@AMDEP_TRUE@include $(DEPFL_STAMP_TEXI) +@AMDEP_TRUE@$(DEPFL_STAMP_AG_TEXT) : +@AMDEP_TRUE@ $(SHELL) $(stamp_script) "$@" +@AMDEP_TRUE@include $(DEPFL_STAMP_AG_TEXT) +@AMDEP_TRUE@$(DEPFL_STAMP_FMEM) : +@AMDEP_TRUE@ $(SHELL) $(stamp_script) "$@" +@AMDEP_TRUE@include $(DEPFL_STAMP_FMEM) +@AMDEP_TRUE@$(DEPFL_STAMP_MAN) : +@AMDEP_TRUE@ $(SHELL) $(stamp_script) "$@" +@AMDEP_TRUE@include $(DEPFL_STAMP_MAN) +@AMDEP_TRUE@$(DEPFL_STAMP_FUNC) : +@AMDEP_TRUE@ $(SHELL) $(stamp_script) "$@" +@AMDEP_TRUE@include $(DEPFL_STAMP_FUNC) +@AMDEP_TRUE@$(DEPFL_STAMP_GVER) : +@AMDEP_TRUE@ $(SHELL) $(stamp_script) "$@" +@AMDEP_TRUE@include $(DEPFL_STAMP_GVER) + +stamp-opts: + @target="$(AUTOGEN_stamp_opts_TList)" \ + $(MAKE_STAMP) + +stamp-proto: + @target="$(AUTOGEN_stamp_proto_TList)" \ + $(MAKE_STAMP) + +stamp-parse: + @target="$(AUTOGEN_stamp_parse_TList)" \ + $(MAKE_STAMP) + +stamp-cgi: + @target="$(AUTOGEN_stamp_cgi_TList)" \ + $(MAKE_STAMP) + +stamp-pseudo: + @target="$(AUTOGEN_stamp_pseudo_TList)" \ + $(MAKE_STAMP) + +stamp-exprini: + @target="$(AUTOGEN_stamp_exprini_TList)" \ + $(MAKE_STAMP) + +stamp-directive: + @target="$(AUTOGEN_stamp_directive_TList)" \ + $(MAKE_STAMP) + +stamp-texi: + @target="$(AUTOGEN_stamp_texi_TList)" \ + $(MAKE_STAMP) + +stamp-ag_text: + @target="$(AUTOGEN_stamp_ag_text_TList)" \ + $(MAKE_STAMP) + +stamp-fmem: + @target="$(AUTOGEN_stamp_fmem_TList)" \ + $(MAKE_STAMP) + +stamp-man: + @target="$(AUTOGEN_stamp_man_TList)" \ + $(MAKE_STAMP) + +stamp-func: + @target="$(AUTOGEN_stamp_func_TList)" \ + $(MAKE_STAMP) + +stamp-gver: + @target="$(AUTOGEN_stamp_gver_TList)" \ + $(MAKE_STAMP) +.PHONY: stamps +stamps: $(list_stamps) + +# end-generated-text +# end of Makefile.am + +# 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/agen5/ag-text.c b/agen5/ag-text.c new file mode 100644 index 0000000..47cfca5 --- /dev/null +++ b/agen5/ag-text.c @@ -0,0 +1,753 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * DO NOT EDIT THIS FILE (ag-text.c) + * + * It has been AutoGen-ed + * From the definitions /u/bkorb/tools/ag/autogen-bld/agen5/ag-text.def + * and the template file strings + * + * Copyright (C) 2011-2018 Bruce Korb, all rights reserved. + * This is free software. It is licensed for use, modification and + * redistribution under the terms of the + * Modified (3 clause) Berkeley Software Distribution License + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name ``Bruce Korb'' nor the name of any other + * contributor may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * strings IS PROVIDED BY Bruce Korb ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Bruce Korb OR ANY OTHER CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "ag-text.h" + +char const ag_text_strtable[16331] = +/* 0 */ "ag-text.c\0" +/* 10 */ "The '%d' address family cannot be handled\0" +/* 52 */ "%s__\0" +/* 57 */ "%s=1\0" +/* 62 */ "ABEND-ing in %s state\n\0" +/* 85 */ "processing template %s\n" + " on line %d\n" + " for function %s (%d)\n\0" +/* 160 */ "ag-fprintf: 'port' is invalid\0" +/* 190 */ "AUTOGEN_MAKE_DEP\0" +/* 207 */ "autogen5\0" +/* 216 */ "AutoGen caught signal %d (%s) before initialization completed\n\0" +/* 279 */ "AutoGen aborting on signal %d (%s) in state %s\n\0" +/* 327 */ "Scheme definition expression does not yield string:\n\0" +/* 380 */ "Scheme Computed Definitions\0" +/* 408 */ "(alist->autogen-def %s)\0" +/* 432 */ "could not allocate for or formatting failed on:\n" + "%s\0" +/* 483 */ "asprintfv returned 0x%08X\n\0" +/* 510 */ "%s Error: Invalid input char '%c' in %s on line %d\n\0" +/* 562 */ "Cannot %s from outside a loop\0" +/* 592 */ "Could not resolve macro name: '%s'\0" +/* 627 */ "??? indecipherable error message ???\0" +/* 664 */ "Ill formed name '%s' in %s line %d\n\0" +/* 700 */ "Invalid regular expression: error %d (%s):\n" + "%s\0" +/* 747 */ "--base-name name is too long\0" +/* 776 */ "** BOGUS **\0" +/* 788 */ "break\0" +/* 794 */ "%lu\0" +/* 798 */ "fserr %d: cannot %s %s: %s\n\0" +/* 827 */ "duplicate make target\0" +/* 849 */ "unknown dependency type: %s\0" +/* 878 */ "Content-type: text/plain\n\n" + "AutoGen form processing error:\n\0" +/* 936 */ "CGI parsing error: %s\0" +/* 959 */ "/tmp/cgi-stderr-XXXXXX\0" +/* 982 */ "CLOSING SHELL SERVER - command failure:\n" + "\t%s\n\0" +/* 1027 */ "%s Error: %s in %s on line %d\n\0" +/* 1059 */ "DEFINITIONS %s in %s line %d for %s:\n" + "\t%s\n\0" +/* 1101 */ "Bad regular expression\0" +/* 1124 */ "continue\0" +/* 1133 */ "\\n\"\n" + " \"\0" +/* 1146 */ "from %s line %d\0" +/* 1162 */ "block\0" +/* 1168 */ "INVALID\0" +/* 1176 */ "text\0" +/* 1181 */ "unknown\0" +/* 1189 */ " \\\n\0" +/* 1193 */ "\n" + ".PHONY : clean-%1$s\n\n" + "clean-%1$s :\n" + "\trm -f %3$s $(%2$s_TList)\n" + "\t@-touch -t 199912312359 %1$s\n\0" +/* 1285 */ "\n" + "%2$s : $(%1$s_SList)\n\n" + "$(%1$s_TList) : %2$s\n" + "\t@:\n\0" +/* 1334 */ " \\\n" + "\t%s\0" +/* 1341 */ "DEPENDENCIES_OUTPUT\0" +/* 1361 */ "\n\n" + "%s_SList =\0" +/* 1374 */ "%s_TList =\0" +/* 1385 */ "/dev/null\0" +/* 1395 */ "baseless\0" +/* 1404 */ "-\0" +/* 1406 */ "=1\0" +/* 1409 */ "$@\0" +/* 1412 */ "$$/../share/autogen\0" +/* 1432 */ "\n" + "#\0" +/* 1435 */ "#assert yielded \"%s\":\n" + "\t`%s`\0" +/* 1463 */ "'#%s' directive encountered out of context\n" + "\tin %s on line %d\n\0" +/* 1525 */ "#error directive -- in %s on line %d\n" + "\t%s\n\0" +/* 1567 */ "open\0" +/* 1572 */ "read\0" +/* 1577 */ "def\0" +/* 1581 */ "WARNING: fserr %d (%s) performing '%s' on %s\n\0" +/* 1627 */ "Definition error: in %s line %d, #endif not found\n\0" +/* 1679 */ "Definition error: in %s line %d, #%s no matching start/if directive\n\0" +/* 1749 */ "Missing #endshell after '#shell' in %s on line %d\n\0" +/* 1800 */ "Computed Definitions\0" +/* 1821 */ "\n" + "#endshell\0" +/* 1832 */ "done_check done\n\0" +/* 1849 */ "done_check re-done\n\0" +/* 1869 */ "%s.%s\0" +/* 1875 */ "\n\n\0" +/* 1878 */ "%s ERROR: Too many definition files\n\0" +/* 1916 */ "%soutput was abandoned\n\0" +/* 1940 */ "%sBogus return from setjmp\n\0" +/* 1968 */ "content-type: text/html\n\n\0" +/* 1994 */ "* NONE *\0" +/* 2003 */ "Starting stdout template\n\0" +/* 2029 */ "stdout\0" +/* 2036 */ "invalid chars in suffix format: %s\0" +/* 2072 */ "Empty suffix format\0" +/* 2092 */ "Duplicate value index for %s: %d\0" +/* 2126 */ "#elif directive found out of context\0" +/* 2163 */ "invalid emission port: %lu\0" +/* 2190 */ "*/\0" +/* 2193 */ "ERROR\0" +/* 2199 */ "Error in template %s, line %d\n" + "\t\0" +/* 2231 */ "attempted to use block macro in eval expression\0" +/* 2279 */ "PROGRAM ERROR: ambiguous expr code\0" +/* 2315 */ "exit_cleanup %s done\n" + "===AutoGen ends - %u\n\n\0" +/* 2359 */ "false\0" +/* 2365 */ "exit_cleanup re-done\n\0" +/* 2387 */ "no waiting\0" +/* 2398 */ "(if (> (string-length shell-cleanup) 0) (shellf \"( (%s) & >/dev/null 2>&1 )\" shell-cleanup) )\0" +/* 2492 */ "waited\0" +/* 2499 */ "an unknown license\0" +/* 2518 */ "%6$s%1$sDO NOT EDIT THIS FILE (%2$s)\n" + "%1$s\n" + "%1$sIt has been AutoGen-ed%3$s\n" + "%1$sFrom the definitions %4$s\n" + "%1$sand the template file %5$s\0" +/* 2659 */ "%s -*- buffer-read-only: t -*- vi: set ro:\n" + "%s\n\0" +/* 2706 */ "%6$s%1$sEDIT THIS FILE WITH CAUTION (%2$s)\n" + "%1$s\n" + "%1$sIt has been AutoGen-ed%3$s\n" + "%1$sFrom the definitions %4$s\n" + "%1$sand the template file %5$s\0" +/* 2852 */ "WARNING: in %s on line %d unknown directive:\n" + "\t#%s\n\0" +/* 2904 */ "DO NOT CHANGE THIS COMMENT\0" +/* 2931 */ "name not followed by '='\0" +/* 2956 */ "no space separating entries\0" +/* 2984 */ "END \0" +/* 2990 */ "START\0" +/* 2996 */ "# %2$d \"%1$s\"\0" +/* 3010 */ "failed\n\0" +/* 3018 */ "SUCCESS\n\0" +/* 3027 */ ".\0" +/* 3029 */ "%s/%s\0" +/* 3035 */ "find-file\0" +/* 3045 */ "agpl\0" +/* 3050 */ "read full file\0" +/* 3065 */ "invalid license file: %s\0" +/* 3090 */ "lgpl\0" +/* 3095 */ "mbsd\0" +/* 3100 */ "stat file\0" +/* 3110 */ "lic\0" +/* 3114 */ "macros cannot nest\0" +/* 3133 */ "macro has no end\0" +/* 3150 */ "WARNING: empty macro in %s line %d\n\0" +/* 3186 */ " -- DEBUG %s -- FOR index %d\0" +/* 3217 */ "%d (%s) is an unknown macro function, or has no handler\0" +/* 3273 */ "? Say, what ?\0" +/* 3287 */ " (%c)\0" +/* 3293 */ "ELSE clause\0" +/* 3305 */ "FOR x IN ... has no list\0" +/* 3330 */ "_GUARD\0" +/* 3337 */ " - FOR-%s %s[%d] it#%d: Nxt %d, first=%s, last=%s\n\0" +/* 3390 */ "'get' invoked with no name in %s line %u\n\0" +/* 3432 */ "'get %s' retrieved in %s line %u\n\0" +/* 3466 */ "Failing Guile command: = = = = =\n\n" + "%s\n\n" + "=================================\n\0" +/* 3540 */ "Could not decipher Guile version: %s\n\0" +/* 3578 */ "Compiled Guile version does not match: %s vs %s\n\0" +/* 3627 */ "GUILE_WARN_DEPRECATED\0" +/* 3649 */ "GUILE_WARN_DEPRECATED=no\0" +/* 3674 */ "els\0" +/* 3678 */ "the\0" +/* 3682 */ "Invalid template file\0" +/* 3704 */ "SHELL=\0" +/* 3711 */ "lse\0" +/* 3715 */ "ndif\0" +/* 3720 */ "fdef \0" +/* 3726 */ "fndef \0" +/* 3733 */ "HEADER\0" +/* 3740 */ "Unterminated HereString\0" +/* 3764 */ "HereString missing the mark\0" +/* 3792 */ "&#%d;\0" +/* 3798 */ "(debug-enable 'backtrace)\0" +/* 3824 */ "HereString mark 64 or more chars\0" +/* 3857 */ "');\n" + "document.write('\" >%s');\n" + "//-->\n" + "\0" +/* 3906 */ ""; }; + +string = { nm = HIDE_EMAIL_START_STR; + str = " +_EOF_ + +export AUTOGEN_DNE_DATE=false + run_ag x ${testname}.def || failure autogen failed +cmp -s ${testname}.base ${testname}.test || \ + failure "`diff ${testname}.base ${testname}.test`" + +AUTOGEN_DNE_DATE=true + run_ag x ${testname}.def || failure autogen failed +dte=`sed -n 's/.*It has been AutoGen-ed *//p' ${testname}.test` +test "X${dte}" = "X" && \ + failure "expected a date on the 'It has been AutoGen-ed' line${nl}` + cat ${testname}.testln`" + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of format.test diff --git a/agen5/test/get.test b/agen5/test/get.test new file mode 100755 index 0000000..45b0d48 --- /dev/null +++ b/agen5/test/get.test @@ -0,0 +1,94 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# get.test --- test get functionality +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . +## +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # TEMPLATE FILE # # # # # # # # # + +echo creating $testname.tpl +cat > $testname.tpl <<_EOF_ +[= AutoGen5 template test =] +[= + +IF (not (exist? "foo.bar.baz")) =][= + (error "foo.bar.baz does, too, exist!") =][= + +ELIF (not (= "mumble" (get "foo.bar.baz"))) =][= + (error (sprintf "We got the wrong baz. We got: %s" + (get "foo.bar.baz"))) =][= +ELSE + =]A OK[= +ENDIF =][= + +- bogus "\nA OK2" =][= +- foo "\nBOGUS" =] +[= (get "fuz-zy") =] +[= (get "fuz_zy") =] +[= (get "fuz^zy") =] +[= (get-c-name "fuz-zy") =] +[= (get-up-name "fuz-zy") =] +[= (get-down-name "fuz-zy") =] +_EOF_ + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +echo creating $testname.def +cat > $testname.def <<_EOF_ +AutoGen definitions $testname; + +foo = { bar = { nada = nothing; }; }; +foo = { bar = { baz = mumble; }; }; /* this is the one */ +foo = { bar = { baz = grumble; }; }; +fuz-zy = Mum-Ble; +_EOF_ + +# # # # # # # # # # EXPECTED OUTPUT FILE # # # # # # # +set -x +echo creating $testname.out +# this is the output we should expect to see +cat > $testname.out <<'_EOF_' +A OK +A OK2 +Mum-Ble +Mum-Ble +Mum-Ble +Mum_Ble +MUM_BLE +mum_ble +_EOF_ + +run_ag x $testname.def || failure autogen failed +cmp -s $testname.test $testname.out || failure unexpected output + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of get.test diff --git a/agen5/test/gperf.test b/agen5/test/gperf.test new file mode 100755 index 0000000..cb6a0aa --- /dev/null +++ b/agen5/test/gperf.test @@ -0,0 +1,94 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# gperf.test --- test functionality of `gperf' +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . +# ---------------------------------------------------------------------- + +if gperf --version > /dev/null 2>&1 +then : +else + echo gperf functionality does not work without gperf >&2 + exit 0 +fi + +. ./defs + +# # # # # # # # # # TEMPLATE FILE # # # # # # # # # + +echo creating ${testname}.tpl +cat > ${testname}.tpl <<_EOF_ +<= AutoGen5 template test => +<= + +(if (not (make-gperf "${testname}" (stack "foo.bar"))) + (error "cannot make gperf")) =><= + +FOR foo "\n" =><= + + FOR bar => +<=bar=> yields: <=(gperf "${testname}" (get "bar"))=><= + ENDFOR =><= + +ENDFOR =><= +\`tar cf - .${testname}.* > ${testname}-prog.tar || \ + die 'cannot save gperf files'\`=><= +(out-push-new "${testname}-code.c") +(emit (gperf-code "${testname}")) (emit "\n") +(out-pop) +=> +_EOF_ + + +# Create the files we need in the test environment +cat > ${testname}.def <<_EOF_ +AutoGen Definitions ${testname}; +foo = { bar = first; bar = second; }; +foo = { bar = third; bar = fourth; }; +_EOF_ + +# this is the output we should expect to see +cat > ${testname}.base <<_EOF_ + +first yields: 0x01 +second yields: 0x02 + +third yields: 0x03 +fourth yields: 0x04 +_EOF_ + +if ${VERBOSE:-false} +then opts="x --trace=server-shell ${testname}.def" +else opts="x ${testname}.def" +fi + +run_ag ${opts} || failure AutoGen failed +cmp -s ${testname}.base ${testname}.test || \ + failure "`diff ${testname}.base ${testname}.test`" + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of gperf.test diff --git a/agen5/test/heredef.test b/agen5/test/heredef.test new file mode 100755 index 0000000..8e8f06f --- /dev/null +++ b/agen5/test/heredef.test @@ -0,0 +1,101 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# heredef.test --- definition reference testing +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . +## +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # TEMPLATE FILE # # # # # # # # # + +${SED} 's/^ *[0-9]*: //' > ${testname}.tpl <<\_EOF_ + 1: <= AutoGen5 template test => + 2: <= + 3: + 4: (if (not (= (get "string1") (get "string2"))) + 5: (error (sprintf "`%s' <> `%s'" + 6: (get "string1") (get "string2") )) ) + 7: + 8: =><= + 9: +10: (if (not (= (get "string2") (get "string3"))) +11: (error (sprintf "`%s' <> `%s'" +12: (get "string1") (get "string2") )) ) +13: =>OKAY: <= (c-string (get "string3")) => +14: FROM: string1 extracted <= (def-file-line "string1") => +15: string2 extracted +16: <= (def-file-line "string2" c-file-line-fmt) => +17: string3 extracted <= +18: (def-file-line "string3" "From %1$s on line %2$d") => +_EOF_ + +# # # # # # # # # # SAMPLE FILE # # # # # # # # # +cat > ${testname}.sample <<\_EOF_ +OKAY: "\"`Testing'" +FROM: string1 extracted from heredef.def line 11 + string2 extracted +#line 15 "heredef.def" + + string3 extracted From heredef.def on line 18 +_EOF_ + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +# Create the files we need in the test environment +echo "AutoGen definitions ${testname};" > ${testname}.def +${SED} 's/^ *[0-9]*: //' >> ${testname}.def <<\_EOF_ + 2: #ifdef BOGUS + 3: /* Line 3 */ + 4: #else + 5: #ifdef WRONG + 6: /* line 6 */ + 7: #endif + 8: #endif + 9: /* line 9 */ +10: string1 = <<- AG_EOF +11: "`Testing' +12: AG_EOF; /* " */ +13: /* line 13 */ +14: string2 = <<- AG_EOF +15: "`Testing' +16: AG_EOF; /* " */ +17: +18: string3 = "\"`Testing'"; /* line 18 */ +19: +_EOF_ + +run_ag x ${testname}.def || failure ${testname} AutoGen failed + +if cmp ${testname}.test ${testname}.sample +then cleanup +else failure "`diff ${testname}.sample ${testname}.test`" +fi + + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of heredef.test diff --git a/agen5/test/html.test b/agen5/test/html.test new file mode 100755 index 0000000..6a81a71 --- /dev/null +++ b/agen5/test/html.test @@ -0,0 +1,129 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# ---------------------------------------------------------------------- +# html.test --- test html generation +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . +## +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # TEMPLATE FILES # # # # # # # # # + +echo creating cgi.tpl +cat > cgi.tpl <<'_EOF_' + +HTTP/1.0 500 AutoGen Forms Error +Content-Type: text/plain + +The submitted form does not contain a valid template () . +_EOF_ + +echo creating ${testname}.tpl +cat > ${testname}.tpl <<'_EOF_' + +Mumble: +Foolish: +_EOF_ + +# # # # # # # SAMPLE OUTPUT FILE # # # # # # + +echo creating ${testname}.out in `pwd` +# this is the output we should expect to see +cat > ${testname}.samp <<'_EOF_' +content-type: text/html + +Mumble: fumble bumble +Foolish: bar +_EOF_ + +# # # # # # # RUN AUTOGEN # # # # # # + +REQUEST_METHOD=GET +QUERY_STRING="mumble=fumble+bumble&foo=bar&template=${testname}" +CONTENT_LENGTH=`expr "${QUERY_STRING}" : ".*"` + +export CONTENT_LENGTH REQUEST_METHOD QUERY_STRING + +run_ag x1 | ${EGREP} -v '^in state' > ${testname}.test + +cmp -s ${testname}.samp ${testname}.test || \ + failure "`diff ${testname}.samp ${testname}.test`" + +# # # # # # # SECOND RUN # # # # # # + +QUERY_STRING="${QUERY_STRING}&break=true" +CONTENT_LENGTH=`expr "${QUERY_STRING}" : ".*"` + +run_ag x2 > ${testname}-2.test +fgrep 'AutoGen form processing error' ${testname}-2.test || \ + failure autogen unexpectedly succeeded + +cat > ${testname}-2.samp <<'_EOF_' +Content-type: text/plain + +AutoGen form processing error: +cgi.tpl:9:22: In expression (define foo bogus): +cgi.tpl:9:22: Unbound variable: bogus +Scheme evaluation error. AutoGen ABEND-ing in template + cgi.tpl on line 9 +Failing Guile command: = = = = = + +(define foo "") + (if (exist? "break") (set! foo bogus)) + +================================= +_EOF_ +${EGREP} -v '^in state' ${testname}-2.test > ${testname}-2.res +cmp -s ${testname}-2.samp ${testname}-2.res || { + exec >&2 + echo Your Guile library does not handle error traps correctly and causes + echo garbage to be emitted instead. Do not use this autogen as a CGI service. +} + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of html.test diff --git a/agen5/test/in.test b/agen5/test/in.test new file mode 100755 index 0000000..79bca0c --- /dev/null +++ b/agen5/test/in.test @@ -0,0 +1,94 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# ---------------------------------------------------------------------- +# in.test --- Verify that the "in?" predicate works +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . +## +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # TEMPLATE FILE # # # # # # # # # + +echo creating ${testname}.tpl +cat > ${testname}.tpl <<_EOF_ +[++ AutoGen5 template out ++][++ + +(define stack-list (stack "foo.bar")) +(string-append + (if (in? (get "baz") stack-list) "success" "FAIL") + "\n" + (if (in? (get "oops") stack-list) "FAIL" "success") +) ++][++ + +IF .true ++] +success[++ +ELSE ++] +FAILURE[++ +ENDIF ++]-[++ .true ++][++ + +IF .false ++] +FAILURE[++ +ELSE ++] +success[++ +ENDIF ++]-[++ .false ++] +_EOF_ + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +echo creating ${testname}.def +cat > ${testname}.def <<_EOF_ +AutoGen definitions ${testname}; +foo = { bar = one; }; +foo = { bar = two; }; +foo = { bar = three; }; +foo = { bar = four; }; +baz = three; +oops = oops; +true = true; +false = false; +_EOF_ + +# # # # # # # # # # EXPECTED OUTPUT FILE # # # # # # # +set -x +echo creating ${testname}.ok +# this is the output we should expect to see +cat > ${testname}.ok <<'_EOF_' +success +success +success-true +success-false +_EOF_ + +run_ag x ${testname}.def || failure autogen failed +cmp -s ${testname}.ok ${testname}.out || \ + failure "`diff ${testname}.ok ${testname}.test`" + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of in.test diff --git a/agen5/test/include.test b/agen5/test/include.test new file mode 100755 index 0000000..1bc484d --- /dev/null +++ b/agen5/test/include.test @@ -0,0 +1,79 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# include.test --- test include functionality +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . +## +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # TEMPLATE FILE # # # # # # # # # + +echo creating ${testname}.in +cat > ${testname}.in <<_EOF_ +<= AutoGen5 Template +# this is just a test +test => +<= v-name =>: <= \`echo This is an ${testname} test\` => +_EOF_ + +echo creating ${testname}.tpl +cat > ${testname}.tpl <<_EOF_ +[= AutoGen5 Template +# this is just a test + +test =] +[= Include "${testname}.in" =] +_EOF_ + +mkdir ${testname}.d ${testname}.d/good +cat > ${testname}.d/${testname}.def <<- _EOF_ + AutoGen Definitions ${testname}.tpl; + #include good/${testname}-aux.def + _EOF_ + +echo "v-name = Verify;" > ${testname}.d/good/${testname}-aux.def + +# # # # # # # # # # EXPECTED OUTPUT FILE # # # # # # # + +echo creating ${testname}.ok +# this is the output we should expect to see +cat > ${testname}.ok <<_EOF_ +Verify: This is an ${testname} test +_EOF_ + +AGCMD="-L ${testname}.d/bad -L ${testname}.d/bad/good" + +run_ag x ${AGCMD} ${testname}.d/${testname}.def || \ + failure ${AGCMD} failed +cmp -s ${testname}.test ${testname}.ok || \ + failure "unexpected output + `diff -u ${testname}.test ${testname}.ok `" +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of include.test diff --git a/agen5/test/leave.test b/agen5/test/leave.test new file mode 100755 index 0000000..bf25b23 --- /dev/null +++ b/agen5/test/leave.test @@ -0,0 +1,104 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# leave.test --- test return/next/break functionality +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . + +. ./defs + +# # # # # # # # # # TEMPLATE FILES # # # # # # # # # + +echo creating $testname.tlib +cat > $testname.tlib <<'_EOF_' +[= AutoGen5 Template test =] +[= RETURN =] +BOGUS +_EOF_ + +echo creating $testname.tpl +cat > $testname.tpl <<_EOF_ +[= AutoGen5 Template test =] +[= +INVOKE macro +=][= +DEFINE macro =][= + +FOR value =][= + IF (= 1 (for-index)) =][= BREAK =][= ENDIF =] +BOGUS +[= ENDFOR =][= + +FOR value =][= + CASE (for-index) =][= + == 4 =][= + * =][= CONTINUE =][= + ESAC =][= (for-index) =] Okay.[= + INCLUDE "$testname.tlib" =][= + + RETURN \=] + +BOGUS +[= ENDFOR =][= ENDDEF =] +_EOF_ + + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +echo creating $testname.def +cat > $testname.def <<_EOF_ +autogen definitions $testname; + +value[1] = first; +value[2] = secondary; +value[4] = tertiary; +value[6] = last; + +_EOF_ + +# this is the output we should expect to see +echo 4 Okay. > $testname.samp + +run_ag x $testname.def || \ + failure "autogen failed" +set -x +cmp -s $testname.samp $testname.test || \ + failure "`diff $testname.samp $testname.test`" + +# # # # # # # # # # TEMPLATE FILES # # # # # # # # # + +echo creating $testname.tlib +cat > $testname.tlib <<'_EOF_' +[= AutoGen5 Template test =] +[= BREAK =] +BOGUS +_EOF_ + +run_ag x -b $testname-bad $testname.def 2>/dev/null && \ + failure "processed broken template" + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of leave.test diff --git a/agen5/test/license.test b/agen5/test/license.test new file mode 100755 index 0000000..1b78940 --- /dev/null +++ b/agen5/test/license.test @@ -0,0 +1,113 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# license.test --- test license functionality +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . +## +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # TEMPLATE FILE # # # # # # # # # + +echo creating ${testname}.tpl +cat > ${testname}.tpl <<_EOF_ +[= AutoGen5 template test =] +/* +[= (license "${testname}" "${testname}" "Auto-Gen" " * " ) =] + */ +_EOF_ + +# # # # # # # # # # LICENSE FILE # # # # # # # # # + +echo creating ${testname}.lic +cat > ${testname}.lic <<'_EOF_' +This is a bogus license granted by %2$s for %1$s. +Use it in good health +_EOF_ + +# # # # # # # # # # EXTEND FILES TO PAGESIZE # # # # # # # # # + +cat > ${testname}-extend.c <<- _EOF_ + #define HAVE_CONFIG_H 1 + #include "config.h" + #include "compat/compat.h" + + int main( int argc, char** argv ) { + char z_tail[] = "=]\n */\n"; + long offset = 0L - (sizeof(z_tail) - 1); + struct stat sb; + char* file; + size_t sz; + FILE* fp; + + file = *++argv; + fp = fopen(file, "a"); + if (fp == NULL) return 1; + if (stat(file, &sb) != 0) return 1; + sz = 0x2000 - (sb.st_size & 0x1FFFUL); + while (sz > 0) { putc( '\n', fp ); sz--; } + fclose(fp); + + file = *++argv; + fp = fopen( file, "r+" ); + if (fp == NULL) return 1; + if (stat(file, &sb) != 0) return 1; + fseek(fp, offset, SEEK_END); + sz = 0x2000 - (sb.st_size & 0x1FFFUL); + while (sz > 0) { putc( '\n', fp ); sz--; } + fputs(z_tail, fp); + fclose(fp); + + return 0; } + _EOF_ + +Csrc=${testname}-extend +compile + +./${testname}-extend ${testname}.lic ${testname}.tpl || \ + failure "Could not extend license/template files to 8KB" +ls -l ${testname}.??? + +# # # # # # # # # # EXPECTED OUTPUT FILE # # # # # # # +set -x +echo creating ${testname}.out +# this is the output we should expect to see +cat > ${testname}.out <<_EOF_ +/* + * This is a bogus license granted by Auto-Gen for ${testname}. + * Use it in good health + */ +_EOF_ + +run_ag x -b ${testname} --no-def -T ${testname}.tpl || \ + failure autogen failed +cmp -s ${testname}.test ${testname}.out || failure unexpected output + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of license.test diff --git a/agen5/test/line.test b/agen5/test/line.test new file mode 100755 index 0000000..53f4f84 --- /dev/null +++ b/agen5/test/line.test @@ -0,0 +1,67 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# line.test --- test (tpl-file-line) functionality +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . +## +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # TEMPLATE FILE # # # # # # # # # + +echo creating ${testname}.tpl +${SED} 's/^ *[0-9]*: //' > ${testname}.tpl << _EOTPL_ + 1: [= AutoGen5 Template txt =] + 2: ${testname} Test + 3: [= (define ix 0) (define ct 63) =] + 4: [=WHILE (< ix ct) \=] + 5: [= (set! ix (+ ix 1)) + 6: (sprintf "test %2d of %2d: %s\n" ix ct (tpl-file-line "%2\$d")) + 7: \=] + 8: [=ENDWHILE \=] + 9: End ${testname} Test +_EOTPL_ + +# # # # # # # # # # EXPECTED OUTPUT FILE # # # # # # # +set -x +echo creating ${testname}.out +# this is the output we should expect to see +cat > ${testname}.out <<- \_EOF_ + line Test + + End line Test + _EOF_ + +run_ag x --base=${testname} --no-def --override=${testname}.tpl || \ + failure autogen failed +${EGREP} -v ' of 63: 5$' ${testname}.txt > ${testname}.test + +cmp -s ${testname}.test ${testname}.out || failure unexpected output + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of line.test diff --git a/agen5/test/loop.test b/agen5/test/loop.test new file mode 100755 index 0000000..6649db9 --- /dev/null +++ b/agen5/test/loop.test @@ -0,0 +1,77 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# loop.test --- test FOR loop +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . +## +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # TEMPLATE FILE # # # # # # # # # + +echo creating ${testname}.tpl +limit=32 +cat > ${testname}.tpl <<- _EOTPL_ + [= AutoGen5 Template test =] + ${testname} Test + [= (define ix 0) (define ct ${limit}) =][= + + WHILE (< ix ct) =][= + (set! ix (+ ix 1)) =][= + (sprintf "test %2d of %2d: %s\n" + ix ct (tpl-file-line "%2\$d")) =][= + ENDWHILE + + =]End ${testname} Test + _EOTPL_ + +# # # # # # # # # # EXPECTED OUTPUT FILE # # # # # # # +set -x +echo creating ${testname}.base + +# this is the output we should expect to see +# +exec 3> ${testname}.base +echo "${testname} Test" >&3 +ix=1 +while test $ix -le $limit +do printf "test %2d of ${limit}: 7\n" $ix + ix=`expr $ix + 1` +done >&3 +echo "End ${testname} Test" >&3 +exec 3>&- + +run_ag x --base=${testname} --no-def --override=${testname}.tpl || \ + failure autogen failed + +cmp -s ${testname}.base ${testname}.test || \ + failure "unexpected output: `diff ${testname}.base ${testname}.test`" + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of loop.test diff --git a/agen5/test/make.test b/agen5/test/make.test new file mode 100755 index 0000000..c1572b8 --- /dev/null +++ b/agen5/test/make.test @@ -0,0 +1,90 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# make.test --- test makefile script manufacture +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . +## +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # TEMPLATE FILE # # # # # # # # # + +echo creating ${testname}.tpl +cat > ${testname}.tpl <<'_EOF_' +[= AutoGen5 Template + +=] +== This source: +[= + + (out-push-new) + +=] +foo=`pwd` && ls -l $foo +bar=$foo continue=command \ +make macros: $(MAKE) $* $@ $< $% $? +shell vars: ${MAKE} $# $F ${?} ${*} $$ +[= +(define txt (out-pop #t)) +(string-append txt "\n== converts to:\n\n" (makefile-script txt)) +=] +_EOF_ + +# # # # # # # SAMPLE OUTPUT FILE # # # # # # + +echo creating ${testname}.out in `pwd` +# this is the output we should expect to see +cat > ${testname}.samp <<'_EOF_' +== This source: + +foo=`pwd` && ls -l $foo +bar=$foo continue=command \ +make macros: $(MAKE) $* $@ $< $% $? +shell vars: ${MAKE} $# $F ${?} ${*} $$ + +== converts to: + + foo=`pwd` && ls -l $$foo ; \ + bar=$$foo continue=command \ + make macros: $(MAKE) $* $@ $< $% $? ; \ + shell vars: $${MAKE} $$# $$F $${?} $${*} $$$$ +_EOF_ + +# # # # # # # RUN AUTOGEN # # # # # # + +run_ag x -T ${testname}.tpl --no-def > ${testname}.test || \ + failure autogen failed + +# # # # # # # TEST RESULTS # # # # # # + +cmp -s ${testname}.samp ${testname}.test || \ + failure "`diff ${testname}.samp ${testname}.test`" + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of make.test diff --git a/agen5/test/match.test b/agen5/test/match.test new file mode 100755 index 0000000..f10f1b8 --- /dev/null +++ b/agen5/test/match.test @@ -0,0 +1,71 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# match.test --- test the "match-value?" scheme +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . +## +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # TEMPLATE FILE # # # # # # # # # + +echo creating ${testname}.tpl +cat > ${testname}.tpl <<'_EOF_' +[= AutoGen5 Template test =] + ==* "sec" [= IF (match-value? ==* "foo.valu" "sec" ) + =]YES[=ELSE=]FAIL[=ENDIF=] + ==* "SEC" [= IF (match-value? ==* "foo.valu" "SEC" ) + =]FAIL[=ELSE=]YES[=ENDIF=] + *=* "rST" [= IF (match-value? *=* "foo.valu" "rST" ) + =]YES[=ELSE=]FAIL[=ENDIF=] + *==* "rST" [= IF (match-value? *==* "foo.valu" "rST" ) + =]FAIL[=ELSE=]YES[=ENDIF=] +_EOF_ + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +echo creating ${testname}.def +cat > ${testname}.def <<_EOF_ +autogen definitions ${testname}.tpl; + +foo = { valu = first.0; valu = primary.0; }; +foo = { valu = first.1; valu = secondary.1; }; +foo = { valu = first.2; }; +foo = { valu = first.3; valu = tertiery.3; }; +_EOF_ + +# # # # # # # # # # EXPECTED OUTPUT FILE # # # # # # # + +run_ag x ${testname}.def || \ + failure could not generate output +${EGREP} FAIL ${testname}.test && \ + failure some ${testname} tests failed + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of match.test diff --git a/agen5/test/opts.test b/agen5/test/opts.test new file mode 100755 index 0000000..59f5679 --- /dev/null +++ b/agen5/test/opts.test @@ -0,0 +1,90 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# ---------------------------------------------------------------------- +# opts.test --- Verify the handling of options +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . + +. ./defs + +# Fetch the options files +# +unstamp() +{ + # The "zDetail" and zCopyrightNotice text gets formatted with "fmt -w 75". + # The different "fmt" implementations behave differently. + # + ${SED} -e "${sed_omit_license}" \ + -e '/ extracted from.* line [1-9]/d' \ + -e '/static char const zDetail/,/";$/d' \ + -e '/static char const zCopyright/,/";$/d' \ + -e '/static char const zLicenseDescrip/,/";$/d' \ + -e '/ "autogen is free software: /,/www\.gnu\.org\/licenses/d' \ + $1 > $2 || + failure Cannot remove stamps from $1 +} + +workdir=`pwd` +rm -f ../VERSION ./opts.* || : + +cd ${top_srcdir}/agen5 +unstamp opts.c ${workdir}/opts.c.base +unstamp opts.h ${workdir}/opts.h.base +cp opts.def ${workdir}/. +cp -f ${top_srcdir}/VERSION ${workdir}/.. + +cd ${workdir} +set -x +ls -l * ../VERSION > $testname.log + +echo Checking for "'define DEBUG'" options +if ${GREP} 'define DEBUG' ${srcdir}/../opts.h +then + AGCMD="-DDEBUG=1" +else + AGCMD="" +fi + +run_ag x ${AGCMD} opts.def || { + rm -f ../VERSION + failure ${AGCMD} opts.def +} + +rm -f ../VERSION + +unstamp opts.c opts.c.res +echo diff opts.c.base opts.c.res +diff opts.c.base opts.c.res || \ + failure "`diff -c opts.c.base opts.c.res`" + +unstamp opts.h opts.h.res +echo diff opts.h.base opts.h.res +diff opts.h.base opts.h.res || \ + failure "`diff -c opts.h.base opts.h.res`" + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of opts.test diff --git a/agen5/test/output.test b/agen5/test/output.test new file mode 100755 index 0000000..1e0b9c9 --- /dev/null +++ b/agen5/test/output.test @@ -0,0 +1,119 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# include.test --- test include functionality +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . +## +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # TEMPLATE FILE # # # # # # # # # + +echo creating $testname.tpl +cat > $testname.tpl <<'EOF' +<= AutoGen5 template test => +<=(out-push-new) + +=>This is sample output +<= `echo echoed text.` =><= +(out-suspend "here") +(out-push-new) +=>This text is from another diversion. +<= +(out-suspend "there") +=>This is the first output text. +<=(out-resume "here") +=> +Final text<= + +(define text (out-pop #t)) =><= + +DEFINE wrapper + +=>BEGIN +<=(out-resume "there") (out-pop #t) +=><= +(. text)=> +END<= + +ENDDEF wrapper =><= + +wrapper => +Done. +EOF + +# # # # # # # SAMPLE OUTPUT FILE # # # # # # + +echo creating $testname.out in `pwd` +# this is the output we should expect to see +cat > $testname.samp <<'EOF' +This is the first output text. +BEGIN +This text is from another diversion. +This is sample output +echoed text. +Final text +END +Done. +EOF + +# # # # # # # RUN AUTOGEN # # # # # # + +run_ag nodef -b $testname -T $testname.tpl --no-def || \ + failure autogen failed + +# # # # # # # TEST RESULTS # # # # # # + +cmp -s $testname.samp $testname.test || \ + failure "`diff $testname.samp $testname.test`" + +# # # # # # # EMPTY DEFINITIONS FILE # # # # # # + +cat > $testname.def < +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . +## +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # TEMPLATE FILE # # # # # # # # # + +echo creating ${testname}.tpl +cat > ${testname}.tpl <<- \_EOF_ + [= AutoGen5 Template + + (define f-name "") + + h=(begin + (set! f-name (getenv "incdir")) + (if (not (string? f-name)) (set! f-name ".")) + (set! f-name (string-append f-name "/%s-hdr.%s")) + (shellf + "d=`dirname %s` + test -d ${d} || mkdir -p $d || die cannot mkdir $d" + f-name) + f-name + ) + + c=(begin + (set! f-name (getenv "srcdir")) + (if (not (string? f-name)) (set! f-name ".")) + (set! f-name (string-append f-name "/%s-body.%s")) + (shellf + "d=`dirname %s` + test -d ${d} || mkdir -p $d || die cannot mkdir $d" + f-name) + f-name + ) + + # end of pseudo + =] + [= + + (sprintf "two file create %s: " (suffix)) =][= + + CASE (suffix) =][= + + == h =]HEADER FILE[= + == c =]BODY 4 FILE[= + * =][= (error "woops") =][= + + ESAC =] + _EOF_ + +# # # # # # # # # # RUN TESTS # # # # # # # + +incdir=${testname}-inc +srcdir=${testname}-src + +export incdir srcdir + +run_ag x --no-def -T${testname}.tpl -b${testname} || \ + failure autogen --no-def -T${testname}.tpl -b${testname} + +f=${incdir}/${testname}-hdr.h +test -f ${f} || \ + failure missing file: ${f} +${FGREP} 'two file create h: HEADER FILE' ${f} || failure bad contents for $f + +f=${srcdir}/${testname}-body.c +test -f ${f} || \ + failure missing file: ${f} +${FGREP} 'two file create c: BODY 4 FILE' ${f} || failure bad contents for $f + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of pseudo.test diff --git a/agen5/test/reorder.test b/agen5/test/reorder.test new file mode 100755 index 0000000..ddb6e3c --- /dev/null +++ b/agen5/test/reorder.test @@ -0,0 +1,106 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# reorder.test --- test reorder functionality +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . +## +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # TEMPLATE FILE # # # # # # # # # + +echo creating $testname.tpl +cat > $testname.tpl <<'_EOF_' +<= AutoGen5 template test => +From zero:<= + +FOR a (for-from 0) (for-by 1) (for-sep ",")=> +<=(sprintf "%5d: " (for-index))=><= + ?% elt %s absent =><= + IF (first-for?) => first loop<= ENDIF =><= + IF (last-for? ) => last loop<= ENDIF =><= +ENDFOR => + +From start by two:<= + +FOR a (for-by 2) (for-sep ",")=> +<=(sprintf "%5d: " (for-index)) =><= + ?% elt %s absent =><= + IF (first-for?) => first loop<= ENDIF =><= + IF (last-for? ) => last loop<= ENDIF =><= +ENDFOR => +_EOF_ + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +echo creating $testname.def +cat > $testname.def <<_EOF_ +autogen definitions $testname; +a[ 3] = { elt = three; }; +a[ 5] = { elt = five; }; +a[12] = { elt = twelve; }; +a[ 8] = { elt = eight; }; +a[ 1] = { elt = one; }; +a[ 2] = { elt = two; }; +_EOF_ + +# # # # # # # # # # EXPECTED OUTPUT FILE # # # # # # # + +echo creating $testname.out +# this is the output we should expect to see +cat > $testname.out <<_EOF_ +From zero: + 0: absent first loop, + 1: one, + 2: two, + 3: three, + 4: absent, + 5: five, + 6: absent, + 7: absent, + 8: eight, + 9: absent, + 10: absent, + 11: absent, + 12: twelve last loop + +From start by two: + 1: one first loop, + 3: three, + 5: five, + 7: absent, + 9: absent, + 11: absent last loop +_EOF_ + +run_ag x $testname.def || failure autogen failed +cmp -s $testname.test $testname.out || failure unexpected output + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of reorder.test diff --git a/agen5/test/return.test b/agen5/test/return.test new file mode 100755 index 0000000..909de98 --- /dev/null +++ b/agen5/test/return.test @@ -0,0 +1,72 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# for.test --- test functionality of `for' function +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . +## +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # TEMPLATE FILE # # # # # # # # # + +echo creating $testname.tpl +cat > $testname.tpl <<_EOF_ +[= AutoGen5 template test =] +[= INVOKE my-mac \=] +[= (if (exist? "list") (emit "ok")) =] +Done. +[= DEFINE my-mac \=] +[= FOR list \=] +[= IF (exist? "leave") \=] +[= RETURN \=] +[= ENDIF \=] +[= ENDFOR list \=] +[= ENDDEF my-mac \=] +_EOF_ + + +# Create the files we need in the test environment +cat > $testname.def <<_EOF_ +AutoGen definitions $testname; +list = { elt = one; }; +list = { leave; }; +_EOF_ + +# this is the output we should expect to see +cat > $testname.sample <<_EOF_ +ok +Done. +_EOF_ + +run_ag x $testname.def || failure AutoGen failed +cmp -s $testname.test $testname.sample || \ + failure "`diff -c $testname.test $testname.sample`" + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of for.test diff --git a/agen5/test/shell.test b/agen5/test/shell.test new file mode 100755 index 0000000..b750469 --- /dev/null +++ b/agen5/test/shell.test @@ -0,0 +1,164 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# shell.test --- test functionality of switching shells +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . +## +# +# The test will verify that a real shell processes the declarations +# and our weirdo shell handles the template. +# +# ---------------------------------------------------------------------- + +exec 9>&2 + +. ./defs + +${FGREP} '#define SHELL_ENABLED ' ${top_builddir}/config.h > /dev/null 2>&1 +test $? -eq 0 || exit 0 + +# # # # # # # # # # TEMPLATE FILE # # # # # # # # # + +cat > ${testname}.c <<- \_EOF_ + #include + #include + #include + #define NUL '\0' + char buf[ 4096 ]; + int + main( int argc, char** argv ) + { + char *pz; + for (;;) { + pz = fgets(buf, sizeof(buf),stdin); + if (pz == NULL) + return 1; /* must get something every time */ + while (isspace(*pz)) pz++; + if (*pz != NUL) break; /* ignore initial blank lines */ + } + + for (;;) { + if (*pz == '#') goto next_line; + if (strncmp( pz, "cd ", 3 ) == 0) goto next_line; + if ((strncmp( pz, "echo", 4 ) == 0) && isspace( pz[4] )) { + pz += 5; + while (isspace(*pz)) pz++; /* suppress the 'echo' */ + } + if (*pz == '\0') pz--; /* always force a newline */ + fputs( pz, stdout ); + fflush( stdout ); + + next_line: + pz = fgets(buf, sizeof(buf),stdin); + if (pz == NULL) + break; + while (isspace(*pz)) pz++; + } + return 0; + } + _EOF_ + +compile + +# The backslashes are stripped by the here-doc processing +# +echo creating ${testname}.tpl +cat > ${testname}.tpl <<- _EOF_ + <= AutoGen5 template test + (setenv "SHELL" "./${testname}") => + <=\` echo SHELL=\$SHELL \`=> + Some <=dummy=> text + <= FOR foo => + foo[<=(for-index)=>] = <=foo=> + raw-shell-str: <=(raw-shell-str (get "foo"))=> + shell-str: <=(shell-str (get "foo"))=> + sub-shell-str: <=(sub-shell-str (get "foo"))=> + <= ENDFOR => + <=\` : This is a final test \`=> + _EOF_ + +echo creating ${testname}.def +cat >${testname}.def <<- \_EOF_ + AutoGen Definitions shell.tpl; + + foo = "''foo'' 'foo' \"foo\" `foo` $foo"; + foo = '\\\'bar\\\' \\"bar\\" \`bar\` \$bar'; + foo = '\\\\\'BAZ\\\\\' \\\\"BAZ\\\\" \\\`BAZ\\\` \\\$BAZ'; + dummy = `echo "mumble"`; /* processed with regular shell */ + _EOF_ + +# this is the output we should expect to see +cat > ${testname}.sample <<- \_EOF_ + SHELL=$SHELL + Some "mumble" text + + foo[0] = ''foo'' 'foo' "foo" `foo` $foo + raw-shell-str: \'\''foo'\'\'' '\''foo'\'' "foo" `foo` $foo' + shell-str: "''foo'' 'foo' \"foo\" `foo` $foo" + sub-shell-str: `''foo'' 'foo' "foo" \`foo\` $foo` + + foo[1] = \'bar\' \"bar\" \`bar\` \$bar + raw-shell-str: '\'\''bar\'\'' \"bar\" \`bar\` \$bar' + shell-str: "\\'bar\\' \\\"bar\\\" \`bar\` \$bar" + sub-shell-str: `\\'bar\\' \"bar\" \\\`bar\\\` \$bar` + + foo[2] = \\'BAZ\\' \\"BAZ\\" \\`BAZ\\` \\$BAZ + raw-shell-str: '\\'\''BAZ\\'\'' \\"BAZ\\" \\`BAZ\\` \\$BAZ' + shell-str: "\\\\'BAZ\\\\' \\\\\"BAZ\\\\\" \\\`BAZ\\\` \\\$BAZ" + sub-shell-str: `\\\\'BAZ\\\\' \\\"BAZ\\\" \\\\\`BAZ\\\\\` \\\$BAZ` + + : This is a final test + _EOF_ + +run_ag x --shell=$PWD/shell ${testname}.def || \ + failure "autogen ${testname}.def" + +${GREP} -v '^AGexe=' ${testname}.test > ${testname}.XX +mv -f ${testname}.XX ${testname}.test +if cmp -s ${testname}.test ${testname}.sample +then cleanup + exit 0 +fi + +if ${FGREP} 'SHELL=' ${testname}.test > /dev/null 2>&1 +then + if ${FGREP} 'SHELL=$SHELL' ${testname}.test > /dev/null 2>&1 + then : ; else + cat >&9 <<- _EOF_ + The ${testname}.test output file does not start with "SHELL=\$SHELL" + This is because you have a Guile library that cannot modify + the environment. This is a known breakage on some platforms + (viz., BSD derivatives). Sorry. + _EOF_ + ${FGREP} 'SHELL=' ${testname}.test >&9 + cleanup + exit 0 + fi +fi + +failure "`set +x;diff -c ${testname}.sample ${testname}.test`" + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of shell.test diff --git a/agen5/test/snarf.test b/agen5/test/snarf.test new file mode 100755 index 0000000..30dea07 --- /dev/null +++ b/agen5/test/snarf.test @@ -0,0 +1,278 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# snarf.test --- test the extraction of scm-type definitions +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . +## +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # SOURCE FILE # # # # # # # # # + +echo creating ${testname}.c +cat > ${testname}.c <<_EOF_ +#include "${testname}.h" +#include "${testname}.ini" +/*=gfunc test_to_example_x + * + * exparg: in, test input arg desc, optional, list + * +=*/ +SCM +test_scm_test_to_example_x(SCM in) +{ + return in; +} + +/*=symbol mumble_check + * + * init_val: SCM_BOOL_T +=*/ +/*=symbol bumble_it + * + * const_val: 100L + * global: +=*/ +/*=syntax guile_syntax_ele + * + * type: scm_makacro + * cfn: scm_m_undefine +=*/ +_EOF_ + +# # # # # # # # # # PROCESS SOURCE FILE # # # # # # # # # + +f=`echo ${AGexe} | ${SED} 's/ .*//'` + +agsrc=`cd $top_srcdir/agen5 && pwd` +tplsrc=`cd $top_srcdir/autoopts/tpl && pwd` + +cat > ${testname}.cfg <<- _EOF_ + subblock exparg=arg_name,arg_desc,arg_optional,arg_list + template snarf.tpl + srcfile + assign group = ${testname}_grp + assign init = Chosen_init + base-name ${testname} + agarg -L$agsrc + agarg -L$tplsrc + input ${testname}.c + autogen ${f} + _EOF_ +unset DEBUG_ENABLED + +echo "getdefs load=${testname}.cfg ${testname}.c" +${VERBOSE} && { + AUTOGEN_TRACE=everything + AUTOGEN_TRACE_OUT=">>${testname}-ag-log.txt" + export AUTOGEN_TRACE AUTOGEN_TRACE_OUT +} +${GDexe} load=${testname}.cfg || \ + failure getdefs load=${testname}.cfg + +${SED} -e "${sed_omit_license}" -e '/^#undef *NEW_PROC *$/,$d' \ + ${testname}.ini > ${testname}.ini.tst1 + +${SED} "${sed_omit_license}" ${testname}.h > ${testname}.h.tst1 + +# # # # # # # # # # EXPECTED INI FILE # # # # # # # # # + +echo creating ${testname}.ini.OK1 +cat > ${testname}.ini.OK1 <<'_EOF_' +/** \file snarf.ini + * + * Guile Initializations - snarf_grp Global Variables + */ +#include "snarf.h" +typedef SCM (*scm_callback_t)(void); +void Chosen_init(void); + +extern SCM snarf_grp_scm_sym_bumble_it = SCM_BOOL_F; +static SCM snarf_grp_scm_sym_mumble_check = SCM_BOOL_F; +#if GUILE_VERSION >= 108000 +#define NEW_PROC(_As, _Ar, _Ao, _Ax, _An) \ + scm_c_define_gsubr((char *)(_As), \ + _Ar, _Ao, _Ax, (scm_callback_t)VOIDP(ag_scm_ ## _An)) +#else +#define NEW_PROC(_As, _Ar, _Ao, _Ax, _An) \ + gh_new_procedure((char *)(_As), (scm_callback_t)VOIDP(ag_scm_ ## _An), \ + _Ar, _Ao, _Ax) +#endif + +/** + * snarf_grp Initialization procedure. + */ +void +Chosen_init(void) +{ +static char const g_nm[55] = +/* 0 */ "test->example!\0" +/* 15 */ "guile-syntax-ele\0" +/* 32 */ "bumble-it\0" +/* 42 */ "mumble-check"; + + NEW_PROC(g_nm + 0, 0, 0, 1, test_to_example_x); + scm_make_synt(g_nm+15, scm_makacro, scm_m_undefine); + snarf_grp_scm_sym_bumble_it = scm_permanent_object(SCM_CAR (scm_intern0 (g_nm+32))); + snarf_grp_scm_sym_mumble_check = scm_permanent_object(SCM_CAR (scm_intern0 (g_nm+42))); +} +_EOF_ + +cmp ${testname}.ini.tst1 ${testname}.ini.OK1 || \ + failure "`diff ${testname}.ini.tst1 ${testname}.ini.OK1`" + +# # # # # # # # # # EXPECTED HEADER FILE # # # # # # # + +echo creating ${testname}.h.OK +cat > ${testname}.h.OK <<_EOF_ +/** \file snarf.h + * Guile Implementation Routines - for the snarf_grp group + */ +#ifndef GUILE_PROCS_SNARF_H_GUARD +#define GUILE_PROCS_SNARF_H_GUARD 1 + +#if GUILE_VERSION >= 108000 +# include +#else +# include +#endif + +typedef enum { + GH_TYPE_UNDEFINED = 0, + GH_TYPE_BOOLEAN, + GH_TYPE_SYMBOL, + GH_TYPE_CHAR, + GH_TYPE_VECTOR, + GH_TYPE_PAIR, + GH_TYPE_NUMBER, + GH_TYPE_STRING, + GH_TYPE_PROCEDURE, + GH_TYPE_LIST, + GH_TYPE_INEXACT, + GH_TYPE_EXACT +} teGuileType; + +extern SCM snarf_grp_scm_test_to_example_x(SCM); +extern SCM snarf_grp_scm_sym_bumble_it; + +#endif /* GUILE_PROCS_SNARF_H_GUARD */ +_EOF_ + +cmp ${testname}.h.* || \ + failure "`diff ${testname}.h.*`" + +# # # # # # # # # # PROCESS SOURCE FILE AGAIN # # # # # # # # # + +cp ${testname}.cfg ${testname}.cfg1 + +echo 'assign debug-enabled = true' >> ${testname}.cfg +DEBUG_ENABLED=true +export DEBUG_ENABLED + +${GDexe} load=${testname}.cfg || \ + failure getdefs load=${testname}.cfg + +${SED} -e "${sed_omit_license}" \ + -e '/^#undef *NEW_PROC$/,$d' \ + ${testname}.ini > ${testname}.ini.tst2 + +${SED} "${sed_omit_license}" ${testname}.h > ${testname}.h.tst2 + +# # # # # # # # # # EXPECTED INI FILE # # # # # # # # # + +echo creating ${testname}.ini.OK2 +cat > ${testname}.ini.OK2 <<'_EOF_' +/** \file snarf.ini + * + * Guile Initializations - snarf_grp Global Variables + */ +#include "snarf.h" +typedef SCM (*scm_callback_t)(void); +void Chosen_init(void); + +extern SCM snarf_grp_scm_sym_bumble_it = SCM_BOOL_F; +static SCM snarf_grp_scm_sym_mumble_check = SCM_BOOL_F; +#ifdef DEBUG_ENABLED +static SCM +agrelay_scm_test_to_example_x(SCM scm0) +{ + if (OPT_VALUE_TRACE >= TRACE_EVERYTHING) { + static char const proc_z[] = + "Called ag_scm_test_to_example_x()\n"; + fwrite(proc_z, sizeof(proc_z) - 1, 1, trace_fp); + } + return ag_scm_test_to_example_x(scm0); +} + +#if GUILE_VERSION >= 108000 +#define NEW_PROC(_As, _Ar, _Ao, _Ax, _An) \ + scm_c_define_gsubr((char *)(_As), \ + _Ar, _Ao, _Ax, (scm_callback_t)VOIDP(agrelay_scm_ ## _An)) +#else +#define NEW_PROC(_As, _Ar, _Ao, _Ax, _An) \ + gh_new_procedure((char *)(_As), (scm_callback_t)VOIDP(agrelay_scm_ ## _An), \ + _Ar, _Ao, _Ax) +#endif + +#else /* DEBUG_ENABLED *not* */ +#if GUILE_VERSION >= 108000 +#define NEW_PROC(_As, _Ar, _Ao, _Ax, _An) \ + scm_c_define_gsubr((char *)(_As), \ + _Ar, _Ao, _Ax, (scm_callback_t)VOIDP(ag_scm_ ## _An)) +#else +#define NEW_PROC(_As, _Ar, _Ao, _Ax, _An) \ + gh_new_procedure((char *)(_As), (scm_callback_t)VOIDP(ag_scm_ ## _An), \ + _Ar, _Ao, _Ax) +#endif +#endif /* DEBUG_ENABLED */ + +/** + * snarf_grp Initialization procedure. + */ +void +Chosen_init(void) +{ +static char const g_nm[55] = +/* 0 */ "test->example!\0" +/* 15 */ "guile-syntax-ele\0" +/* 32 */ "bumble-it\0" +/* 42 */ "mumble-check"; + + NEW_PROC(g_nm + 0, 0, 0, 1, test_to_example_x); + scm_make_synt(g_nm+15, scm_makacro, scm_m_undefine); + snarf_grp_scm_sym_bumble_it = scm_permanent_object(SCM_CAR (scm_intern0 (g_nm+32))); + snarf_grp_scm_sym_mumble_check = scm_permanent_object(SCM_CAR (scm_intern0 (g_nm+42))); +} +_EOF_ + +cmp ${testname}.ini.tst2 ${testname}.ini.OK2 || \ + failure "`diff ${testname}.ini.tst2 ${testname}.ini.OK2`" + +cleanup + +## +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of snarf.test diff --git a/agen5/test/stack.test b/agen5/test/stack.test new file mode 100755 index 0000000..299f349 --- /dev/null +++ b/agen5/test/stack.test @@ -0,0 +1,92 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# ---------------------------------------------------------------------- +# stack.test --- test stack and join functionality +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . +## +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # TEMPLATE FILE # # # # # # # # # + +echo creating ${testname}.tpl +cat > ${testname}.tpl <<_EOF_ +[= AutoGen5 template test =] +[= + + (join ", " (stack "foo.bar.baz")) + +=] +[= + + (join ",\n" "one" "two" "three" "four" ) + +=] +[= + + (join ", " "foo" (stack "foo.bar.baz") "bar" "baz") + +=] +[= (string-substitute (join "\n" (stack "foo.bar.baz")) + '("umb" "le") '("_UMB_" "<=") ) =] +_EOF_ + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +echo creating ${testname}.def +cat > ${testname}.def <<_EOF_ +AutoGen definitions ${testname}; + +foo = { bar = { baz = fumble; }; }; +foo = { bar = { baz = mumble; }; }; +foo = { bar = { baz = grumble; }; }; +_EOF_ + +# # # # # # # # # # EXPECTED OUTPUT FILE # # # # # # # +set -x +echo creating ${testname}.out +# this is the output we should expect to see +cat > ${testname}.out <<'_EOF_' +fumble, mumble, grumble +one, +two, +three, +four +foo, fumble, mumble, grumble, bar, baz +f_UMB_<= +m_UMB_<= +gr_UMB_<= +_EOF_ + +run_ag x ${testname}.def || failure autogen failed +cmp -s ${testname}.test ${testname}.out || \ + failure "`diff ${testname}.*t`" + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of stack.test diff --git a/agen5/test/str2m.test b/agen5/test/str2m.test new file mode 100755 index 0000000..23bdf63 --- /dev/null +++ b/agen5/test/str2m.test @@ -0,0 +1,415 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# str2m.test --- test str2enum and str2mask functionality +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . +## +# +# ---------------------------------------------------------------------- + +. ./defs +gperf=`command -v gperf` +test -x "$gperf" || { + echo "$0 - cannot run without gperf installed" >&2 + exit 0 +} + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +echo creating $testname.def +cat > $testname.def <<'_EOF_' +AutoGen Definitions str2enum; + +cmd[0] = one; +cmd[3] = three; +cmd[7] = seven; +cmd[11] = eleven; +cmd[19] = ninteen; + +type = kwd; +mask = { m-name = one-seven; m-bit = one, seven; }; +mask = { m-name = not-one-seven; m-bit = three, eleven, ninteen; m-invert; }; +_EOF_ + +cmd_list=`${SED} -n '/^cmd/{s/.*= *//;s/;//;p;}' $testname.def` +cmd_list=`echo $cmd_list` +# # # # # # # # # # EXPECTED OUTPUT FILES # # # # # # # + +echo creating $testname-h.base +# this is the output we should expect to see +cat > $testname-h.base <<- _EOF_ + typedef enum { + STR2M_INVALID_KWD = 0, + STR2M_KWD_ONE = 1, + STR2M_KWD_THREE = 4, + STR2M_KWD_SEVEN = 8, + STR2M_KWD_ELEVEN = 12, + STR2M_KWD_NINTEEN = 20, + STR2M_COUNT_KWD + } str2m_enum_t; + + extern str2m_enum_t + find_str2m_kwd(char const * str, size_t len); + + extern char const * + str2m_name(str2m_enum_t id); + + #endif /* STR2ENUM_STR2M_H_GUARD */ + _EOF_ + +cat > $testname-c.base <<- _EOF_ + * Convert a command (keyword) to a str2m_enum_t enumeration value. + * + * @param[in] str a string that should start with a known key word. + * @param[in] len the provided length of the keyword at \a str. + * @returns the enumeration value. + * If not found, that value is STR2M_INVALID_KWD. + */ + str2m_enum_t + find_str2m_kwd(char const * str, size_t len) + { + str2m_map_t const * map; + + map = find_str2m_name(str, (unsigned int)len); + return (map == NULL) ? STR2M_INVALID_KWD : map->str2m_id; + } + + /** + * Convert an str2m_enum_t value into a string. + * + * @param[in] id the enumeration value + * @returns the associated string, or "* UNDEFINED *" if \a id + * is out of range. + */ + char const * + str2m_name(str2m_enum_t id) + { + static char const undef[] = "* UNDEFINED *"; + static char const * const nm_table[] = { + [STR2M_KWD_ELEVEN ] = "eleven", + [STR2M_KWD_NINTEEN ] = "ninteen", + [STR2M_KWD_ONE ] = "one", + [STR2M_KWD_SEVEN ] = "seven", + [STR2M_KWD_THREE ] = "three" }; + char const * res = undef; + if (id < STR2M_COUNT_KWD) { + res = nm_table[id]; + if (res == NULL) + res = undef; + } + return res; + } + + /* end of str2m.c */ + _EOF_ + +# # # # # # # # # # RUN THE TEST # # # # # # # + +AGCMD="-L ${srcdir}/.. -L ${top_srcdir}/autoopts/tpl" +echo run_ag x ${AGCMD} $testname.def +run_ag x ${AGCMD} $testname.def || \ + failure ${AGCMD} failed + +get_h_text="/^typedef enum/,/#endif.*GUARD/p" +${SED} -n "${get_h_text}" $testname.h > $testname-h.res +fpair="$testname-h.base $testname-h.res" +cmp -s $fpair || \ + failure "$testname $fpair failed`echo + diff $fpair`" +get_c_text="/ Convert .*to a ${testname}_enum_t/,/end of $testname.c/p" +${SED} -n "${get_c_text}" $testname.c > $testname-c.res + +fpair="$testname-c.base $testname-c.res" +cmp -s $fpair || \ + failure "$testname $fpair failed`echo + diff $fpair`" + +# # # # # # # # # # OUTPUT FILES PART 2 # # # # # # # + +echo creating $testname-h2.base +TNAME=`echo $testname | tr '[a-z]' '[A-Z]'` +rep_name="s/${testname}/${testname}_2/g;s/${TNAME}/${TNAME}_2/g" +cat > $testname-h2.base <<- _EOF_ + #ifndef STR2ENUM_STR2M_2_H_GUARD + #define STR2ENUM_STR2M_2_H_GUARD 1 + #include + #include + + /** integral type for holding str2m_2 masks */ + typedef uint32_t str2m_2_mask_t; + + /** bits defined for str2m_2_mask_t */ + #define STR2M_2_KWD_ONE 0x00001U + #define STR2M_2_KWD_THREE 0x00008U + #define STR2M_2_KWD_SEVEN 0x00080U + #define STR2M_2_KWD_ELEVEN 0x00800U + #define STR2M_2_KWD_NINTEEN 0x80000U + + /** bits in ONE_SEVEN mask: + * one seven */ + #define STR2M_2_KWD_ONE_SEVEN_MASK 0x00081U + + /** bits omitted from NOT_ONE_SEVEN mask: + * three eleven ninteen */ + #define STR2M_2_KWD_NOT_ONE_SEVEN_MASK 0x00081U + + /** all bits in str2m_2_mask_t masks */ + #define STR2M_2_KWD_MASK_ALL 0x80889U + + /** no bits in str2m_2_mask_t */ + #define STR2M_2_KWD_EMPTY 0x00000U + + /** buffer size needed to hold all bit names for str2m_2_mask_t masks */ + #define MAX_STR2M_2_NAME_SIZE 31 + + extern str2m_2_mask_t + str2m_2_str2mask(char const * str, str2m_2_mask_t old); + + extern size_t + str2m_2_mask2str(str2m_2_mask_t mask, char * buf, size_t len); + + #endif /* STR2ENUM_STR2M_2_H_GUARD */ + _EOF_ + +mask_all=` + sed -n '/KWD_MASK_ALL/{;s/.*0x/0x/;s/UL*$//;p;q;}' $testname-h2.base` + +cat > $testname-c2.base <<- _EOF_ + * Convert a command (keyword) to a str2m_2_enum_t enumeration value. + * + * @param[in] str a string that should start with a known key word. + * @param[in] len the provided length of the keyword at \a str. + * @returns the enumeration value. + * If not found, that value is STR2M_2_COUNT_KWDBNM. + */ + static str2m_2_enum_t + find_str2m_2_kwdbnm(char const * str, size_t len) + { + str2m_2_map_t const * map; + + map = find_str2m_2_name(str, (unsigned int)len); + return (map == NULL) ? STR2M_2_COUNT_KWDBNM : map->str2m_2_id; + } + + /** + * Convert an str2m_2_enum_t value into a string. + * + * @param[in] id the enumeration value + * @returns the associated string, or "* UNDEFINED *" if \a id + * is out of range. + */ + static char const * + str2m_2_name(str2m_2_enum_t id) + { + static char const undef[] = "* UNDEFINED *"; + static char const * const nm_table[] = { + [STR2M_2_KWDBNM_ELEVEN ] = "eleven", + [STR2M_2_KWDBNM_NINTEEN ] = "ninteen", + [STR2M_2_KWDBNM_ONE ] = "one", + [STR2M_2_KWDBNM_SEVEN ] = "seven", + [STR2M_2_KWDBNM_THREE ] = "three" }; + char const * res = undef; + if (id < STR2M_2_COUNT_KWDBNM) { + res = nm_table[id]; + if (res == NULL) + res = undef; + } + return res; + } + + /** + * Convert a string to a str2m_2_mask_t mask. + * Bit names prefixed with a hyphen have the bit removed from the mask. + * If the string starts with a '-', '+' or '|' character, then + * the old value is used as a base, otherwise the result mask + * is initialized to zero. Separating bit names with '+' or '|' + * characters is optional. By default, the bits are "or"-ed into the + * result. + * + * @param[in] str string with a list of bit names + * @param[in] old previous value, used if \a str starts with a '+' or '-'. + * + * @returns an unsigned integer with the bits set. + */ + str2m_2_mask_t + str2m_2_str2mask(char const * str, str2m_2_mask_t old) + { + static char const white[] = ", \t\f"; + static char const name_chars[] = + "ehilnorstv" + "EHILNORSTV"; + + str2m_2_mask_t res = 0; + int have_data = 0; + + for (;;) { + str2m_2_enum_t val; + unsigned int val_len; + unsigned int invert = 0; + + str += strspn(str, white); + switch (*str) { + case NUL: return res; + case '-': case '~': + invert = 1; + /* FALLTHROUGH */ + + case '+': case '|': + if (have_data == 0) + res = old; + + str += 1 + strspn(str + 1, white); + if (*str == NUL) + return 0; + } + + val_len = strspn(str, name_chars); + if (val_len == 0) + return 0; + val = find_str2m_2_kwdbnm(str, val_len); + if (val == STR2M_2_COUNT_KWDBNM) + return 0; + if (invert) + res &= ~((str2m_2_mask_t)1 << val); + else + res |= (str2m_2_mask_t)1 << val; + have_data = 1; + str += val_len; + } + } + + /** + * Convert a str2m_2_mask_t mask to a string. + * + * @param[in] mask the mask with the bits to be named + * @param[out] buf where to store the result. This may be NULL. + * @param[in] len size of the output buffer + * @results The full length of the space needed for the result, + * including the terminating NUL byte. The actual result will not + * overwrite \a len bytes at \a buf. This value will also never + * exceed MAX_STR2M_2_NAME_SIZE. + */ + size_t + str2m_2_mask2str(str2m_2_mask_t mask, char * buf, size_t len) + { + str2m_2_enum_t val = (str2m_2_enum_t)0; + size_t res = 0; + if (buf == NULL) len = 0; + + for (; mask != 0; val++, mask >>= 1) { + char const * p; + size_t l; + + if (val >= STR2M_2_COUNT_KWDBNM) + break; + + if ((mask & 1) == 0) + continue; + + p = str2m_2_name(val); + if (*p == '*') + continue; /* ignore invalid bits */ + + l = strlen(p) + 1; /* includes NUL byte or spacer byte */ + if (l <= len) { + if (res > 0) + *(buf++) = ' '; + memcpy(buf, p, l); + buf += l - 1; + len -= l; + } + res += l; + } + return (res == 0) ? 1 : res; + } + /* end of str2m-2.c */ + _EOF_ + +# # # # # # # # # # RUN THE TEST PART 2 # # # # # # # + +echo run_ag x ${AGCMD} -T str2mask $testname.def +echo "base-name = '$testname-2'; prefix = '${testname}_2';" >> $testname.def +run_ag x ${AGCMD} -T str2mask $testname.def || \ + failure ${AGCMD} failed +get_h_text='/#ifndef .*_GUARD/,/#endif .*_GUARD/p' +${SED} -n "${get_h_text}" $testname-2.h > $testname-h2.res +get_c_text=`echo "$get_c_text" | ${SED} "$rep_name"` +${SED} -n "/_names+/d;${get_c_text}" $testname-2.c > $testname-c2.res + +fpair="$testname-h2.base $testname-h2.res" +cmp -s $fpair || \ + failure "$testname-2 $fpair failed`echo + diff $fpair`" + +fpair="$testname-c2.base $testname-c2.res" +cmp -s $fpair || \ + failure "$testname-2 $fpair failed`echo + diff $fpair`" + +# # # # # # # # # # RUN THE TEST PART 3 # # # # # # # + +echo running $testname-2.c program +chmod 666 $testname-2.c +cmd_sum=`echo $cmd_list | sed 's/ / + /g'` +cat > $testname-main.c <<- _EOF_ + #include + #include "$testname-2.c" + int main(int argc, char ** argv) { + str2m_2_mask_t mask = + str2m_2_str2mask("${cmd_sum}", 0); + char buf[MAX_STR2M_2_NAME_SIZE]; + size_t l = str2m_2_mask2str(mask, buf, MAX_STR2M_2_NAME_SIZE); + + printf("0x%04X --> %u bytes: '%s'\n", + (unsigned int)mask, (unsigned int)l, buf); + if (l != MAX_STR2M_2_NAME_SIZE) { + fprintf(stderr, "expected len: %u, actual: %u\n", + MAX_STR2M_2_NAME_SIZE, (unsigned int)l); + return 1; + } + mask = str2m_2_str2mask("- three - eleven - ninteen", mask); + if (mask != STR2M_2_KWD_NOT_ONE_SEVEN_MASK) { + fprintf(stderr, "0x%04X != 0x%04X\n", mask, + STR2M_2_KWD_NOT_ONE_SEVEN_MASK); + return 1; + } + return 0; + } + _EOF_ + +${CC:-cc} -o ${testname} $testname-main.c || \ + failure "cannot compile $testname-2.c" +./${testname} > ${testname}-btest +echo "$mask_all --> $(( ${#cmd_list} + 1 )) bytes: '$cmd_list'" \ + > ${testname}-bbase +fpair="${testname}-bbase ${testname}-btest" +cmp -s $fpair || \ + failure "$testname $fpair run failed`echo + diff $fpair`" + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 4 +## sh-basic-offset: 4 +## End: + +# end of str2m.test diff --git a/agen5/test/stress.test b/agen5/test/stress.test new file mode 100755 index 0000000..84e44e0 --- /dev/null +++ b/agen5/test/stress.test @@ -0,0 +1,67 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# ---------------------------------------------------------------------- +# stress.test --- stress test +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . +## +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # TEMPLATE FILE # # # # # # # # # + +echo creating ${testname}.tpl +cat > ${testname}.tpl <<_EOF_ +[= AutoGen5 template test =] +Entry Count = [= (count "entry") =]. +_EOF_ + +# # # # # # # # # # EXPECTED OUTPUT FILE # # # # # # # +set -x +echo creating ${testname}.samp +ecount=${STRESS_COUNT:-1000} +# this is the output we should expect to see +echo "Entry Count = ${ecount}." > ${testname}.samp + +( + set +x + echo "AutoGen Definitions ${testname};" + idx=1 + while test $idx -le ${ecount} + do + echo "entry = { value = 'val-${idx}'; depth = '${idx}'; const = xx; };" + idx=`expr $idx + 1` + done +) | run_ag x -b ${testname} - +test $? -eq 0 || failure autogen failed + +cmp -s ${testname}.test ${testname}.samp || \ + failure "`diff ${testname}.test ${testname}.samp`" + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of stress.test diff --git a/agen5/test/string.test b/agen5/test/string.test new file mode 100755 index 0000000..ad651c4 --- /dev/null +++ b/agen5/test/string.test @@ -0,0 +1,248 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# string.test --- test string formation rules +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . +## +# ---------------------------------------------------------------------- + +. ./defs + +# There are five different things we need to examine: +# +# 1. That the autogen internal string. +# 2. What we expect that string to contain. +# 3. What is generated as the "C" representation +# 4. What is generated for raw shell strings +# 5. What is generated for "cooked" shell strings +# +# We will compare all these things by generating a C program that +# will test the various strings and a shell script to invoke the +# program with the two shell string formats for arguments. +# The program will also write out the expected string value. +# That value will be compared with what autogen wrote out +# as its internal value. +# +# All this stuff must be generated carefully. +# Specifically, the '${testname}' expressions need to +# be expanded in certain parts of the output file. +# In those areas, the eof marker must *not* be quoted. +# In other places (e.g., where defining the strings), +# rather than hassle with understanding shell quoting rules, +# instead we *will* quote the EOF marker to avoid +# any shell interpretation at all!! +# +# # # # # # # # # # TEMPLATE FILE # # # # # # # # # + +echo creating $testname.tpl +exec 4> $testname.tpl +cat >&4 <<_EOF_ +[= AutoGen5 Template c sh =] +[= + +CASE (suffix) =][= + + == c + +=]#include +#include +#include + +#ifndef STDOUT_FILENO +# define STDOUT_FILENO 1 +#endif[= + + + ;; Create a file containing nothing but the + ;; autogen internal contents of the string + ;; + (out-push-new "${testname}.raw") + + =][=string=][= + + (out-pop) + +=] +_EOF_ + +test -z "$LINENO" && LINENO=` + ${GREP} -n FIND-THIS-LINE-NUMBER $0 | sed 's/:.*//'` # close enough +printf '\nchar zTestFile[] = "%s";\n' \ + ${testname}.raw >&4 + +test "X$LINENO" = X || \ + echo "#line `expr $LINENO - 1` \"$(basename $0)\"" >&4 +cat >&4 <<'_EOF_' +char zGened[] = [=(c-string (get "string"))=]; +char zKrGen[] = [=(kr-string (get "string"))=]; +char zExpect[] = "'\f\r\b\v\t\a\n\n" + "\\f\\r\\b\\v\\t\\a\\n\n" + "\"Wow!\" This'll be \\hard\\'\n" + "#endif /* .\n" + "and it'll be a \"hassle\"." + "\001\002\003\n'"; +#define expectSize ((int)(sizeof(zExpect) - 1)) +int checkStr( char* pz, char const* pzWhat ); +int checkStr( char* pz, char const* pzWhat ) +{ + static char const zNotMatch[] = + "%s generated string mismatches at offset %d of %d\n" + "Expected char: 0x%02X saw char: 0x%02X\n" + "Expected string:\n==>%s<==\n\n" + "Generated string:\n-->%s<--\n\n"; + + char* pzE = zExpect; + char* pzR = pz; + int ix = (int)strlen(pz); + int res = 0; + + if (ix != expectSize) { + fprintf( stderr, "%s is %d bytes, not %d\n", pzWhat, ix, expectSize ); + res = 1; + } + + for (ix = 0; ix < expectSize; ix++) { + if (*(pzE++) != *(pzR++)) { + fprintf(stderr, zNotMatch, pzWhat, ix, expectSize, + (unsigned char)pzE[-1], (unsigned char)pzR[-1], zExpect, pz); + return 1; + } + } + if (*pzE != '\0') { + fputs( "compile error: expected string too long\n", stderr); + res = 1; + } else if (*pzR != '\0') { + fprintf(stderr, "%s has %d residual characters:\n==>%s<==\n", + pzWhat, (int)strlen(pzR), pzR); + res = 1; + } + return res; +} + + +int main( int argc, char** argv ) +{ + int resCode = 0; + + /* + * Write out the expected value to a file. + * The "cmp" program will compare it with the + * internal version autogen wrote out itself. + */ + write( STDOUT_FILENO, zExpect, sizeof( zExpect )-1); + close( STDOUT_FILENO ); + + if (sizeof( zGened ) != sizeof( zExpect )) { + fputs( "Expected and generated string sizes do not match.\n", + stderr ); + resCode = 1; + } + + if (strlen( zGened ) != sizeof( zGened )-1) { + fputs( "The generated string contains a NUL.\n", stderr ); + resCode++; + } + + if (checkStr( zGened, "'C' program" )) + resCode++; + + if (checkStr( zKrGen, "K&R 'C' program" )) + resCode++; + + if (checkStr( argv[1], "Raw shell" )) + resCode++; + + if (checkStr( argv[2], "Cooked shell" )) + resCode++; + + return resCode; +}[= + + == sh + +=]#! /bin/sh +set -x +_EOF_ + +cat 1>&4 <<_EOF_ +./${testname} [=(raw-shell-str (get "string")) + =] [=(shell-str (get "string"))=] > ${testname}.out +res=\$? +cmp ${testname}.out ${testname}.raw > /dev/null 2>&1 + +if [ \$? -ne 0 ] +then + echo the AutoGen internal content did not match expectations + res=\`expr \$res + 1\` +fi +if [ \$res -eq 0 ] +then + echo All string comparisons pass +else + echo There were \$res string test failures + exit \$res +fi[= + +ESAC + +=] +_EOF_ +exec 4>&- + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +echo creating $testname.def +echo "autogen definitions $testname.tpl;" > $testname.def +cat >> $testname.def <<'_EOF_' + +string = + "'\f\r\b\v\t\a\n +" + '\f\r\b\v\t\a\n +' + '"Wow!" This\'ll be \\hard\\\' +\#endif /* . +' + "and it'll be a \"hassle\"." + "\001\x02\X03\n'"; + +_EOF_ + +# # # # # # # # # # RUN THE TESTS # # # # # # # # # # # + +SHELL=${SHELL-/bin/sh} + +run_ag x $testname.def || failure autogen failed + +compile + +chmod +x *.sh + +./${testname}.sh || failure strings do not match + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 4 +## sh-basic-offset: 4 +## End: + +# end of string.test diff --git a/agen5/test/strtable.test b/agen5/test/strtable.test new file mode 100755 index 0000000..9504611 --- /dev/null +++ b/agen5/test/strtable.test @@ -0,0 +1,96 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# strtable.test --- test string-table functionality +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . +## +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # TEMPLATE FILE # # # # # # # # # + +echo creating ${testname}.tpl +cat > ${testname}.tpl <<_EOF_ +[= AutoGen5 template test =] +[= + +(string-table-new "scribble") +(out-push-new) ;; redirect output to temporary +(define ct 1) + +=][= + +FOR str IN that was the week that was + +=][= (set! ct (+ ct 1)) =] + [= (string-table-add-ref "scribble" (get "str")) =],[= + +ENDFOR + +=][= + (out-suspend "main") + (emit-string-table "scribble") + (emit (sprintf "\n#define STRING_CT %d\n" (- ct 1))) + (ag-fprintf 0 "\nchar const * const ap[%d] = {" ct) + (out-resume "main") + (out-pop #t) ;; now dump out the redirected output + ;; and finish: =] + NULL }; +_EOF_ + +# # # # # # # # # # EXPECTED OUTPUT FILE # # # # # # # +set -x +echo creating ${testname}.base +# this is the output we should expect to see +cat > ${testname}.base <<'_EOF_' + +static char const scribble[18] = +/* 0 */ "that\0" +/* 5 */ "was\0" +/* 9 */ "the\0" +/* 13 */ "week"; + +#define STRING_CT 6 + +char const * const ap[7] = { + scribble+0, + scribble+5, + scribble+9, + scribble+13, + scribble+0, + scribble+5, + NULL }; +_EOF_ + +run_ag x -b ${testname} -T ${testname}.tpl --no-defin || \ + failure autogen failed +cmp -s ${testname}.base ${testname}.test || \ + failure "bad output: `diff -c ${testname}.base ${testname}.test`" + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of strtable.test diff --git a/agen5/test/strxform.test b/agen5/test/strxform.test new file mode 100755 index 0000000..3290e2c --- /dev/null +++ b/agen5/test/strxform.test @@ -0,0 +1,86 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# strxform.test --- test string transformation functionality +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . +## +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # TEMPLATE FILE # # # # # # # # # + +echo creating ${testname}.tpl +${SED} 's/^ *[0-9]*: //' > ${testname}.tpl <<- _EOTPL_ + 1: [= AutoGen5 Template test =] + 2: string input: [= in-str =] + 3: + 4: string->c-name! [= (string->c-name! (get "in-str")) =] + 5: string-upcase! [= (string-upcase! (get "in-str")) =] + 6: string-capitalize! [= (string-capitalize! (get "in-str")) =] + 7: string-capitalize [= (string-capitalize (get "in-str")) =] + 8: string-downcase! [= (string-downcase! (get "in-str")) =] + 9: string-downcase [= (string-downcase (get "in-str")) =] +10: string->camelcase [= (string->camelcase (get "in-str")) =] +_EOTPL_ + +cat > ${testname}.def <<- _EOF_ + AutoGen Definitions ${testname}.tpl; + in-str = "The 10quick\tfoxes-jumped/very=\n=high9indeed!"; + _EOF_ + +# # # # # # # # # # # EXPECTED OUTPUT FILE # # # # # # # +set -x +echo creating ${testname}.out +# this is the output we should expect to see +cat > ${testname}.out <<- \_EOF_ + string input: The 10quick foxes-jumped/very= + =high9indeed! + + string->c-name! The 10quick foxes_jumped_very_ + _high9indeed_ + string-upcase! THE 10QUICK FOXES-JUMPED/VERY= + =HIGH9INDEED! + string-capitalize! The 10quick Foxes-Jumped/Very= + =High9indeed! + string-capitalize The 10quick Foxes-Jumped/Very= + =High9indeed! + string-downcase! the 10quick foxes-jumped/very= + =high9indeed! + string-downcase the 10quick foxes-jumped/very= + =high9indeed! + string->camelcase The10QuickFoxesJumpedVeryHigh9Indeed + _EOF_ + +run_ag x ${testname}.def || failure autogen failed + +cmp -s ${testname}.test ${testname}.out || \ + failure "unexpected output:${nl}`diff ${testname}.out ${testname}.test`" + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of strxform.test diff --git a/agen5/test/suffix.test b/agen5/test/suffix.test new file mode 100755 index 0000000..225618c --- /dev/null +++ b/agen5/test/suffix.test @@ -0,0 +1,89 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# suffix.test --- test the select suffix option +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . +## +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # TEMPLATE FILE # # # # # # # # # + +echo creating ${testname}.tpl +cat > ${testname}.tpl <<'_EOF_' +[= AutoGen5 Template test =] +[= + +CASE (suffix) =][= + +== test =]BOGUS[= +== "* NONE *" =]No Suffix[= +== Example =]Example[= +* =]Bogon ``[=(suffix)=]''[= + +ESAC =] +_EOF_ + +# # # # # # # # # # EXPECTED OUTPUT FILE # # # # # # # + +echo "Example" > ${testname}.Example.test +echo "No Suffix" > ${testname}.stdout.test + +# # # # # # # # # # RUN TESTS # # # # # # # +nodefopt="--no-def -T${testname}.tpl" +run_ag ex ${nodefopt} -oExample -b${testname} || \ + failure autogen ${nodefopt} -oExample -b${testname} + +cmp ${testname}.Example* || \ + failure `diff -c cmp ${testname}.Example*` + +# # # # # # # # # # STDOUT TEMPLATE # # # # # # # # # + +echo creating ${testname}.tpl +cat > ${testname}.tpl <<'_EOF_' +[= AutoGen5 Template =] +[= +text =] +_EOF_ + +cat > ${testname}.samp <<- EOF + This is some text. + This should appear in the output. +EOF + +cat > ${testname}.def <<\EOF +AutoGen Definitions suffix; +text = `cat suffix.samp`; +EOF + +run_ag sfx ${testname}.def | ${EGREP} -v '^in state ' > ${testname}.out +cmp ${testname}.out ${testname}.samp || \ + failure "`diff ${testname}.out ${testname}.samp`" + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of suffix.test diff --git a/agen5/test/time.test b/agen5/test/time.test new file mode 100755 index 0000000..2ee9e81 --- /dev/null +++ b/agen5/test/time.test @@ -0,0 +1,63 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# ---------------------------------------------------------------------- +# time.test --- test modification time settings +# +# Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . +## +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # TEMPLATE FILE # # # # # # # # # + +echo creating ${testname}.tpl +cat > ${testname}.tpl <<_EOF_ +[= AutoGen5 template test =] +Plain text template. +_EOF_ + +touch -t 200109110846.00 ${testname}.tpl + +run_ag time --source-time -b ${testname} -T ${testname}.tpl --no-definitions || \ + failure autogen failed + +touch -t 200109110846.02 ${testname}.taaa + +set -- `ls -t ${testname}.t*` + +while : +do + test "${3}" = ${testname}.tpl || break + test "${2}" = ${testname}.test || break + test "${1}" = ${testname}.taaa || break + cleanup + exit 0 +done + +failure "wrong file time ordering: $*" + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of time.test diff --git a/agen5/tpLoad.c b/agen5/tpLoad.c new file mode 100644 index 0000000..4eb5b32 --- /dev/null +++ b/agen5/tpLoad.c @@ -0,0 +1,560 @@ + +/** + * @file tpLoad.c + * + * This module will load a template and return a template structure. + * + * @addtogroup autogen + * @{ + */ +/* + * This file is part of AutoGen. + * Copyright (C) 1992-2018 Bruce Korb - all rights reserved + * + * AutoGen is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AutoGen is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +/** + * Return the template structure matching the name passed in. + */ +static templ_t * +find_tpl(char const * tpl_name) +{ + templ_t * pT = named_tpls; + while (pT != NULL) { + if (streqvcmp(tpl_name, pT->td_name) == 0) + break; + pT = C(templ_t *, (pT->td_scan)); + } + return pT; +} + +/** + * the name is a regular file with read access. + * @param[in] fname file name to check + * @returns \a true when the named file exists and is a regular file + * @returns \a false otherwise. + */ +static bool +read_okay(char const * fname) +{ + struct stat stbf; + if (stat(fname, &stbf) != 0) + return false; + if (! S_ISREG(stbf.st_mode)) + return false; + return (access(fname, R_OK) == 0) ? true : false; +} + +/** + * Expand a directory name that starts with '$'. + * + * @param[in,out] dir_pp pointer to pointer to directory name + * @returns the resulting pointer + */ +static char const * +expand_dir(char const ** dir_pp, char * name_buf) +{ + char * res = VOIDP(*dir_pp); + + if (res[1] == NUL) + AG_ABEND(aprf(LOAD_FILE_SHORT_NAME, res)); + + if (! optionMakePath(name_buf, (int)AG_PATH_MAX, res, + autogenOptions.pzProgPath)) { + /* + * The name expanded to "empty", so substitute curdir. + */ + strcpy(res, FIND_FILE_CURDIR); + + } else { + free(res); + AGDUPSTR(res, name_buf, "find dir name"); + *dir_pp = res; /* save computed name for later */ + } + + return res; +} + +static inline bool +file_search_dirs( + char const * in_name, + char * res_name, + char const * const * sfx_list, + char const * referring_tpl, + size_t nm_len, + bool no_suffix) +{ + /* + * Search each directory in our directory search list for the file. + * We always force two copies of this option, so we know it exists. + * Later entries are more recently added and are searched first. + * We start the "dirlist" pointing to the real last entry. + */ + int ct = STACKCT_OPT(TEMPL_DIRS); + char const ** dirlist = STACKLST_OPT(TEMPL_DIRS) + ct - 1; + char const * c_dir = FIND_FILE_CURDIR; + + /* + * IF the file name starts with a directory separator, + * then we only search once, looking for the exact file name. + */ + if (*in_name == '/') + ct = -1; + + for (;;) { + char * pzEnd; + + /* + * c_dir is always FIND_FILE_CURDIR the first time through + * and is never that value after that. + */ + if (c_dir == FIND_FILE_CURDIR) { + + memcpy(res_name, in_name, nm_len); + pzEnd = res_name + nm_len; + *pzEnd = NUL; + + } else { + unsigned int fmt_len; + + /* + * IF one of our template paths starts with '$', then expand it + * and replace it now and forever (the rest of this run, anyway). + */ + if (*c_dir == '$') + c_dir = expand_dir(dirlist+1, res_name); + + fmt_len = (unsigned)snprintf( + res_name, AG_PATH_MAX - MAX_SUFFIX_LEN, + FIND_FILE_DIR_FMT, c_dir, in_name); + if (fmt_len >= AG_PATH_MAX - MAX_SUFFIX_LEN) + break; // fail-return + pzEnd = res_name + fmt_len; + } + + if (read_okay(res_name)) + return true; + + /* + * IF the file does not already have a suffix, + * THEN try the ones that are okay for this file. + */ + if (no_suffix && (sfx_list != NULL)) { + char const * const * sfxl = sfx_list; + *(pzEnd++) = '.'; + + do { + strcpy(pzEnd, *(sfxl++)); /* must fit */ + if (read_okay(res_name)) + return true; + + } while (*sfxl != NULL); + } + + /* + * IF we've exhausted the search list, + * THEN see if we're done, else go through search dir list. + * + * We try one more thing if there is a referrer. + * If the searched-for file is a full path, "ct" will + * start at -1 and we will leave the loop here and now. + */ + if (--ct < 0) { + if ((referring_tpl == NULL) || (ct != -1)) + break; + c_dir = referring_tpl; + + } else { + c_dir = *(dirlist--); + } + } + + return false; +} + +/** + * Search for a file. + * + * Starting with the current directory, search the directory list trying to + * find the base template file name. If there is a referring template (a + * template with an "INCLUDE" macro), then try that, too, before giving up. + * + * @param[in] in_name the file name we are looking for. + * @param[out] res_name where we stash the file name we found. + * @param[in] sfx_list a list of suffixes to try, if \a in_name has none. + * @param[in] referring_tpl file name of the template with a INCLUDE macro. + * + * @returns \a SUCCESS when \a res_name is valid + * @returns \a FAILURE when the file is not found. + */ +static tSuccess +find_file(char const * in_name, + char * res_name, + char const * const * sfx_list, + char const * referring_tpl) +{ + bool no_suffix; + void * free_me = NULL; + tSuccess res = SUCCESS; + + size_t nm_len = strlen(in_name); + if (nm_len >= AG_PATH_MAX - MAX_SUFFIX_LEN) + return FAILURE; + + /* + * Expand leading environment variables. + * We will not mess with embedded ones. + */ + if (*in_name == '$') { + if (! optionMakePath(res_name, (int)AG_PATH_MAX, in_name, + autogenOptions.pzProgPath)) + return FAILURE; + + AGDUPSTR(in_name, res_name, "find file name"); + free_me = VOIDP(in_name); + + /* + * in_name now points to the name the file system can use. + * It must _not_ point to res_name because we will likely + * rewrite that value using this pointer! + */ + nm_len = strlen(in_name); + } + + /* + * Not a complete file name. If there is not already + * a suffix for the file name, then append ".tpl". + * Check for immediate access once again. + */ + { + char * bf = strrchr(in_name, '/'); + bf = (bf != NULL) ? strchr(bf, '.') : strchr(in_name, '.'); + no_suffix = (bf == NULL); + } + + /* + * The referrer is useful only if it includes a directory name. + * If not NULL, referring_tpl becomes an allocated directory name. + */ + if (referring_tpl != NULL) { + char * pz = strrchr(referring_tpl, '/'); + if (pz == NULL) + referring_tpl = NULL; + else { + AGDUPSTR(referring_tpl, referring_tpl, "refer tpl"); + pz = strrchr(referring_tpl, '/'); + *pz = NUL; + } + } + + if (! file_search_dirs(in_name, res_name, sfx_list, referring_tpl, + nm_len, no_suffix)) + res = FAILURE; + + AGFREE(free_me); + AGFREE(referring_tpl); + return res; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Count the macros in a template. + * We need to allocate the right number of pointers. + */ +static size_t +cnt_macros(char const * pz) +{ + size_t ct = 2; + for (;;) { + pz = strstr(pz, st_mac_mark); + if (pz == NULL) + break; + ct += 2; + if (strncmp(pz - end_mac_len, end_mac_mark, end_mac_len) == 0) + ct--; + pz += st_mac_len; + } + return ct; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Load the macro array and file name. + * @param[in,out] tpl the template to load + * @param[in] fname the source file name of the template + * @param[in] pzN someting + * @param[in] data the template text + */ +static void +load_macs(templ_t * tpl, char const * fname, char const * pzData) +{ + macro_t * pMac = tpl->td_macros; + + { + char * txt = (char *)(pMac + tpl->td_mac_ct); + + AGDUPSTR(tpl->td_file, fname, "templ file"); + + memcpy(txt, PSEUDO_MAC_TPL_FILE, PSEUDO_MAC_TPL_FILE_LEN+1); + tpl->td_name = txt; + tpl->td_text = (txt += PSEUDO_MAC_TPL_FILE_LEN); + tpl->td_scan = txt + 1; + } + + current_tpl = tpl; + + { + macro_t * e_mac = parse_tpl(pMac, &pzData); + int ct; + + /* + * Make sure all of the input string was scanned. + */ + if (pzData != NULL) + AG_ABEND(LOAD_MACS_BAD_PARSE); + + ct = (int)(e_mac - pMac); + + /* + * IF there are empty macro slots, + * THEN pack the text + */ + if (ct < tpl->td_mac_ct) { + int delta = + (int)(sizeof(macro_t) * (size_t)(tpl->td_mac_ct - ct)); + void * data = + (tpl->td_name == NULL) ? tpl->td_text : tpl->td_name; + size_t size = (size_t)(tpl->td_scan - (char *)data); + memmove(VOIDP(e_mac), data, size); + + tpl->td_text -= delta; + tpl->td_scan -= delta; + tpl->td_name -= delta; + tpl->td_mac_ct = ct; + } + } + + tpl->td_size = (size_t)(tpl->td_scan - (char *)tpl); + tpl->td_scan = NULL; + + /* + * We cannot reallocate a smaller array because + * the entries are all linked together and + * realloc-ing it may cause it to move. + */ +#if defined(DEBUG_ENABLED) + if (HAVE_OPT(SHOW_DEFS)) { + static char const zSum[] = + "loaded %d macros from %s\n" + "\tBinary template size: 0x%zX\n\n"; + fprintf(trace_fp, zSum, tpl->td_mac_ct, fname, tpl->td_size); + } +#endif +} + +/** + * Load a template from mapped memory. Load up the pseudo macro, + * count the macros, allocate the data, and parse all the macros. + * + * @param[in] minfo information about the mapped memory. + * @param[in] fname the full path input file name. + * + * @returns the digested data + */ +static templ_t * +digest_tpl(tmap_info_t * minfo, char * fname) +{ + templ_t * res; + + /* + * Count the number of macros in the template. Compute + * the output data size as a function of the number of macros + * and the size of the template data. These may get reduced + * by comments. + */ + char const * dta = + load_pseudo_mac((char const *)minfo->txt_data, fname); + + size_t mac_ct = cnt_macros(dta); + size_t alloc_sz = (sizeof(*res) + (mac_ct * sizeof(macro_t)) + + minfo->txt_size + - (size_t)(dta - (char const *)minfo->txt_data) + + strlen(fname) + 0x10) + & (size_t)(~0x0F); + + res = (templ_t *)AGALOC(alloc_sz, "main template"); + memset(VOIDP(res), 0, alloc_sz); + + /* + * Initialize the values: + */ + res->td_magic = magic_marker; + res->td_size = alloc_sz; + res->td_mac_ct = (int)mac_ct; + + strcpy(res->td_start_mac, st_mac_mark); /* must fit */ + strcpy(res->td_end_mac, end_mac_mark); /* must fit */ + load_macs(res, fname, dta); + + res->td_name -= (long)res; + res->td_text -= (long)res; + res = (templ_t *)AGREALOC(VOIDP(res), res->td_size, + "resize template"); + res->td_name += (long)res; + res->td_text += (long)res; + + return res; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Starting with the current directory, search the directory + * list trying to find the base template file name. + */ +static templ_t * +tpl_load(char const * fname, char const * referrer) +{ + static tmap_info_t map_info; + static char tpl_file[ AG_PATH_MAX ]; + + /* + * Find the template file somewhere + */ + { + static char const * const sfx_list[] = { + LOAD_TPL_SFX_TPL, LOAD_TPL_SFX_AGL, NULL }; + if (! SUCCESSFUL(find_file(fname, tpl_file, sfx_list, referrer))) { + errno = ENOENT; + AG_CANT(LOAD_TPL_CANNOT_MAP, fname); + } + } + + /* + * Make sure the specified file is a regular file. + * Make sure the output time stamp is at least as recent. + */ + { + struct stat stbf; + if (stat(tpl_file, &stbf) != 0) + AG_CANT(LOAD_TPL_CANNOT_STAT, fname); + + if (! S_ISREG(stbf.st_mode)) { + errno = EINVAL; + AG_CANT(LOAD_TPL_IRREGULAR, fname); + } + + if (time_is_before(outfile_time, stbf.st_mtime)) + outfile_time = stbf.st_mtime; + if (time_is_before(maxfile_time, stbf.st_mtime)) + maxfile_time = stbf.st_mtime; + } + + text_mmap(tpl_file, PROT_READ|PROT_WRITE, MAP_PRIVATE, &map_info); + if (TEXT_MMAP_FAILED_ADDR(map_info.txt_data)) + AG_ABEND(aprf(LOAD_TPL_CANNOT_OPEN, tpl_file)); + + if (dep_fp != NULL) + add_source_file(tpl_file); + + /* + * Process the leading pseudo-macro. The template proper + * starts immediately after it. + */ + { + macro_t * sv_mac = cur_macro; + templ_t * res; + cur_macro = NULL; + + res = digest_tpl(&map_info, tpl_file); + cur_macro = sv_mac; + text_munmap(&map_info); + + return res; + } +} + +/** + * Deallocate anything related to a template. + * This includes the pointer passed in and any macros that have an + * unload procedure associated with it. + * + * @param[in] tpl the template to unload + */ +static void +tpl_unload(templ_t * tpl) +{ + macro_t * mac = tpl->td_macros; + int ct = tpl->td_mac_ct; + + while (--ct >= 0) { + unload_proc_p_t proc; + unsigned int ix = mac->md_code; + + /* + * "select" functions get remapped, depending on the alias used for + * the selection. See the "mac_func_t" enumeration in functions.h. + */ + if (ix >= FUNC_CT) + ix = FTYP_SELECT; + + proc = unload_procs[ ix ]; + if (proc != NULL) + (*proc)(mac); + + mac++; + } + + AGFREE(tpl->td_file); + AGFREE(tpl); +} + +/** + * This gets called when all is well at the end. + * The supplied template and all named templates are unloaded. + * + * @param[in] tpl the last template standing + */ +static void +cleanup(templ_t * tpl) +{ + if (HAVE_OPT(USED_DEFINES)) + print_used_defines(); + + if (dep_fp != NULL) + wrap_up_depends(); + + optionFree(&autogenOptions); + + for (;;) { + tpl_unload(tpl); + tpl = named_tpls; + if (tpl == NULL) + break; + named_tpls = C(templ_t *, (tpl->td_scan)); + } + + free_for_context(INT_MAX); + unload_defs(); +} + +/** + * @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of agen5/tpLoad.c */ diff --git a/agen5/tpParse.c b/agen5/tpParse.c new file mode 100644 index 0000000..ce35294 --- /dev/null +++ b/agen5/tpParse.c @@ -0,0 +1,412 @@ + +/** + * @file tpParse.c + * + * This module will load a template and return a template structure. + * + * @addtogroup autogen + * @{ + */ +/* + * This file is part of AutoGen. + * Copyright (C) 1992-2018 Bruce Korb - all rights reserved + * + * AutoGen is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AutoGen is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#if defined(DEBUG_ENABLED) + static char const zTUndef[] = "%-10s (%d) line %d - MARKER\n"; + + static int tpl_nest_lvl = 0; + + static char const tpl_def_fmt[] = "%-10s (%d) line %d end=%d, strlen=%d\n"; +#endif + +/** + * Return the enumerated function type corresponding + * to a name pointed to by the input argument. + */ +static mac_func_t +func_code(char const ** pscan) +{ + fn_name_type_t const * pNT; + char const * pzFuncName = *pscan; + int hi, lo, av; + int cmp; + + /* + * IF the name starts with a punctuation, then it is some sort of + * alias. Find the function in the alias portion of the table. + */ + if (IS_PUNCTUATION_CHAR(*pzFuncName)) { + hi = FUNC_ALIAS_HIGH_INDEX; + lo = FUNC_ALIAS_LOW_INDEX; + do { + av = (hi + lo)/2; + pNT = fn_name_types + av; + cmp = (int)(*(pNT->pName)) - (int)(*pzFuncName); + + /* + * For strings that start with a punctuation, we + * do not need to test for the end of token + * We will not strip off the marker and the load function + * will figure out what to do with the code. + */ + if (cmp == 0) + return pNT->fType; + if (cmp > 0) + hi = av - 1; + else lo = av + 1; + } while (hi >= lo); + return FTYP_BOGUS; + } + + if (! IS_VAR_FIRST_CHAR(*pzFuncName)) + return FTYP_BOGUS; + + hi = FUNC_NAMES_HIGH_INDEX; + lo = FUNC_NAMES_LOW_INDEX; + + do { + av = (hi + lo)/2; + pNT = fn_name_types + av; + cmp = strneqvcmp(pNT->pName, pzFuncName, (int)pNT->cmpLen); + if (cmp == 0) { + /* + * Make sure we matched to the end of the token. + */ + if (IS_VARIABLE_NAME_CHAR(pzFuncName[pNT->cmpLen])) + break; + + /* + * Advance the scanner past the macro name. + * The name is encoded in the "fType". + */ + *pscan = pzFuncName + pNT->cmpLen; + return pNT->fType; + } + if (cmp > 0) + hi = av - 1; + else lo = av + 1; + } while (hi >= lo); + + /* + * Save the name for later lookup + */ + cur_macro->md_name_off = + (size_t)(current_tpl->td_scan - current_tpl->td_text); + { + char * pzCopy = current_tpl->td_scan; + char * pe = SPN_VALUE_NAME_CHARS(pzFuncName); + size_t l = (size_t)(pe - pzFuncName); + memcpy(pzCopy, pzFuncName, l); + pzCopy += l; + pzFuncName += l; + + /* + * Names are allowed to contain colons, but not end with them. + */ + if (pzCopy[-1] == ':') + pzCopy--, pzFuncName--; + + *(pzCopy++) = NUL; + *pscan = pzFuncName; + current_tpl->td_scan = pzCopy; + } + + /* + * "Unknown" means we have to check again before we + * know whether to assign it to "FTYP_INVOKE" or "FTYP_COND". + * That depends on whether or not we find a named template + * at template instantiation time. + */ + return FTYP_UNKNOWN; +} + +static char const * +find_mac_end(char const ** ppzMark) +{ + char const * pzMark = *ppzMark + st_mac_len; + char const * pzFunc; + char const * pzNextMark; + char const * pzEndMark; + + /* + * Set our pointers to the start of the macro text + */ + for (;;) { + pzMark = SPN_NON_NL_WHITE_CHARS(pzMark); + if (*pzMark != NL) + break; + tpl_line++; + pzMark++; + } + + pzFunc = pzMark; + cur_macro->md_code = func_code(&pzMark); + cur_macro->md_line = tpl_line; + *ppzMark = pzMark; + + /* + * Find the end. (We must.) If the thing is empty, treat as a comment, + * but warn about it. + */ + pzEndMark = strstr(pzMark, end_mac_mark); + if (pzEndMark == NULL) + AG_ABEND(FIND_MAC_END_NOPE); + + if (pzEndMark == pzFunc) { + cur_macro->md_code = FTYP_COMMENT; + fprintf(trace_fp, FIND_MAC_END_EMPTY, + current_tpl->td_file, tpl_line); + return pzEndMark; + } + + /* + * Back up over a preceding backslash. It is a flag to indicate the + * removal of the end of line white space. + */ + if (pzEndMark[-1] == '\\') + pzEndMark--; + + pzNextMark = strstr(pzMark, st_mac_mark); + if (pzNextMark == NULL) + return pzEndMark; + + if (pzEndMark > pzNextMark) + AG_ABEND(FIND_MAC_END_NESTED); + + return pzEndMark; +} + +static char const * +find_mac_start(char const * pz, macro_t ** ppm, templ_t * tpl) +{ + char * pzCopy; + char const * pzEnd; + char const * res = strstr(pz, st_mac_mark); + macro_t * mac = *ppm; + + if (res == pz) + return res; + + /* + * There is some text here. Make a text macro entry. + */ + pzCopy = tpl->td_scan; + pzEnd = (res != NULL) ? res : pz + strlen(pz); + mac->md_txt_off = (uintptr_t)(pzCopy - tpl->td_text); + mac->md_code = FTYP_TEXT; + mac->md_line = tpl_line; + +#if defined(DEBUG_ENABLED) + if (HAVE_OPT(SHOW_DEFS)) { + int ct = tpl_nest_lvl; + fprintf(trace_fp, "%3u ", (unsigned int)(mac - tpl->td_macros)); + do { fputs(" ", trace_fp); } while (--ct > 0); + + fprintf(trace_fp, tpl_def_fmt, ag_fun_names[ FTYP_TEXT ], FTYP_TEXT, + mac->md_line, mac->md_end_idx, (unsigned int)(pzEnd - pz)); + } +#endif + + do { + if ((*(pzCopy++) = *(pz++)) == NL) + tpl_line++; + } while (pz < pzEnd); + + *(pzCopy++) = NUL; + *ppm = mac + 1; + tpl->td_scan = pzCopy; + + return res; /* may be NULL, if there are no more macros */ +} + +static char const * +find_macro(templ_t * tpl, macro_t ** ppm, char const ** pscan) +{ + char const * scan = *pscan; + char const * pzMark; + + pzMark = find_mac_start(scan, ppm, tpl); + + /* + * IF no more macro marks are found, THEN we are done... + */ + if (pzMark == NULL) + return pzMark; + + /* + * Find the macro code and the end of the macro invocation + */ + cur_macro = *ppm; + scan = find_mac_end(&pzMark); + + /* + * Count the lines in the macro text and advance the + * text pointer to after the marker. + */ + { + char const * pzMacEnd = scan; + char const * pz = pzMark; + + for (;;pz++) { + pz = strchr(pz, NL); + if ((pz == NULL) || (pz > pzMacEnd)) + break; + tpl_line++; + } + + /* + * Strip white space from the macro + */ + pzMark = SPN_WHITESPACE_CHARS(pzMark); + + if (pzMark != pzMacEnd) { + pzMacEnd = SPN_WHITESPACE_BACK( pzMark, pzMacEnd); + (*ppm)->md_txt_off = (uintptr_t)pzMark; + (*ppm)->md_res = (uintptr_t)(pzMacEnd - pzMark); + } + } + + /* + * IF the end macro mark was preceded by a backslash, then we remove + * trailing white space from there to the end of the line. + */ + if ((*scan != '\\') || (strncmp(end_mac_mark, scan, end_mac_len) == 0)) + scan += end_mac_len; + + else { + char const * pz; + scan += end_mac_len + 1; + pz = SPN_NON_NL_WHITE_CHARS(scan); + if (*pz == NL) { + scan = pz + 1; + tpl_line++; + } + } + + *pscan = scan; + return pzMark; +} + +#if defined(DEBUG_ENABLED) + static void +print_indentation(templ_t * tpl, macro_t * mac, int idx) +{ + static char const fmt_fmt[] = "%%%us"; + char fmt[16]; + + if (idx < 0) + fputs(" ", trace_fp); + else fprintf(trace_fp, "%3u ", (unsigned int)idx); + snprintf(fmt, sizeof(fmt), fmt_fmt, tpl_nest_lvl); + fprintf(trace_fp, fmt, ""); + (void)tpl; + (void)mac; +} + + static void +print_ag_defs(templ_t * tpl, macro_t * mac) +{ + mac_func_t ft = mac->md_code; + int ln = mac->md_line; + int idx = (mac->md_code == FTYP_BOGUS) ? -1 : (int)(mac - tpl->td_macros); + + print_indentation(tpl, mac, idx); + + if (mac->md_code == FTYP_BOGUS) + fprintf(trace_fp, zTUndef, ag_fun_names[ ft ], ft, ln); + else { + char const * pz; + if (ft >= FUNC_CT) + ft = FTYP_SELECT; + pz = (mac->md_txt_off == 0) + ? zNil + : (tpl->td_text + mac->md_txt_off); + fprintf(trace_fp, tpl_def_fmt, ag_fun_names[ft], mac->md_code, + ln, mac->md_end_idx, (unsigned int)strlen(pz)); + } +} +#endif + +/** + * Parse the template. + * @param[out] mac array of macro descriptors to fill in + * @param[in,out] p_scan pointer to string scanning address + */ +static macro_t * +parse_tpl(macro_t * mac, char const ** p_scan) +{ + char const * scan = *p_scan; + templ_t * tpl = current_tpl; + +#if defined(DEBUG_ENABLED) + + #define DEBUG_DEC(l) l-- + + if ( ((tpl_nest_lvl++) > 0) + && HAVE_OPT(SHOW_DEFS)) { + int idx = (int)(mac - tpl->td_macros); + macro_t * m = mac - 1; + + print_indentation(tpl, m, idx); + + fprintf(trace_fp, zTUndef, ag_fun_names[m->md_code], + m->md_code, m->md_line); + } +#else + #define DEBUG_DEC(l) +#endif + + while (find_macro(tpl, &mac, &scan) != NULL) { + /* + * IF the called function returns a NULL next macro pointer, + * THEN some block has completed. The returned scanning pointer + * will be non-NULL. + */ + load_proc_p_t const fn = load_proc_table[mac->md_code]; + macro_t * nxt_mac = fn(tpl, mac, &scan); + +#if defined(DEBUG_ENABLED) + if (HAVE_OPT(SHOW_DEFS)) + print_ag_defs(tpl, mac); +#endif + + if (nxt_mac == NULL) { + *p_scan = scan; + DEBUG_DEC(tpl_nest_lvl); + return mac; + } + mac = nxt_mac; + } + + DEBUG_DEC(tpl_nest_lvl); + + /* + * We reached the end of the input string. + * Return a NULL scanning pointer and a pointer to the end. + */ + *p_scan = NULL; + return mac; +} +/** + * @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of agen5/tpParse.c */ diff --git a/agen5/tpProcess.c b/agen5/tpProcess.c new file mode 100644 index 0000000..5558745 --- /dev/null +++ b/agen5/tpProcess.c @@ -0,0 +1,444 @@ + +/** + * @file tpProcess.c + * + * Parse and process the template data descriptions + * + * @addtogroup autogen + * @{ + */ +/* + * This file is part of AutoGen. + * AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoGen is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AutoGen is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +/** + * Generate all the text within a block. + * The caller must know the exact bounds of the block. + * + * @param tpl template containing block of macros + * @param mac first macro in series + * @param emac one past last macro in series + */ +static void +gen_block(templ_t * tpl, macro_t * mac, macro_t * emac) +{ + /* + * Set up the processing context for this block of macros. + * It is used by the Guile callback routines and the exception + * handling code. It is all for user friendly diagnostics. + */ + current_tpl = tpl; + + while ((mac != NULL) && (mac < emac)) { + mac_func_t fc = mac->md_code; + if (fc >= FUNC_CT) + fc = FTYP_BOGUS; + + scribble_free(); + if (OPT_VALUE_TRACE >= TRACE_EVERYTHING) + trace_macro(tpl, mac); + + cur_macro = mac; + mac = (*(load_procs[ fc ]))(tpl, mac); + } +} + +/** + * Print out information about the invocation of a macro. + * Print up to the first 32 characters in the macro, for context. + * + * @param tpl template containing macros + * @param mac first macro in series + */ +static void +trace_macro(templ_t * tpl, macro_t * mac) +{ + mac_func_t fc = mac->md_code; + if (fc >= FUNC_CT) + fc = FTYP_BOGUS; + + fprintf(trace_fp, TRACE_MACRO_FMT, ag_fun_names[fc], mac->md_code, + tpl->td_file, mac->md_line); + + if (mac->md_txt_off > 0) { + char * pz = tpl->td_text + mac->md_txt_off; + char * pe = BRK_NEWLINE_CHARS(pz); + if (pe > pz + 32) + pz = pz + 32; + + putc(' ', trace_fp); putc(' ', trace_fp); + fwrite(pz, (size_t)(pe - pz), 1, trace_fp); + putc(NL, trace_fp); + } +} + +/** + * The template output goes to stdout. Perhaps because output + * is for a CGI script. In any case, this case must be handled + * specially. + * + * @param tpl template to be processed + */ +static void +do_stdout_tpl(templ_t * tpl) +{ + SCM res; + + last_scm_cmd = NULL; /* We cannot be in Scheme processing */ + + switch (setjmp(abort_jmp_buf)) { + case SUCCESS: + break; + + case PROBLEM: + if (*oops_pfx != NUL) { + fprintf(stdout, DO_STDOUT_TPL_ABANDONED, oops_pfx); + oops_pfx = zNil; + } + fclose(stdout); + return; + + default: + fserr(AUTOGEN_EXIT_FS_ERROR, DO_STDOUT_TPL_BADR, oops_pfx); + + case FAILURE: + exit(EXIT_FAILURE); + /* NOTREACHED */ + } + + curr_sfx = DO_STDOUT_TPL_NOSFX; + curr_def_ctx = root_def_ctx; + cur_fpstack = &out_root; + out_root.stk_fp = stdout; + out_root.stk_fname = DO_STDOUT_TPL_STDOUT; + out_root.stk_flags = FPF_NOUNLINK | FPF_STATIC_NM; + if (OPT_VALUE_TRACE >= TRACE_EVERYTHING) + fputs(DO_STDOUT_TPL_START_STD, trace_fp); + + /* + * IF there is a CGI prefix for error messages, + * THEN divert all output to a temporary file so that + * the output will be clean for any error messages we have to emit. + */ + if (*oops_pfx == NUL) + gen_block(tpl, tpl->td_macros, tpl->td_macros + tpl->td_mac_ct); + + else { + char const * pzRes; + (void)ag_scm_out_push_new(SCM_UNDEFINED); + + gen_block(tpl, tpl->td_macros, tpl->td_macros + tpl->td_mac_ct); + + /* + * Read back in the spooled output. Make sure it starts with + * a content-type: prefix. If not, we supply our own HTML prefix. + */ + res = ag_scm_out_pop(SCM_BOOL_T); + pzRes = scm_i_string_chars(res); + + /* 13 char prefix is: "content-type:" */ + if (strneqvcmp(pzRes, DO_STDOUT_TPL_CONTENT, 13) != 0) + fputs(DO_STDOUT_TPL_CONTENT, stdout); + + fwrite(pzRes, scm_c_string_length(res), 1, stdout); + } + + fclose(stdout); +} + +/** + * pop the current output spec structure. Deallocate it and the + * file name, too, if necessary. + */ +static out_spec_t * +next_out_spec(out_spec_t * os) +{ + out_spec_t * res = os->os_next; + + if (os->os_dealloc_fmt) + AGFREE(os->os_file_fmt); + + AGFREE(os); + return res; +} + +static void +process_tpl(templ_t * tpl) +{ + /* + * IF the template file does not specify any output suffixes, + * THEN we will generate to standard out with the suffix set to zNoSfx. + * With output going to stdout, we don't try to remove output on errors. + */ + if (output_specs == NULL) { + do_stdout_tpl(tpl); + return; + } + + do { + out_spec_t * os; + + /* + * We cannot be in Scheme processing. We've either just started + * or we've made a long jump from our own code. If we've made a + * long jump, we've printed a message that is sufficient and we + * don't need to print any scheme expressions. + */ + last_scm_cmd = NULL; + + /* + * HOW was that we got here? + */ + switch (setjmp(abort_jmp_buf)) { + case SUCCESS: + os = output_specs; + + if (OPT_VALUE_TRACE >= TRACE_EVERYTHING) { + fprintf(trace_fp, PROC_TPL_START, os->os_sfx); + fflush(trace_fp); + } + /* + * Set the output file name buffer. + * It may get switched inside open_output. + */ + open_output(os); + memcpy(&out_root, cur_fpstack, sizeof(out_root)); + AGFREE(cur_fpstack); + cur_fpstack = &out_root; + curr_sfx = os->os_sfx; + curr_def_ctx = root_def_ctx; + cur_fpstack->stk_flags &= ~FPF_FREE; + cur_fpstack->stk_prev = NULL; + gen_block(tpl, tpl->td_macros, tpl->td_macros+tpl->td_mac_ct); + + do { + out_close(false); /* keep output */ + } while (cur_fpstack->stk_prev != NULL); + + output_specs = next_out_spec(os); + break; + + case PROBLEM: + os = output_specs; + /* + * We got here by a long jump. Close/purge the open files + * and go on to the next output. + */ + do { + out_close(true); /* discard output */ + } while (cur_fpstack->stk_prev != NULL); + last_scm_cmd = NULL; /* "problem" means "drop current output". */ + output_specs = next_out_spec(os); + break; + + default: + fprintf(trace_fp, PROC_TPL_BOGUS_RET, oops_pfx); + oops_pfx = zNil; + /* FALLTHROUGH */ + + case FAILURE: + os = output_specs; + + /* + * We got here by a long jump. Close/purge the open files. + */ + do { + out_close(true); /* discard output */ + } while (cur_fpstack->stk_prev != NULL); + + /* + * On failure (or unknown jump type), we quit the program, too. + */ + processing_state = PROC_STATE_ABORTING; + while (os != NULL) + os = next_out_spec(os); + + exit(EXIT_FAILURE); + /* NOTREACHED */ + } + } while (output_specs != NULL); +} + +static void +set_utime(char const * fname) +{ +#ifdef HAVE_UTIMENSAT + enum { ACCESS_IDX = 0, MODIFY_IDX = 1 }; + struct timespec const times[2] = { + [ACCESS_IDX] = { + .tv_sec = 0, + .tv_nsec = UTIME_OMIT + }, + [MODIFY_IDX] = { + .tv_sec = outfile_time.tv_sec, + .tv_nsec = outfile_time.tv_nsec + } + }; + utimensat(AT_FDCWD, fname, times, 0); + +#else + struct utimbuf const tbuf = { + .actime = time(NULL), + .modtime = outfile_time + }; + + /* + * The putative start time is one second earlier than the + * earliest output file time, regardless of when that is. + */ + if (outfile_time <= start_time) + start_time = outfile_time - 1; + + utime(fname, &tbuf); +#endif +} + +/** + * close current output file + * + * @param purge "true" means the output is to be discarded + * + * Most output files will be set to read only, though that may + * get overridden. If the file name has been allocated, then it + * is also freed. The current output is set to the next in the + * stack. + */ +static void +out_close(bool purge) +{ + if ((cur_fpstack->stk_flags & FPF_NOCHMOD) == 0) + make_readonly(); + + if (OPT_VALUE_TRACE > TRACE_DEBUG_MESSAGE) + fprintf(trace_fp, OUT_CLOSE_TRACE_WRAP, __func__, + cur_fpstack->stk_fname); + + fclose(cur_fpstack->stk_fp); + + /* + * Only stdout and /dev/null are marked, "NOUNLINK" + */ + if ((cur_fpstack->stk_flags & FPF_NOUNLINK) == 0) { + /* + * IF we are told to purge the file OR the file is an AutoGen temp + * file, then get rid of the output. + */ + if (purge || ((cur_fpstack->stk_flags & FPF_UNLINK) != 0)) + unlink(cur_fpstack->stk_fname); + + else + set_utime(cur_fpstack->stk_fname); + } + + /* + * Do not deallocate statically allocated names + */ + if ((cur_fpstack->stk_flags & FPF_STATIC_NM) == 0) + AGFREE(cur_fpstack->stk_fname); + + /* + * Do not deallocate the root entry. It is not allocated!! + */ + if ((cur_fpstack->stk_flags & FPF_FREE) != 0) { + out_stack_t * p = cur_fpstack; + cur_fpstack = p->stk_prev; + AGFREE(p); + } +} + +/** + * Figure out what to use as the base name of the output file. + * If an argument is not provided, we use the base name of + * the definitions file. + */ +static void +open_output(out_spec_t * spec) +{ + static char const write_mode[] = "w" FOPEN_BINARY_FLAG "+"; + + char const * out_file = NULL; + + if (strcmp(spec->os_sfx, OPEN_OUTPUT_NULL) == 0) { + static int const flags = FPF_NOUNLINK | FPF_NOCHMOD | FPF_TEMPFILE; + null_open: + open_output_file(DEV_NULL, DEV_NULL_LEN, write_mode, flags); + return; + } + + /* + * IF we are to skip the current suffix, + * we will redirect the output to /dev/null and + * perform all the work. There may be side effects. + */ + if (HAVE_OPT(SKIP_SUFFIX)) { + int ct = STACKCT_OPT(SKIP_SUFFIX); + const char ** ppz = STACKLST_OPT(SKIP_SUFFIX); + + while (--ct >= 0) { + if (strcmp(spec->os_sfx, *ppz++) == 0) + goto null_open; + } + } + + /* + * Remove any suffixes in the last file name + */ + { + char const * def_file = OPT_ARG(BASE_NAME); + char z[AG_PATH_MAX]; + const char * pst = strrchr(def_file, '/'); + char * end; + + pst = (pst == NULL) ? def_file : (pst + 1); + + /* + * We allow users to specify a suffix with '-' and '_', but when + * stripping a suffix from the "base name", we do not recognize 'em. + */ + end = strchr(pst, '.'); + if (end != NULL) { + size_t len = (unsigned)(end - pst); + if (len >= sizeof(z)) + AG_ABEND(BASE_NAME_TOO_LONG); + + memcpy(z, pst, len); + z[ end - pst ] = NUL; + pst = z; + } + + /* + * Now formulate the output file name in the buffer + * provided as the input argument. + */ + out_file = aprf(spec->os_file_fmt, pst, spec->os_sfx); + if (out_file == NULL) + AG_ABEND(aprf(OPEN_OUTPUT_BAD_FMT, spec->os_file_fmt, pst, + spec->os_sfx)); + } + + open_output_file(out_file, strlen(out_file), write_mode, 0); + free(VOIDP(out_file)); +} +/** + * @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of agen5/tpProcess.c */ diff --git a/autoopts/Makefile.am b/autoopts/Makefile.am new file mode 100644 index 0000000..5562e78 --- /dev/null +++ b/autoopts/Makefile.am @@ -0,0 +1,244 @@ +## -*- Mode: Makefile -*- +## +## Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +BUILT_SOURCES = +MOSTLYCLEANFILES = +libdatadir = $(libdir)/@PACKAGE@ +SUBDIRS = @OPTS_TESTDIR@ +AM_CPPFLAGS = @INCLIST@ +AM_CFLAGS = @WARN_CFLAGS@ +libsrc = libopts-@AO_CURRENT@.@AO_REVISION@.@AO_AGE@.tar.gz +LIBOPTS_VER = @AO_CURRENT@:@AO_REVISION@:@AO_AGE@ + +if NEED_PATHFIND +PATHFIND_MAN = pathfind.3 +else +PATHFIND_MAN = +endif + +MAN_STAMP = man3-stamp +GENTEXI = libopts.texi libopts.menu +TEXI_STAMP = texi-stamp +EXTRA_DIST = +GENMAN = $(PATHFIND_MAN) \ + ao_string_tokenize.3 configFileLoad.3 \ + optionFileLoad.3 optionFindNextValue.3 \ + optionFindValue.3 optionFree.3 \ + optionGetValue.3 optionLoadLine.3 \ + optionMemberList.3 optionNextValue.3 \ + optionOnlyUsage.3 optionPrintVersion.3 \ + optionPrintVersionAndReturn.3 optionProcess.3 \ + optionRestore.3 optionSaveFile.3 \ + optionSaveState.3 optionUnloadNested.3 \ + optionVersion.3 strequate.3 \ + streqvcmp.3 streqvmap.3 \ + strneqvcmp.3 strtransform.3 + +nodist_pkgdata_DATA = $(libsrc) \ + tpl/man2mdoc tpl/man2texi tpl/mdoc2man \ + tpl/mdoc2texi tpl/texi2man tpl/texi2mdoc \ + tpl/tpl-config.tlib + +nodist_libdata_DATA = tpl/tpl-config.tlib + +pkgdata_DATA = \ + autoopts.m4 tpl/aginfo3.tpl tpl/aginfo.tpl \ + tpl/agman1.tpl tpl/agman3.tpl tpl/agman-cmd.tpl \ + tpl/agman-file.tpl tpl/agman.tlib tpl/agmdoc-cmd.tpl \ + tpl/agmdoc-file.tpl tpl/agpl.lic tpl/agtexi-cmd.tpl \ + tpl/agtexi-file.tpl tpl/bits.tpl tpl/cmd-doc.tlib \ + tpl/def2pot.tpl tpl/getopt.tpl tpl/gpl.lic \ + tpl/gplv2.lic tpl/lgpl.lic tpl/lgplv2.lic \ + tpl/mbsd.lic tpl/Mdoc.pm tpl/optcode.tlib \ + tpl/opthead.tlib tpl/options.tpl tpl/optlib.tlib \ + tpl/optmain.tlib tpl/perlopt.tpl tpl/rc-sample.tpl \ + tpl/stdoptions.def tpl/str2enum.tpl tpl/str2init.tlib \ + tpl/str2mask.tpl tpl/strings.tpl tpl/usage.tlib + +EXTRA_DATA = $(pkgdata_DATA) \ + autogen.map autoopts-config.in bootstrap.dir \ + install-hook.sh mk-autoopts-pc.in mk-tpl-config.sh \ + po tpl/man2mdoc.pl tpl/man2texi.sh \ + tpl/mdoc2man.pl tpl/mdoc2texi.pl tpl/texi2man.sh \ + tpl/texi2mdoc.sh tpl/tpl-config-tlib.in + +GENSCRIPTS = $(srcdir)/funcs.def \ + tpl/man2man tpl/man2mdoc tpl/man2texi tpl/mdoc2man tpl/mdoc2mdoc \ + tpl/mdoc2texi tpl/texi2man tpl/texi2mdoc tpl/texi2texi + +EXTRA_DIST += $(top_srcdir)/config/gendocs.sh +EXTRA_DIST += gettext.h +EXTRA_DIST += $(top_srcdir)/config/config.rpath +EXTRA_DIST += intprops.h +EXTRA_DIST += parse-duration.c +EXTRA_DIST += parse-duration.h +# Because this Makefile snippet defines a variable used by other +# gnulib Makefile snippets, it must be present in all makefiles that +# need it. This is ensured by the applicability 'all' defined above. +_NORETURN_H=$(srcdir)/_Noreturn.h +EXTRA_DIST += _Noreturn.h +BUILT_SOURCES += $(STDNORETURN_H) +# We need the following in order to create when the system +# doesn't have one that works. +if GL_GENERATE_STDNORETURN_H +stdnoreturn.h: stdnoreturn.in.h $(top_builddir)/config.status $(_NORETURN_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ + sed -e '/definition of _Noreturn/r $(_NORETURN_H)' \ + < $(srcdir)/stdnoreturn.in.h; \ + } > $@-t && \ + mv $@-t $@ +else +stdnoreturn.h: $(top_builddir)/config.status + rm -f $@ +endif +MOSTLYCLEANFILES += stdnoreturn.h stdnoreturn.h-t +EXTRA_DIST += stdnoreturn.in.h + +GENHDRS = autoopts/options.h autoopts/usage-txt.h genshell.h \ + option-xat-attribute.h option-value-type.h ao-strs.h \ + ag-char-map.h save-flags.h +HDRS = $(GENHDRS) autoopts.h project.h proto.h +GEN_SRC = ao-strs.c option-value-type.c option-xat-attribute.c \ + save-flags.c + +## The primary source (autoopts.c) must be by itself on the first line after +## "CSRC". 'sed' does some magic here to get the list of source files for the +## documentation. Files without documentation are on the CSRC = line. +## +CSRC = parse-duration.c $(GEN_SRC) \ + autoopts.c \ + alias.c boolean.c check.c configfile.c cook.c \ + enum.c env.c file.c find.c genshell.c \ + load.c makeshell.c nested.c numeric.c pgusage.c \ + putshell.c reset.c restore.c save.c sort.c \ + stack.c streqvcmp.c text_mmap.c time.c tokenize.c \ + usage.c version.c init.c + +SRC = $(HDRS) $(CSRC) $(GENSRC) +DEF_FILES = genshell.def $(srcdir)/funcs.def ao-strs.def +pkgconfigdir =$(libdir)/pkgconfig + +## # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +## +## A U T O M A K E V A R S +## +## # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +CLEANFILES = tmp-* libopts.c +DISTCLEANFILES = $(GENMAN) $(GENTEXI) *-stamp +MAINTAINERCLEANFILES = $(GENHDRS) $(GENSRC) $(GENSCRIPTS) +m4datadir = $(datadir)/aclocal + +nodist_libopts_la_SOURCES = libopts.c +libopts_la_SOURCES = $(HDRS) +libopts_la_CFLAGS = -DPKGDATADIR='"$(pkgdatadir)"' $(AM_CFLAGS) +libopts_la_LDFLAGS = -version-info $(LIBOPTS_VER) +libopts_la_LIBADD = $(top_builddir)/snprintfv/libsnprintfv.la + +EXTRA_DIST += $(SRC) $(EXTRA_DATA) $(man_MANS) $(DEF_FILES) + +INST_MANS = autoopts-config.1 $(GENMAN) +INST_PKGCFG = pkgconfig/autoopts.pc +INST_LIBS = libopts.la +INST_HDRS = autoopts/options.h autoopts/usage-txt.h +INST_SH = autoopts-config + +man_MANS = $(INST_MANS) +m4data_DATA = autoopts.m4 +pkgconfig_DATA = $(INST_PKGCFG) +lib_LTLIBRARIES = $(INST_LIBS) +nobase_include_HEADERS = $(INST_HDRS) +bin_SCRIPTS = $(INST_SH) + +BOOTENV = AGexe="$(AGexe)" GDexe="$(GDexe)" CLexe="$(CLexe)" \ + srcdir="$(srcdir)" top_srcdir="$(top_srcdir)" \ + builddir="$(builddir)" top_builddir="$(top_builddir)" \ + AO_AGE="$(AO_AGE)" AO_CURRENT="$(AO_CURRENT)" \ + AO_REVISION="$(AO_REVISION)" POSIX_SHELL="$(POSIX_SHELL)" + +## # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +## +## M A K E F I L E R U L E S +## +## # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +libopts.c : tpl-config-stamp +$(GENSCRIPTS) : tpl-config-stamp + +tpl-config-stamp: $(HDRS) $(CSRC) \ + $(top_builddir)/config.h $(srcdir)/mk-tpl-config.sh + LGCFLAGS="$(GUILE_CFLAGS)" \ + $(BOOTENV) \ + $(POSIX_SHELL) $(srcdir)/mk-tpl-config.sh $@ $(HDRS) $(CSRC) + +makeshell.lo : genshell.c +genshell.c : $(srcdir)/genshell.def + $(BOOTENV) \ + $(POSIX_SHELL) $(srcdir)/bootstrap.dir $@ + +strcspn.lo : $(top_srcdir)/compat/strcspn.c + $(LTCOMPILE) -o $@ -c $(top_srcdir)/compat/strcspn.c + +install-data-local : install-man3 + +$(GENMAN) : $(MAN_STAMP) +$(MAN_STAMP) : $(srcdir)/funcs.def + @test -x ../agen5/autogen || exit 0 ; \ + touch tmp-$@ ; \ + opts='-L$(srcdir)/tpl -L$(builddir)/tpl -Tagman3.tpl' ; \ + echo ! $(AGexe) $${opts} $(srcdir)/funcs.def ; \ + $(AGexe) $${opts} $(srcdir)/funcs.def ; \ + mv -f tmp-$@ $@ + +$(GENTEXI) : $(TEXI_STAMP) +$(TEXI_STAMP) : ../agen5/autogen $(srcdir)/funcs.def + @touch tmp-$@ ; \ + opts='-L$(srcdir)/tpl -L$(builddir)/tpl -Taginfo3.tpl' ; \ + cmd="$(AGexe) $${opts} -DLEVEL=subsection -blibopts" ; \ + cmd="$${cmd} -L$(srcdir) $(srcdir)/funcs.def" ; \ + echo ! $$cmd ; $$cmd ; mv -f tmp-$@ $@ + +libsrc : $(libsrc) +$(libsrc) : + @$(BOOTENV) \ + AO_AGE=@AO_AGE@ AO_CURRENT=@AO_CURRENT@ AO_REVISION=@AO_REVISION@ \ + $(POSIX_SHELL) $(top_srcdir)/pkg/libopts/mklibsrc.sh + +pkgconfig/autoopts.pc : mk-autoopts-pc + $(POSIX_SHELL) mk-autoopts-pc $@ + +install-data-hook: + @DESTdestdir='$(DESTDIR)$(includedir)/autoopts' \ + DESTpkgdatadir='$(DESTDIR)$(pkgdatadir)' \ + DESTlibdatadir='$(DESTDIR)$(pkglibdir)' \ + top_builddir='$(top_builddir)' \ + LIBOPTS_VER='$(LIBOPTS_VER)' \ + POSIX_SHELL='$(POSIX_SHELL)' \ + bindir='$(bindir)' \ + $(POSIX_SHELL) $(srcdir)/install-hook.sh + +.NOTPARALLEL: + +# Makefile.am ends here diff --git a/autoopts/Makefile.in b/autoopts/Makefile.in new file mode 100644 index 0000000..4082dd9 --- /dev/null +++ b/autoopts/Makefile.in @@ -0,0 +1,1323 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 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. + +@SET_MAKE@ + + + + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = autoopts +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/ag_macros.m4 \ + $(top_srcdir)/config/asm-underscore.m4 \ + $(top_srcdir)/config/extensions.m4 \ + $(top_srcdir)/config/guile.m4 \ + $(top_srcdir)/config/host-cpu-c-abi.m4 \ + $(top_srcdir)/config/lib-ld.m4 \ + $(top_srcdir)/config/lib-link.m4 \ + $(top_srcdir)/config/lib-prefix.m4 \ + $(top_srcdir)/config/libopts.m4 \ + $(top_srcdir)/config/libtool.m4 \ + $(top_srcdir)/config/ltoptions.m4 \ + $(top_srcdir)/config/ltsugar.m4 \ + $(top_srcdir)/config/ltversion.m4 \ + $(top_srcdir)/config/lt~obsolete.m4 \ + $(top_srcdir)/config/onceonly.m4 $(top_srcdir)/config/pkg.m4 \ + $(top_srcdir)/config/snprintfv.m4 \ + $(top_srcdir)/config/stdnoreturn.m4 \ + $(top_srcdir)/config/unlocked-io.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(nobase_include_HEADERS) \ + $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = mk-autoopts-pc autoopts-config +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \ + "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man3dir)" \ + "$(DESTDIR)$(m4datadir)" "$(DESTDIR)$(libdatadir)" \ + "$(DESTDIR)$(pkgdatadir)" "$(DESTDIR)$(pkgconfigdir)" \ + "$(DESTDIR)$(pkgdatadir)" "$(DESTDIR)$(includedir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +libopts_la_DEPENDENCIES = $(top_builddir)/snprintfv/libsnprintfv.la +am__objects_1 = +am__objects_2 = $(am__objects_1) +am_libopts_la_OBJECTS = $(am__objects_2) +nodist_libopts_la_OBJECTS = libopts_la-libopts.lo +libopts_la_OBJECTS = $(am_libopts_la_OBJECTS) \ + $(nodist_libopts_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libopts_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libopts_la_CFLAGS) \ + $(CFLAGS) $(libopts_la_LDFLAGS) $(LDFLAGS) -o $@ +SCRIPTS = $(bin_SCRIPTS) +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/config/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/libopts_la-libopts.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libopts_la_SOURCES) $(nodist_libopts_la_SOURCES) +DIST_SOURCES = $(libopts_la_SOURCES) +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +man1dir = $(mandir)/man1 +man3dir = $(mandir)/man3 +NROFF = nroff +MANS = $(man_MANS) +DATA = $(m4data_DATA) $(nodist_libdata_DATA) $(nodist_pkgdata_DATA) \ + $(pkgconfig_DATA) $(pkgdata_DATA) +HEADERS = $(nobase_include_HEADERS) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir distdir-am +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/autoopts-config.in \ + $(srcdir)/mk-autoopts-pc.in $(top_srcdir)/config/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +AGEN5_TESTS = @AGEN5_TESTS@ +AG_LDFLAGS = @AG_LDFLAGS@ +AG_MAJOR_VERSION = @AG_MAJOR_VERSION@ +AG_MINOR_VERSION = @AG_MINOR_VERSION@ +AG_STATIC_AUTOGEN = @AG_STATIC_AUTOGEN@ +AG_TIMEOUT = @AG_TIMEOUT@ +AG_VERSION = @AG_VERSION@ +AG_XML2 = @AG_XML2@ +AGexe = @AGexe@ +AGnam = @AGnam@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AO_AGE = @AO_AGE@ +AO_CURRENT = @AO_CURRENT@ +AO_REVISION = @AO_REVISION@ +AO_TEMPLATE_VERSION = @AO_TEMPLATE_VERSION@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLexe = @CLexe@ +CLnam = @CLnam@ +CONFIG_SHELL = @CONFIG_SHELL@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBUG_ENABLED = @DEBUG_ENABLED@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +DYNAMIC_AG = @DYNAMIC_AG@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_STATIC = @ENABLE_STATIC@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GDexe = @GDexe@ +GDnam = @GDnam@ +GO_AGE = @GO_AGE@ +GO_CURRENT = @GO_CURRENT@ +GO_REVISION = @GO_REVISION@ +GREP = @GREP@ +GUILE_CFLAGS = @GUILE_CFLAGS@ +GUILE_EFFECTIVE_VERSION = @GUILE_EFFECTIVE_VERSION@ +GUILE_LDFLAGS = @GUILE_LDFLAGS@ +GUILE_LIBS = @GUILE_LIBS@ +GUILE_LTLIBS = @GUILE_LTLIBS@ +HOST_CPU = @HOST_CPU@ +HOST_CPU_C_ABI = @HOST_CPU_C_ABI@ +INCLIST = @INCLIST@ +INCSNPRINTFV = @INCSNPRINTFV@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSNPRINTFV = @LIBSNPRINTFV@ +LIBTOOL = @LIBTOOL@ +LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ +LIBXML2_LIBS = @LIBXML2_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +M4_SRC = @M4_SRC@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPTS_TESTDIR = @OPTS_TESTDIR@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSIX_SHELL = @POSIX_SHELL@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STDNORETURN_H = @STDNORETURN_H@ +STRIP = @STRIP@ +TEXI2HTML = @TEXI2HTML@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_aux_dir = @ac_aux_dir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +BUILT_SOURCES = $(STDNORETURN_H) +MOSTLYCLEANFILES = stdnoreturn.h stdnoreturn.h-t +libdatadir = $(libdir)/@PACKAGE@ +SUBDIRS = @OPTS_TESTDIR@ +AM_CPPFLAGS = @INCLIST@ +AM_CFLAGS = @WARN_CFLAGS@ +libsrc = libopts-@AO_CURRENT@.@AO_REVISION@.@AO_AGE@.tar.gz +LIBOPTS_VER = @AO_CURRENT@:@AO_REVISION@:@AO_AGE@ +@NEED_PATHFIND_FALSE@PATHFIND_MAN = +@NEED_PATHFIND_TRUE@PATHFIND_MAN = pathfind.3 +MAN_STAMP = man3-stamp +GENTEXI = libopts.texi libopts.menu +TEXI_STAMP = texi-stamp +EXTRA_DIST = $(top_srcdir)/config/gendocs.sh gettext.h \ + $(top_srcdir)/config/config.rpath intprops.h parse-duration.c \ + parse-duration.h _Noreturn.h stdnoreturn.in.h $(SRC) \ + $(EXTRA_DATA) $(man_MANS) $(DEF_FILES) +GENMAN = $(PATHFIND_MAN) \ + ao_string_tokenize.3 configFileLoad.3 \ + optionFileLoad.3 optionFindNextValue.3 \ + optionFindValue.3 optionFree.3 \ + optionGetValue.3 optionLoadLine.3 \ + optionMemberList.3 optionNextValue.3 \ + optionOnlyUsage.3 optionPrintVersion.3 \ + optionPrintVersionAndReturn.3 optionProcess.3 \ + optionRestore.3 optionSaveFile.3 \ + optionSaveState.3 optionUnloadNested.3 \ + optionVersion.3 strequate.3 \ + streqvcmp.3 streqvmap.3 \ + strneqvcmp.3 strtransform.3 + +nodist_pkgdata_DATA = $(libsrc) \ + tpl/man2mdoc tpl/man2texi tpl/mdoc2man \ + tpl/mdoc2texi tpl/texi2man tpl/texi2mdoc \ + tpl/tpl-config.tlib + +nodist_libdata_DATA = tpl/tpl-config.tlib +pkgdata_DATA = \ + autoopts.m4 tpl/aginfo3.tpl tpl/aginfo.tpl \ + tpl/agman1.tpl tpl/agman3.tpl tpl/agman-cmd.tpl \ + tpl/agman-file.tpl tpl/agman.tlib tpl/agmdoc-cmd.tpl \ + tpl/agmdoc-file.tpl tpl/agpl.lic tpl/agtexi-cmd.tpl \ + tpl/agtexi-file.tpl tpl/bits.tpl tpl/cmd-doc.tlib \ + tpl/def2pot.tpl tpl/getopt.tpl tpl/gpl.lic \ + tpl/gplv2.lic tpl/lgpl.lic tpl/lgplv2.lic \ + tpl/mbsd.lic tpl/Mdoc.pm tpl/optcode.tlib \ + tpl/opthead.tlib tpl/options.tpl tpl/optlib.tlib \ + tpl/optmain.tlib tpl/perlopt.tpl tpl/rc-sample.tpl \ + tpl/stdoptions.def tpl/str2enum.tpl tpl/str2init.tlib \ + tpl/str2mask.tpl tpl/strings.tpl tpl/usage.tlib + +EXTRA_DATA = $(pkgdata_DATA) \ + autogen.map autoopts-config.in bootstrap.dir \ + install-hook.sh mk-autoopts-pc.in mk-tpl-config.sh \ + po tpl/man2mdoc.pl tpl/man2texi.sh \ + tpl/mdoc2man.pl tpl/mdoc2texi.pl tpl/texi2man.sh \ + tpl/texi2mdoc.sh tpl/tpl-config-tlib.in + +GENSCRIPTS = $(srcdir)/funcs.def \ + tpl/man2man tpl/man2mdoc tpl/man2texi tpl/mdoc2man tpl/mdoc2mdoc \ + tpl/mdoc2texi tpl/texi2man tpl/texi2mdoc tpl/texi2texi + +# Because this Makefile snippet defines a variable used by other +# gnulib Makefile snippets, it must be present in all makefiles that +# need it. This is ensured by the applicability 'all' defined above. +_NORETURN_H = $(srcdir)/_Noreturn.h +GENHDRS = autoopts/options.h autoopts/usage-txt.h genshell.h \ + option-xat-attribute.h option-value-type.h ao-strs.h \ + ag-char-map.h save-flags.h + +HDRS = $(GENHDRS) autoopts.h project.h proto.h +GEN_SRC = ao-strs.c option-value-type.c option-xat-attribute.c \ + save-flags.c + +CSRC = parse-duration.c $(GEN_SRC) \ + autoopts.c \ + alias.c boolean.c check.c configfile.c cook.c \ + enum.c env.c file.c find.c genshell.c \ + load.c makeshell.c nested.c numeric.c pgusage.c \ + putshell.c reset.c restore.c save.c sort.c \ + stack.c streqvcmp.c text_mmap.c time.c tokenize.c \ + usage.c version.c init.c + +SRC = $(HDRS) $(CSRC) $(GENSRC) +DEF_FILES = genshell.def $(srcdir)/funcs.def ao-strs.def +pkgconfigdir = $(libdir)/pkgconfig +CLEANFILES = tmp-* libopts.c +DISTCLEANFILES = $(GENMAN) $(GENTEXI) *-stamp +MAINTAINERCLEANFILES = $(GENHDRS) $(GENSRC) $(GENSCRIPTS) +m4datadir = $(datadir)/aclocal +nodist_libopts_la_SOURCES = libopts.c +libopts_la_SOURCES = $(HDRS) +libopts_la_CFLAGS = -DPKGDATADIR='"$(pkgdatadir)"' $(AM_CFLAGS) +libopts_la_LDFLAGS = -version-info $(LIBOPTS_VER) +libopts_la_LIBADD = $(top_builddir)/snprintfv/libsnprintfv.la +INST_MANS = autoopts-config.1 $(GENMAN) +INST_PKGCFG = pkgconfig/autoopts.pc +INST_LIBS = libopts.la +INST_HDRS = autoopts/options.h autoopts/usage-txt.h +INST_SH = autoopts-config +man_MANS = $(INST_MANS) +m4data_DATA = autoopts.m4 +pkgconfig_DATA = $(INST_PKGCFG) +lib_LTLIBRARIES = $(INST_LIBS) +nobase_include_HEADERS = $(INST_HDRS) +bin_SCRIPTS = $(INST_SH) +BOOTENV = AGexe="$(AGexe)" GDexe="$(GDexe)" CLexe="$(CLexe)" \ + srcdir="$(srcdir)" top_srcdir="$(top_srcdir)" \ + builddir="$(builddir)" top_builddir="$(top_builddir)" \ + AO_AGE="$(AO_AGE)" AO_CURRENT="$(AO_CURRENT)" \ + AO_REVISION="$(AO_REVISION)" POSIX_SHELL="$(POSIX_SHELL)" + +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu autoopts/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu autoopts/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +mk-autoopts-pc: $(top_builddir)/config.status $(srcdir)/mk-autoopts-pc.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ +autoopts-config: $(top_builddir)/config.status $(srcdir)/autoopts-config.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ + +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libopts.la: $(libopts_la_OBJECTS) $(libopts_la_DEPENDENCIES) $(EXTRA_libopts_la_DEPENDENCIES) + $(AM_V_CCLD)$(libopts_la_LINK) -rpath $(libdir) $(libopts_la_OBJECTS) $(libopts_la_LIBADD) $(LIBS) +install-binSCRIPTS: $(bin_SCRIPTS) + @$(NORMAL_INSTALL) + @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n' \ + -e 'h;s|.*|.|' \ + -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) { files[d] = files[d] " " $$1; \ + if (++n[d] == $(am__install_max)) { \ + print "f", d, files[d]; n[d] = 0; files[d] = "" } } \ + else { print "f", d "/" $$4, $$1 } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binSCRIPTS: + @$(NORMAL_UNINSTALL) + @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 's,.*/,,;$(transform)'`; \ + dir='$(DESTDIR)$(bindir)'; $(am__uninstall_files_from_dir) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libopts_la-libopts.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +libopts_la-libopts.lo: libopts.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libopts_la_CFLAGS) $(CFLAGS) -MT libopts_la-libopts.lo -MD -MP -MF $(DEPDIR)/libopts_la-libopts.Tpo -c -o libopts_la-libopts.lo `test -f 'libopts.c' || echo '$(srcdir)/'`libopts.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libopts_la-libopts.Tpo $(DEPDIR)/libopts_la-libopts.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='libopts.c' object='libopts_la-libopts.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libopts_la_CFLAGS) $(CFLAGS) -c -o libopts_la-libopts.lo `test -f 'libopts.c' || echo '$(srcdir)/'`libopts.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-man1: $(man_MANS) + @$(NORMAL_INSTALL) + @list1=''; \ + list2='$(man_MANS)'; \ + test -n "$(man1dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.1[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ + done; } + +uninstall-man1: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man1dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.1[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) +install-man3: $(man_MANS) + @$(NORMAL_INSTALL) + @list1=''; \ + list2='$(man_MANS)'; \ + test -n "$(man3dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man3dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man3dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.3[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man3dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man3dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man3dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man3dir)" || exit $$?; }; \ + done; } + +uninstall-man3: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man3dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.3[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man3dir)'; $(am__uninstall_files_from_dir) +install-m4dataDATA: $(m4data_DATA) + @$(NORMAL_INSTALL) + @list='$(m4data_DATA)'; test -n "$(m4datadir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(m4datadir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(m4datadir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(m4datadir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(m4datadir)" || exit $$?; \ + done + +uninstall-m4dataDATA: + @$(NORMAL_UNINSTALL) + @list='$(m4data_DATA)'; test -n "$(m4datadir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(m4datadir)'; $(am__uninstall_files_from_dir) +install-nodist_libdataDATA: $(nodist_libdata_DATA) + @$(NORMAL_INSTALL) + @list='$(nodist_libdata_DATA)'; test -n "$(libdatadir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(libdatadir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libdatadir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(libdatadir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(libdatadir)" || exit $$?; \ + done + +uninstall-nodist_libdataDATA: + @$(NORMAL_UNINSTALL) + @list='$(nodist_libdata_DATA)'; test -n "$(libdatadir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(libdatadir)'; $(am__uninstall_files_from_dir) +install-nodist_pkgdataDATA: $(nodist_pkgdata_DATA) + @$(NORMAL_INSTALL) + @list='$(nodist_pkgdata_DATA)'; test -n "$(pkgdatadir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkgdatadir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkgdatadir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgdatadir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgdatadir)" || exit $$?; \ + done + +uninstall-nodist_pkgdataDATA: + @$(NORMAL_UNINSTALL) + @list='$(nodist_pkgdata_DATA)'; test -n "$(pkgdatadir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkgdatadir)'; $(am__uninstall_files_from_dir) +install-pkgconfigDATA: $(pkgconfig_DATA) + @$(NORMAL_INSTALL) + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkgconfigdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \ + done + +uninstall-pkgconfigDATA: + @$(NORMAL_UNINSTALL) + @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) +install-pkgdataDATA: $(pkgdata_DATA) + @$(NORMAL_INSTALL) + @list='$(pkgdata_DATA)'; test -n "$(pkgdatadir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pkgdatadir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pkgdatadir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgdatadir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgdatadir)" || exit $$?; \ + done + +uninstall-pkgdataDATA: + @$(NORMAL_UNINSTALL) + @list='$(pkgdata_DATA)'; test -n "$(pkgdatadir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(pkgdatadir)'; $(am__uninstall_files_from_dir) +install-nobase_includeHEADERS: $(nobase_include_HEADERS) + @$(NORMAL_INSTALL) + @list='$(nobase_include_HEADERS)'; test -n "$(includedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \ + fi; \ + $(am__nobase_list) | while read dir files; do \ + xfiles=; for file in $$files; do \ + if test -f "$$file"; then xfiles="$$xfiles $$file"; \ + else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ + test -z "$$xfiles" || { \ + test "x$$dir" = x. || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(includedir)/$$dir'"; \ + $(MKDIR_P) "$(DESTDIR)$(includedir)/$$dir"; }; \ + echo " $(INSTALL_HEADER) $$xfiles '$(DESTDIR)$(includedir)/$$dir'"; \ + $(INSTALL_HEADER) $$xfiles "$(DESTDIR)$(includedir)/$$dir" || exit $$?; }; \ + done + +uninstall-nobase_includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(nobase_include_HEADERS)'; test -n "$(includedir)" || list=; \ + $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ + dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) + +# 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. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-recursive +all-am: Makefile $(LTLIBRARIES) $(SCRIPTS) $(MANS) $(DATA) $(HEADERS) +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man3dir)" "$(DESTDIR)$(m4datadir)" "$(DESTDIR)$(libdatadir)" "$(DESTDIR)$(pkgdatadir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(pkgdatadir)" "$(DESTDIR)$(includedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES) + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-recursive + +clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ + mostlyclean-am + +distclean: distclean-recursive + -rm -f ./$(DEPDIR)/libopts_la-libopts.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: install-data-local install-m4dataDATA install-man \ + install-nobase_includeHEADERS install-nodist_libdataDATA \ + install-nodist_pkgdataDATA install-pkgconfigDATA \ + install-pkgdataDATA + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-data-hook +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: install-binSCRIPTS install-libLTLIBRARIES + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: install-man1 install-man3 + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f ./$(DEPDIR)/libopts_la-libopts.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-binSCRIPTS uninstall-libLTLIBRARIES \ + uninstall-m4dataDATA uninstall-man \ + uninstall-nobase_includeHEADERS uninstall-nodist_libdataDATA \ + uninstall-nodist_pkgdataDATA uninstall-pkgconfigDATA \ + uninstall-pkgdataDATA + +uninstall-man: uninstall-man1 uninstall-man3 + +.MAKE: $(am__recursive_targets) all check install install-am \ + install-data-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ + am--depfiles check check-am clean clean-generic \ + clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-binSCRIPTS \ + install-data install-data-am install-data-hook \ + install-data-local install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-libLTLIBRARIES install-m4dataDATA \ + install-man install-man1 install-man3 \ + install-nobase_includeHEADERS install-nodist_libdataDATA \ + install-nodist_pkgdataDATA install-pdf install-pdf-am \ + install-pkgconfigDATA install-pkgdataDATA install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am uninstall-binSCRIPTS \ + uninstall-libLTLIBRARIES uninstall-m4dataDATA uninstall-man \ + uninstall-man1 uninstall-man3 uninstall-nobase_includeHEADERS \ + uninstall-nodist_libdataDATA uninstall-nodist_pkgdataDATA \ + uninstall-pkgconfigDATA uninstall-pkgdataDATA + +.PRECIOUS: Makefile + +# We need the following in order to create when the system +# doesn't have one that works. +@GL_GENERATE_STDNORETURN_H_TRUE@stdnoreturn.h: stdnoreturn.in.h $(top_builddir)/config.status $(_NORETURN_H) +@GL_GENERATE_STDNORETURN_H_TRUE@ $(AM_V_GEN)rm -f $@-t $@ && \ +@GL_GENERATE_STDNORETURN_H_TRUE@ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ +@GL_GENERATE_STDNORETURN_H_TRUE@ sed -e '/definition of _Noreturn/r $(_NORETURN_H)' \ +@GL_GENERATE_STDNORETURN_H_TRUE@ < $(srcdir)/stdnoreturn.in.h; \ +@GL_GENERATE_STDNORETURN_H_TRUE@ } > $@-t && \ +@GL_GENERATE_STDNORETURN_H_TRUE@ mv $@-t $@ +@GL_GENERATE_STDNORETURN_H_FALSE@stdnoreturn.h: $(top_builddir)/config.status +@GL_GENERATE_STDNORETURN_H_FALSE@ rm -f $@ + +libopts.c : tpl-config-stamp +$(GENSCRIPTS) : tpl-config-stamp + +tpl-config-stamp: $(HDRS) $(CSRC) \ + $(top_builddir)/config.h $(srcdir)/mk-tpl-config.sh + LGCFLAGS="$(GUILE_CFLAGS)" \ + $(BOOTENV) \ + $(POSIX_SHELL) $(srcdir)/mk-tpl-config.sh $@ $(HDRS) $(CSRC) + +makeshell.lo : genshell.c +genshell.c : $(srcdir)/genshell.def + $(BOOTENV) \ + $(POSIX_SHELL) $(srcdir)/bootstrap.dir $@ + +strcspn.lo : $(top_srcdir)/compat/strcspn.c + $(LTCOMPILE) -o $@ -c $(top_srcdir)/compat/strcspn.c + +install-data-local : install-man3 + +$(GENMAN) : $(MAN_STAMP) +$(MAN_STAMP) : $(srcdir)/funcs.def + @test -x ../agen5/autogen || exit 0 ; \ + touch tmp-$@ ; \ + opts='-L$(srcdir)/tpl -L$(builddir)/tpl -Tagman3.tpl' ; \ + echo ! $(AGexe) $${opts} $(srcdir)/funcs.def ; \ + $(AGexe) $${opts} $(srcdir)/funcs.def ; \ + mv -f tmp-$@ $@ + +$(GENTEXI) : $(TEXI_STAMP) +$(TEXI_STAMP) : ../agen5/autogen $(srcdir)/funcs.def + @touch tmp-$@ ; \ + opts='-L$(srcdir)/tpl -L$(builddir)/tpl -Taginfo3.tpl' ; \ + cmd="$(AGexe) $${opts} -DLEVEL=subsection -blibopts" ; \ + cmd="$${cmd} -L$(srcdir) $(srcdir)/funcs.def" ; \ + echo ! $$cmd ; $$cmd ; mv -f tmp-$@ $@ + +libsrc : $(libsrc) +$(libsrc) : + @$(BOOTENV) \ + AO_AGE=@AO_AGE@ AO_CURRENT=@AO_CURRENT@ AO_REVISION=@AO_REVISION@ \ + $(POSIX_SHELL) $(top_srcdir)/pkg/libopts/mklibsrc.sh + +pkgconfig/autoopts.pc : mk-autoopts-pc + $(POSIX_SHELL) mk-autoopts-pc $@ + +install-data-hook: + @DESTdestdir='$(DESTDIR)$(includedir)/autoopts' \ + DESTpkgdatadir='$(DESTDIR)$(pkgdatadir)' \ + DESTlibdatadir='$(DESTDIR)$(pkglibdir)' \ + top_builddir='$(top_builddir)' \ + LIBOPTS_VER='$(LIBOPTS_VER)' \ + POSIX_SHELL='$(POSIX_SHELL)' \ + bindir='$(bindir)' \ + $(POSIX_SHELL) $(srcdir)/install-hook.sh + +.NOTPARALLEL: + +# Makefile.am ends here + +# 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/autoopts/_Noreturn.h b/autoopts/_Noreturn.h new file mode 100644 index 0000000..c44ad89 --- /dev/null +++ b/autoopts/_Noreturn.h @@ -0,0 +1,10 @@ +#if !defined _Noreturn && __STDC_VERSION__ < 201112 +# if (3 <= __GNUC__ || (__GNUC__ == 2 && 8 <= __GNUC_MINOR__) \ + || 0x5110 <= __SUNPRO_C) +# define _Noreturn __attribute__ ((__noreturn__)) +# elif 1200 <= _MSC_VER +# define _Noreturn __declspec (noreturn) +# else +# define _Noreturn +# endif +#endif diff --git a/autoopts/ag-char-map.h b/autoopts/ag-char-map.h new file mode 100644 index 0000000..cced230 --- /dev/null +++ b/autoopts/ag-char-map.h @@ -0,0 +1,526 @@ +/* + * 29 bits for 46 character classifications + * generated by char-mapper on 08/26/18 at 10:44:22 + * + * This file contains the character classifications + * used by AutoGen and AutoOpts for identifying tokens. + * The table is static scope, so %guard is empty. + * + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ +#ifndef AG_CHAR_MAP_H_GUARD +#define AG_CHAR_MAP_H_GUARD 1 + +#ifdef HAVE_CONFIG_H +# if defined(HAVE_INTTYPES_H) +# include + +# elif defined(HAVE_STDINT_H) +# include + +# elif !defined(HAVE_UINT32_T) +# if SIZEOF_INT == 4 + typedef unsigned int uint32_t; +# elif SIZEOF_LONG == 4 + typedef unsigned long uint32_t; +# endif +# endif /* HAVE_*INT*_H header */ + +#else /* not HAVE_CONFIG_H -- */ +# include +#endif /* HAVE_CONFIG_H */ + +#if 0 /* mapping specification source (from autogen.map) */ +// +// %guard +// %file ag-char-map.h +// %backup +// %optimize +// +// %comment -- see above +// % +// +// newline "\n" +// nul-byte "\x00" +// dir-sep "/\\" +// percent "%" +// comma "," +// colon ":" +// underscore "_" +// plus "+" +// dollar "$" +// option-marker "-" +// +// horiz-white "\t " +// alt-white "\v\f\r\b" +// whitespace +horiz-white +newline +alt-white +// non-nl-white +horiz-white +alt-white +// quote "'\"" +// parentheses "()" +// +// graphic "!-~" +// inversion "~-" +// oct-digit "0-7" +// dec-digit "89" +oct-digit +// hex-digit "a-fA-F" +dec-digit +// lower-case "a-z" +// upper-case "A-Z" +// alphabetic +lower-case +upper-case +// alphanumeric +alphabetic +dec-digit +// var-first +underscore +alphabetic +// variable-name +var-first +dec-digit +// option-name "^-" +variable-name +// value-name +colon +option-name +// name-sep "[.]" +// compound-name +value-name +name-sep +horiz-white +// scheme-note +parentheses +quote +// +// unquotable "!-~" -"#,;<=>[\\]`{}?*" -quote -parentheses +// end-xml-token "/>" +whitespace +// plus-n-space +plus +whitespace +// punctuation "!-~" -alphanumeric -"_" +// suffix "-._" +alphanumeric +// suffix-fmt +percent +suffix +dir-sep +// false-type "nNfF0" +nul-byte +// file-name +dir-sep +suffix +// end-token +nul-byte +whitespace +// end-list-entry +comma +end-token +// set-separator "|+-!" +end-list-entry +// signed-number +inversion +dec-digit +// make-script +dollar +newline +// load-line-skip +horiz-white +option-marker +// +#endif /* 0 -- mapping spec. source */ + + +typedef uint32_t ag_char_map_mask_t; + +#define IS_NEWLINE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000001) +#define SPN_NEWLINE_CHARS(_s) spn_ag_char_map_chars(_s, 0) +#define BRK_NEWLINE_CHARS(_s) brk_ag_char_map_chars(_s, 0) +#define SPN_NEWLINE_BACK(s,e) spn_ag_char_map_back(s, e, 0) +#define BRK_NEWLINE_BACK(s,e) brk_ag_char_map_back(s, e, 0) +#define IS_NUL_BYTE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000002) +#define SPN_NUL_BYTE_CHARS(_s) spn_ag_char_map_chars(_s, 1) +#define BRK_NUL_BYTE_CHARS(_s) brk_ag_char_map_chars(_s, 1) +#define SPN_NUL_BYTE_BACK(s,e) spn_ag_char_map_back(s, e, 1) +#define BRK_NUL_BYTE_BACK(s,e) brk_ag_char_map_back(s, e, 1) +#define IS_DIR_SEP_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000004) +#define SPN_DIR_SEP_CHARS(_s) spn_ag_char_map_chars(_s, 2) +#define BRK_DIR_SEP_CHARS(_s) brk_ag_char_map_chars(_s, 2) +#define SPN_DIR_SEP_BACK(s,e) spn_ag_char_map_back(s, e, 2) +#define BRK_DIR_SEP_BACK(s,e) brk_ag_char_map_back(s, e, 2) +#define IS_PERCENT_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000008) +#define SPN_PERCENT_CHARS(_s) spn_ag_char_map_chars(_s, 3) +#define BRK_PERCENT_CHARS(_s) brk_ag_char_map_chars(_s, 3) +#define SPN_PERCENT_BACK(s,e) spn_ag_char_map_back(s, e, 3) +#define BRK_PERCENT_BACK(s,e) brk_ag_char_map_back(s, e, 3) +#define IS_COMMA_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000010) +#define SPN_COMMA_CHARS(_s) spn_ag_char_map_chars(_s, 4) +#define BRK_COMMA_CHARS(_s) brk_ag_char_map_chars(_s, 4) +#define SPN_COMMA_BACK(s,e) spn_ag_char_map_back(s, e, 4) +#define BRK_COMMA_BACK(s,e) brk_ag_char_map_back(s, e, 4) +#define IS_COLON_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000020) +#define SPN_COLON_CHARS(_s) spn_ag_char_map_chars(_s, 5) +#define BRK_COLON_CHARS(_s) brk_ag_char_map_chars(_s, 5) +#define SPN_COLON_BACK(s,e) spn_ag_char_map_back(s, e, 5) +#define BRK_COLON_BACK(s,e) brk_ag_char_map_back(s, e, 5) +#define IS_UNDERSCORE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000040) +#define SPN_UNDERSCORE_CHARS(_s) spn_ag_char_map_chars(_s, 6) +#define BRK_UNDERSCORE_CHARS(_s) brk_ag_char_map_chars(_s, 6) +#define SPN_UNDERSCORE_BACK(s,e) spn_ag_char_map_back(s, e, 6) +#define BRK_UNDERSCORE_BACK(s,e) brk_ag_char_map_back(s, e, 6) +#define IS_PLUS_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000080) +#define SPN_PLUS_CHARS(_s) spn_ag_char_map_chars(_s, 7) +#define BRK_PLUS_CHARS(_s) brk_ag_char_map_chars(_s, 7) +#define SPN_PLUS_BACK(s,e) spn_ag_char_map_back(s, e, 7) +#define BRK_PLUS_BACK(s,e) brk_ag_char_map_back(s, e, 7) +#define IS_DOLLAR_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000100) +#define SPN_DOLLAR_CHARS(_s) spn_ag_char_map_chars(_s, 8) +#define BRK_DOLLAR_CHARS(_s) brk_ag_char_map_chars(_s, 8) +#define SPN_DOLLAR_BACK(s,e) spn_ag_char_map_back(s, e, 8) +#define BRK_DOLLAR_BACK(s,e) brk_ag_char_map_back(s, e, 8) +#define IS_OPTION_MARKER_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000200) +#define SPN_OPTION_MARKER_CHARS(_s) spn_ag_char_map_chars(_s, 9) +#define BRK_OPTION_MARKER_CHARS(_s) brk_ag_char_map_chars(_s, 9) +#define SPN_OPTION_MARKER_BACK(s,e) spn_ag_char_map_back(s, e, 9) +#define BRK_OPTION_MARKER_BACK(s,e) brk_ag_char_map_back(s, e, 9) +#define IS_HORIZ_WHITE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000400) +#define SPN_HORIZ_WHITE_CHARS(_s) spn_ag_char_map_chars(_s, 10) +#define BRK_HORIZ_WHITE_CHARS(_s) brk_ag_char_map_chars(_s, 10) +#define SPN_HORIZ_WHITE_BACK(s,e) spn_ag_char_map_back(s, e, 10) +#define BRK_HORIZ_WHITE_BACK(s,e) brk_ag_char_map_back(s, e, 10) +#define IS_ALT_WHITE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000800) +#define SPN_ALT_WHITE_CHARS(_s) spn_ag_char_map_chars(_s, 11) +#define BRK_ALT_WHITE_CHARS(_s) brk_ag_char_map_chars(_s, 11) +#define SPN_ALT_WHITE_BACK(s,e) spn_ag_char_map_back(s, e, 11) +#define BRK_ALT_WHITE_BACK(s,e) brk_ag_char_map_back(s, e, 11) +#define IS_WHITESPACE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000C01) +#define SPN_WHITESPACE_CHARS(_s) spn_ag_char_map_chars(_s, 12) +#define BRK_WHITESPACE_CHARS(_s) brk_ag_char_map_chars(_s, 12) +#define SPN_WHITESPACE_BACK(s,e) spn_ag_char_map_back(s, e, 12) +#define BRK_WHITESPACE_BACK(s,e) brk_ag_char_map_back(s, e, 12) +#define IS_NON_NL_WHITE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000C00) +#define SPN_NON_NL_WHITE_CHARS(_s) spn_ag_char_map_chars(_s, 13) +#define BRK_NON_NL_WHITE_CHARS(_s) brk_ag_char_map_chars(_s, 13) +#define SPN_NON_NL_WHITE_BACK(s,e) spn_ag_char_map_back(s, e, 13) +#define BRK_NON_NL_WHITE_BACK(s,e) brk_ag_char_map_back(s, e, 13) +#define IS_QUOTE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00001000) +#define SPN_QUOTE_CHARS(_s) spn_ag_char_map_chars(_s, 14) +#define BRK_QUOTE_CHARS(_s) brk_ag_char_map_chars(_s, 14) +#define SPN_QUOTE_BACK(s,e) spn_ag_char_map_back(s, e, 14) +#define BRK_QUOTE_BACK(s,e) brk_ag_char_map_back(s, e, 14) +#define IS_PARENTHESES_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00002000) +#define SPN_PARENTHESES_CHARS(_s) spn_ag_char_map_chars(_s, 15) +#define BRK_PARENTHESES_CHARS(_s) brk_ag_char_map_chars(_s, 15) +#define SPN_PARENTHESES_BACK(s,e) spn_ag_char_map_back(s, e, 15) +#define BRK_PARENTHESES_BACK(s,e) brk_ag_char_map_back(s, e, 15) +#define IS_GRAPHIC_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00004000) +#define SPN_GRAPHIC_CHARS(_s) spn_ag_char_map_chars(_s, 16) +#define BRK_GRAPHIC_CHARS(_s) brk_ag_char_map_chars(_s, 16) +#define SPN_GRAPHIC_BACK(s,e) spn_ag_char_map_back(s, e, 16) +#define BRK_GRAPHIC_BACK(s,e) brk_ag_char_map_back(s, e, 16) +#define IS_INVERSION_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00008000) +#define SPN_INVERSION_CHARS(_s) spn_ag_char_map_chars(_s, 17) +#define BRK_INVERSION_CHARS(_s) brk_ag_char_map_chars(_s, 17) +#define SPN_INVERSION_BACK(s,e) spn_ag_char_map_back(s, e, 17) +#define BRK_INVERSION_BACK(s,e) brk_ag_char_map_back(s, e, 17) +#define IS_OCT_DIGIT_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00010000) +#define SPN_OCT_DIGIT_CHARS(_s) spn_ag_char_map_chars(_s, 18) +#define BRK_OCT_DIGIT_CHARS(_s) brk_ag_char_map_chars(_s, 18) +#define SPN_OCT_DIGIT_BACK(s,e) spn_ag_char_map_back(s, e, 18) +#define BRK_OCT_DIGIT_BACK(s,e) brk_ag_char_map_back(s, e, 18) +#define IS_DEC_DIGIT_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00030000) +#define SPN_DEC_DIGIT_CHARS(_s) spn_ag_char_map_chars(_s, 19) +#define BRK_DEC_DIGIT_CHARS(_s) brk_ag_char_map_chars(_s, 19) +#define SPN_DEC_DIGIT_BACK(s,e) spn_ag_char_map_back(s, e, 19) +#define BRK_DEC_DIGIT_BACK(s,e) brk_ag_char_map_back(s, e, 19) +#define IS_HEX_DIGIT_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00070000) +#define SPN_HEX_DIGIT_CHARS(_s) spn_ag_char_map_chars(_s, 20) +#define BRK_HEX_DIGIT_CHARS(_s) brk_ag_char_map_chars(_s, 20) +#define SPN_HEX_DIGIT_BACK(s,e) spn_ag_char_map_back(s, e, 20) +#define BRK_HEX_DIGIT_BACK(s,e) brk_ag_char_map_back(s, e, 20) +#define IS_LOWER_CASE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00080000) +#define SPN_LOWER_CASE_CHARS(_s) spn_ag_char_map_chars(_s, 21) +#define BRK_LOWER_CASE_CHARS(_s) brk_ag_char_map_chars(_s, 21) +#define SPN_LOWER_CASE_BACK(s,e) spn_ag_char_map_back(s, e, 21) +#define BRK_LOWER_CASE_BACK(s,e) brk_ag_char_map_back(s, e, 21) +#define IS_UPPER_CASE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00100000) +#define SPN_UPPER_CASE_CHARS(_s) spn_ag_char_map_chars(_s, 22) +#define BRK_UPPER_CASE_CHARS(_s) brk_ag_char_map_chars(_s, 22) +#define SPN_UPPER_CASE_BACK(s,e) spn_ag_char_map_back(s, e, 22) +#define BRK_UPPER_CASE_BACK(s,e) brk_ag_char_map_back(s, e, 22) +#define IS_ALPHABETIC_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00180000) +#define SPN_ALPHABETIC_CHARS(_s) spn_ag_char_map_chars(_s, 23) +#define BRK_ALPHABETIC_CHARS(_s) brk_ag_char_map_chars(_s, 23) +#define SPN_ALPHABETIC_BACK(s,e) spn_ag_char_map_back(s, e, 23) +#define BRK_ALPHABETIC_BACK(s,e) brk_ag_char_map_back(s, e, 23) +#define IS_ALPHANUMERIC_CHAR( _c) is_ag_char_map_char((char)(_c), 0x001B0000) +#define SPN_ALPHANUMERIC_CHARS(_s) spn_ag_char_map_chars(_s, 24) +#define BRK_ALPHANUMERIC_CHARS(_s) brk_ag_char_map_chars(_s, 24) +#define SPN_ALPHANUMERIC_BACK(s,e) spn_ag_char_map_back(s, e, 24) +#define BRK_ALPHANUMERIC_BACK(s,e) brk_ag_char_map_back(s, e, 24) +#define IS_VAR_FIRST_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00180040) +#define SPN_VAR_FIRST_CHARS(_s) spn_ag_char_map_chars(_s, 25) +#define BRK_VAR_FIRST_CHARS(_s) brk_ag_char_map_chars(_s, 25) +#define SPN_VAR_FIRST_BACK(s,e) spn_ag_char_map_back(s, e, 25) +#define BRK_VAR_FIRST_BACK(s,e) brk_ag_char_map_back(s, e, 25) +#define IS_VARIABLE_NAME_CHAR( _c) is_ag_char_map_char((char)(_c), 0x001B0040) +#define SPN_VARIABLE_NAME_CHARS(_s) spn_ag_char_map_chars(_s, 26) +#define BRK_VARIABLE_NAME_CHARS(_s) brk_ag_char_map_chars(_s, 26) +#define SPN_VARIABLE_NAME_BACK(s,e) spn_ag_char_map_back(s, e, 26) +#define BRK_VARIABLE_NAME_BACK(s,e) brk_ag_char_map_back(s, e, 26) +#define IS_OPTION_NAME_CHAR( _c) is_ag_char_map_char((char)(_c), 0x003B0040) +#define SPN_OPTION_NAME_CHARS(_s) spn_ag_char_map_chars(_s, 27) +#define BRK_OPTION_NAME_CHARS(_s) brk_ag_char_map_chars(_s, 27) +#define SPN_OPTION_NAME_BACK(s,e) spn_ag_char_map_back(s, e, 27) +#define BRK_OPTION_NAME_BACK(s,e) brk_ag_char_map_back(s, e, 27) +#define IS_VALUE_NAME_CHAR( _c) is_ag_char_map_char((char)(_c), 0x003B0060) +#define SPN_VALUE_NAME_CHARS(_s) spn_ag_char_map_chars(_s, 28) +#define BRK_VALUE_NAME_CHARS(_s) brk_ag_char_map_chars(_s, 28) +#define SPN_VALUE_NAME_BACK(s,e) spn_ag_char_map_back(s, e, 28) +#define BRK_VALUE_NAME_BACK(s,e) brk_ag_char_map_back(s, e, 28) +#define IS_NAME_SEP_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00400000) +#define SPN_NAME_SEP_CHARS(_s) spn_ag_char_map_chars(_s, 29) +#define BRK_NAME_SEP_CHARS(_s) brk_ag_char_map_chars(_s, 29) +#define SPN_NAME_SEP_BACK(s,e) spn_ag_char_map_back(s, e, 29) +#define BRK_NAME_SEP_BACK(s,e) brk_ag_char_map_back(s, e, 29) +#define IS_COMPOUND_NAME_CHAR( _c) is_ag_char_map_char((char)(_c), 0x007B0460) +#define SPN_COMPOUND_NAME_CHARS(_s) spn_ag_char_map_chars(_s, 30) +#define BRK_COMPOUND_NAME_CHARS(_s) brk_ag_char_map_chars(_s, 30) +#define SPN_COMPOUND_NAME_BACK(s,e) spn_ag_char_map_back(s, e, 30) +#define BRK_COMPOUND_NAME_BACK(s,e) brk_ag_char_map_back(s, e, 30) +#define IS_SCHEME_NOTE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00003000) +#define SPN_SCHEME_NOTE_CHARS(_s) spn_ag_char_map_chars(_s, 31) +#define BRK_SCHEME_NOTE_CHARS(_s) brk_ag_char_map_chars(_s, 31) +#define SPN_SCHEME_NOTE_BACK(s,e) spn_ag_char_map_back(s, e, 31) +#define BRK_SCHEME_NOTE_BACK(s,e) brk_ag_char_map_back(s, e, 31) +#define IS_UNQUOTABLE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00800000) +#define SPN_UNQUOTABLE_CHARS(_s) spn_ag_char_map_chars(_s, 32) +#define BRK_UNQUOTABLE_CHARS(_s) brk_ag_char_map_chars(_s, 32) +#define SPN_UNQUOTABLE_BACK(s,e) spn_ag_char_map_back(s, e, 32) +#define BRK_UNQUOTABLE_BACK(s,e) brk_ag_char_map_back(s, e, 32) +#define IS_END_XML_TOKEN_CHAR( _c) is_ag_char_map_char((char)(_c), 0x01000C01) +#define SPN_END_XML_TOKEN_CHARS(_s) spn_ag_char_map_chars(_s, 33) +#define BRK_END_XML_TOKEN_CHARS(_s) brk_ag_char_map_chars(_s, 33) +#define SPN_END_XML_TOKEN_BACK(s,e) spn_ag_char_map_back(s, e, 33) +#define BRK_END_XML_TOKEN_BACK(s,e) brk_ag_char_map_back(s, e, 33) +#define IS_PLUS_N_SPACE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000C81) +#define SPN_PLUS_N_SPACE_CHARS(_s) spn_ag_char_map_chars(_s, 34) +#define BRK_PLUS_N_SPACE_CHARS(_s) brk_ag_char_map_chars(_s, 34) +#define SPN_PLUS_N_SPACE_BACK(s,e) spn_ag_char_map_back(s, e, 34) +#define BRK_PLUS_N_SPACE_BACK(s,e) brk_ag_char_map_back(s, e, 34) +#define IS_PUNCTUATION_CHAR( _c) is_ag_char_map_char((char)(_c), 0x02000000) +#define SPN_PUNCTUATION_CHARS(_s) spn_ag_char_map_chars(_s, 35) +#define BRK_PUNCTUATION_CHARS(_s) brk_ag_char_map_chars(_s, 35) +#define SPN_PUNCTUATION_BACK(s,e) spn_ag_char_map_back(s, e, 35) +#define BRK_PUNCTUATION_BACK(s,e) brk_ag_char_map_back(s, e, 35) +#define IS_SUFFIX_CHAR( _c) is_ag_char_map_char((char)(_c), 0x041B0000) +#define SPN_SUFFIX_CHARS(_s) spn_ag_char_map_chars(_s, 36) +#define BRK_SUFFIX_CHARS(_s) brk_ag_char_map_chars(_s, 36) +#define SPN_SUFFIX_BACK(s,e) spn_ag_char_map_back(s, e, 36) +#define BRK_SUFFIX_BACK(s,e) brk_ag_char_map_back(s, e, 36) +#define IS_SUFFIX_FMT_CHAR( _c) is_ag_char_map_char((char)(_c), 0x041B000C) +#define SPN_SUFFIX_FMT_CHARS(_s) spn_ag_char_map_chars(_s, 37) +#define BRK_SUFFIX_FMT_CHARS(_s) brk_ag_char_map_chars(_s, 37) +#define SPN_SUFFIX_FMT_BACK(s,e) spn_ag_char_map_back(s, e, 37) +#define BRK_SUFFIX_FMT_BACK(s,e) brk_ag_char_map_back(s, e, 37) +#define IS_FALSE_TYPE_CHAR( _c) is_ag_char_map_char((char)(_c), 0x08000002) +#define SPN_FALSE_TYPE_CHARS(_s) spn_ag_char_map_chars(_s, 38) +#define BRK_FALSE_TYPE_CHARS(_s) brk_ag_char_map_chars(_s, 38) +#define SPN_FALSE_TYPE_BACK(s,e) spn_ag_char_map_back(s, e, 38) +#define BRK_FALSE_TYPE_BACK(s,e) brk_ag_char_map_back(s, e, 38) +#define IS_FILE_NAME_CHAR( _c) is_ag_char_map_char((char)(_c), 0x041B0004) +#define SPN_FILE_NAME_CHARS(_s) spn_ag_char_map_chars(_s, 39) +#define BRK_FILE_NAME_CHARS(_s) brk_ag_char_map_chars(_s, 39) +#define SPN_FILE_NAME_BACK(s,e) spn_ag_char_map_back(s, e, 39) +#define BRK_FILE_NAME_BACK(s,e) brk_ag_char_map_back(s, e, 39) +#define IS_END_TOKEN_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000C03) +#define SPN_END_TOKEN_CHARS(_s) spn_ag_char_map_chars(_s, 40) +#define BRK_END_TOKEN_CHARS(_s) brk_ag_char_map_chars(_s, 40) +#define SPN_END_TOKEN_BACK(s,e) spn_ag_char_map_back(s, e, 40) +#define BRK_END_TOKEN_BACK(s,e) brk_ag_char_map_back(s, e, 40) +#define IS_END_LIST_ENTRY_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000C13) +#define SPN_END_LIST_ENTRY_CHARS(_s) spn_ag_char_map_chars(_s, 41) +#define BRK_END_LIST_ENTRY_CHARS(_s) brk_ag_char_map_chars(_s, 41) +#define SPN_END_LIST_ENTRY_BACK(s,e) spn_ag_char_map_back(s, e, 41) +#define BRK_END_LIST_ENTRY_BACK(s,e) brk_ag_char_map_back(s, e, 41) +#define IS_SET_SEPARATOR_CHAR( _c) is_ag_char_map_char((char)(_c), 0x10000C13) +#define SPN_SET_SEPARATOR_CHARS(_s) spn_ag_char_map_chars(_s, 42) +#define BRK_SET_SEPARATOR_CHARS(_s) brk_ag_char_map_chars(_s, 42) +#define SPN_SET_SEPARATOR_BACK(s,e) spn_ag_char_map_back(s, e, 42) +#define BRK_SET_SEPARATOR_BACK(s,e) brk_ag_char_map_back(s, e, 42) +#define IS_SIGNED_NUMBER_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00038000) +#define SPN_SIGNED_NUMBER_CHARS(_s) spn_ag_char_map_chars(_s, 43) +#define BRK_SIGNED_NUMBER_CHARS(_s) brk_ag_char_map_chars(_s, 43) +#define SPN_SIGNED_NUMBER_BACK(s,e) spn_ag_char_map_back(s, e, 43) +#define BRK_SIGNED_NUMBER_BACK(s,e) brk_ag_char_map_back(s, e, 43) +#define IS_MAKE_SCRIPT_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000101) +#define SPN_MAKE_SCRIPT_CHARS(_s) spn_ag_char_map_chars(_s, 44) +#define BRK_MAKE_SCRIPT_CHARS(_s) brk_ag_char_map_chars(_s, 44) +#define SPN_MAKE_SCRIPT_BACK(s,e) spn_ag_char_map_back(s, e, 44) +#define BRK_MAKE_SCRIPT_BACK(s,e) brk_ag_char_map_back(s, e, 44) +#define IS_LOAD_LINE_SKIP_CHAR( _c) is_ag_char_map_char((char)(_c), 0x00000600) +#define SPN_LOAD_LINE_SKIP_CHARS(_s) spn_ag_char_map_chars(_s, 45) +#define BRK_LOAD_LINE_SKIP_CHARS(_s) brk_ag_char_map_chars(_s, 45) +#define SPN_LOAD_LINE_SKIP_BACK(s,e) spn_ag_char_map_back(s, e, 45) +#define BRK_LOAD_LINE_SKIP_BACK(s,e) brk_ag_char_map_back(s, e, 45) + +static ag_char_map_mask_t const ag_char_map_table[128] = { + /*NUL*/ 0x00000002, /*x01*/ 0x00000000, /*x02*/ 0x00000000, /*x03*/ 0x00000000, + /*x04*/ 0x00000000, /*x05*/ 0x00000000, /*x06*/ 0x00000000, /*BEL*/ 0x00000000, + /* BS*/ 0x00000800, /* HT*/ 0x00000400, /* NL*/ 0x00000001, /* VT*/ 0x00000800, + /* FF*/ 0x00000800, /* CR*/ 0x00000800, /*x0E*/ 0x00000000, /*x0F*/ 0x00000000, + /*x10*/ 0x00000000, /*x11*/ 0x00000000, /*x12*/ 0x00000000, /*x13*/ 0x00000000, + /*x14*/ 0x00000000, /*x15*/ 0x00000000, /*x16*/ 0x00000000, /*x17*/ 0x00000000, + /*x18*/ 0x00000000, /*x19*/ 0x00000000, /*x1A*/ 0x00000000, /*ESC*/ 0x00000000, + /*x1C*/ 0x00000000, /*x1D*/ 0x00000000, /*x1E*/ 0x00000000, /*x1F*/ 0x00000000, + /* */ 0x00000400, /* ! */ 0x02804000, /* " */ 0x02005000, /* # */ 0x02004000, + /* $ */ 0x02804100, /* % */ 0x02804008, /* & */ 0x02804000, /* ' */ 0x02005000, + /* ( */ 0x02006000, /* ) */ 0x02006000, /* * */ 0x02004000, /* + */ 0x12804080, + /* , */ 0x02004010, /* - */ 0x06A0C200, /* . */ 0x06C04000, /* / */ 0x03804004, + /* 0 */ 0x08814000, /* 1 */ 0x00814000, /* 2 */ 0x00814000, /* 3 */ 0x00814000, + /* 4 */ 0x00814000, /* 5 */ 0x00814000, /* 6 */ 0x00814000, /* 7 */ 0x00814000, + /* 8 */ 0x00824000, /* 9 */ 0x00824000, /* : */ 0x02804020, /* ; */ 0x02004000, + /* < */ 0x02004000, /* = */ 0x02004000, /* > */ 0x03004000, /* ? */ 0x02004000, + /* @ */ 0x02804000, /* A */ 0x00944000, /* B */ 0x00944000, /* C */ 0x00944000, + /* D */ 0x00944000, /* E */ 0x00944000, /* F */ 0x08944000, /* G */ 0x00904000, + /* H */ 0x00904000, /* I */ 0x00904000, /* J */ 0x00904000, /* K */ 0x00904000, + /* L */ 0x00904000, /* M */ 0x00904000, /* N */ 0x08904000, /* O */ 0x00904000, + /* P */ 0x00904000, /* Q */ 0x00904000, /* R */ 0x00904000, /* S */ 0x00904000, + /* T */ 0x00904000, /* U */ 0x00904000, /* V */ 0x00904000, /* W */ 0x00904000, + /* X */ 0x00904000, /* Y */ 0x00904000, /* Z */ 0x00904000, /* [ */ 0x02404000, + /* \ */ 0x02004004, /* ] */ 0x02404000, /* ^ */ 0x02A04000, /* _ */ 0x04804040, + /* ` */ 0x02004000, /* a */ 0x008C4000, /* b */ 0x008C4000, /* c */ 0x008C4000, + /* d */ 0x008C4000, /* e */ 0x008C4000, /* f */ 0x088C4000, /* g */ 0x00884000, + /* h */ 0x00884000, /* i */ 0x00884000, /* j */ 0x00884000, /* k */ 0x00884000, + /* l */ 0x00884000, /* m */ 0x00884000, /* n */ 0x08884000, /* o */ 0x00884000, + /* p */ 0x00884000, /* q */ 0x00884000, /* r */ 0x00884000, /* s */ 0x00884000, + /* t */ 0x00884000, /* u */ 0x00884000, /* v */ 0x00884000, /* w */ 0x00884000, + /* x */ 0x00884000, /* y */ 0x00884000, /* z */ 0x00884000, /* { */ 0x02004000, + /* | */ 0x12804000, /* } */ 0x02004000, /* ~ */ 0x0280C000, /*x7F*/ 0x00000000 +}; + +#include +#include +#include + +#ifndef _ +# define _(_s) _s +#endif + +static unsigned char const * ag_char_map_spanners[46]; +/** + * Character category masks. Some categories may have multiple bits, + * if their definition incorporates other character categories. + * This mask array is only used by calc_ag_char_map_spanners(). + */ +static ag_char_map_mask_t const ag_char_map_masks[46] = { + 0x00000001, /* NEWLINE */ + 0x00000002, /* NUL_BYTE */ + 0x00000004, /* DIR_SEP */ + 0x00000008, /* PERCENT */ + 0x00000010, /* COMMA */ + 0x00000020, /* COLON */ + 0x00000040, /* UNDERSCORE */ + 0x00000080, /* PLUS */ + 0x00000100, /* DOLLAR */ + 0x00000200, /* OPTION_MARKER */ + 0x00000400, /* HORIZ_WHITE */ + 0x00000800, /* ALT_WHITE */ + 0x00000C01, /* WHITESPACE */ + 0x00000C00, /* NON_NL_WHITE */ + 0x00001000, /* QUOTE */ + 0x00002000, /* PARENTHESES */ + 0x00004000, /* GRAPHIC */ + 0x00008000, /* INVERSION */ + 0x00010000, /* OCT_DIGIT */ + 0x00030000, /* DEC_DIGIT */ + 0x00070000, /* HEX_DIGIT */ + 0x00080000, /* LOWER_CASE */ + 0x00100000, /* UPPER_CASE */ + 0x00180000, /* ALPHABETIC */ + 0x001B0000, /* ALPHANUMERIC */ + 0x00180040, /* VAR_FIRST */ + 0x001B0040, /* VARIABLE_NAME */ + 0x003B0040, /* OPTION_NAME */ + 0x003B0060, /* VALUE_NAME */ + 0x00400000, /* NAME_SEP */ + 0x007B0460, /* COMPOUND_NAME */ + 0x00003000, /* SCHEME_NOTE */ + 0x00800000, /* UNQUOTABLE */ + 0x01000C01, /* END_XML_TOKEN */ + 0x00000C81, /* PLUS_N_SPACE */ + 0x02000000, /* PUNCTUATION */ + 0x041B0000, /* SUFFIX */ + 0x041B000C, /* SUFFIX_FMT */ + 0x08000002, /* FALSE_TYPE */ + 0x041B0004, /* FILE_NAME */ + 0x00000C03, /* END_TOKEN */ + 0x00000C13, /* END_LIST_ENTRY */ + 0x10000C13, /* SET_SEPARATOR */ + 0x00038000, /* SIGNED_NUMBER */ + 0x00000101, /* MAKE_SCRIPT */ + 0x00000600, /* LOAD_LINE_SKIP */ +}; +#undef LOCK_SPANNER_TABLES + +static unsigned char const * +calc_ag_char_map_spanners(unsigned int mask_ix) +{ +#ifdef LOCK_SPANNER_TABLES + if (ag_char_map_spanners[mask_ix] != NULL) + return ag_char_map_spanners[mask_ix]; + + pthread_mutex_lock(&ag_char_map_mutex); + if (ag_char_map_spanners[mask_ix] == NULL) +#endif + { + int ix = 1; + ag_char_map_mask_t mask = ag_char_map_masks[mask_ix]; + unsigned char * res = malloc(256 /* 1 << NBBY */); + if (res == NULL) { + fputs(_("no memory for char-mapper span map\n"), stderr); + exit(EXIT_FAILURE); + } + + memset(res, 0, 256); + for (; ix < 128; ix++) + if (ag_char_map_table[ix] & mask) + res[ix] = 1; + ag_char_map_spanners[mask_ix] = res; + } +#ifdef LOCK_SPANNER_TABLES + pthread_mutex_unlock(&ag_char_map_mutex); +#endif + return ag_char_map_spanners[mask_ix]; +} +#define ag_char_map_masks POISONED_ag_char_map_masks + +static inline int +is_ag_char_map_char(char ch, ag_char_map_mask_t mask) +{ + unsigned int ix = (unsigned char)ch; + return ((ix < 128) && ((ag_char_map_table[ix] & mask) != 0)); +} + +static inline char * +spn_ag_char_map_chars(char const * p, unsigned int mask_ix) +{ + unsigned char const * v = ag_char_map_spanners[mask_ix]; + if (v == NULL) + v = calc_ag_char_map_spanners(mask_ix); + while (v[(unsigned char)*p]) p++; + return (char *)(uintptr_t)p; +} + +static inline char * +brk_ag_char_map_chars(char const * p, unsigned int mask_ix) +{ + unsigned char const * v = ag_char_map_spanners[mask_ix]; + if (v == NULL) + v = calc_ag_char_map_spanners(mask_ix); + while ((*p != '\0') && (! v[(unsigned char)*p])) p++; + return (char *)(uintptr_t)p; +} + +static inline char * +spn_ag_char_map_back(char const * s, char const * e, unsigned int mask_ix) +{ + unsigned char const * v = ag_char_map_spanners[mask_ix]; + if (v == NULL) + v = calc_ag_char_map_spanners(mask_ix); + if (s >= e) e = s + strlen(s); + while ((e > s) && v[(unsigned char)e[-1]]) e--; + return (char *)(uintptr_t)e; +} + +static inline char * +brk_ag_char_map_back(char const * s, char const * e, unsigned int mask_ix) +{ + unsigned char const * v = ag_char_map_spanners[mask_ix]; + if (v == NULL) + v = calc_ag_char_map_spanners(mask_ix); + if (s == e) e += strlen(e); + while ((e > s) && (! v[(unsigned char)e[-1]])) e--; + return (char *)(uintptr_t)e; +} +#endif /* AG_CHAR_MAP_H_GUARD */ diff --git a/autoopts/alias.c b/autoopts/alias.c new file mode 100644 index 0000000..231f275 --- /dev/null +++ b/autoopts/alias.c @@ -0,0 +1,116 @@ + +/** + * \file alias.c + * + * Handle options that are aliases for another option. + * + * @addtogroup autoopts + * @{ + */ +/* + * This routine will forward an option alias to the correct option code. + * + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +static tSuccess +too_many_occurrences(tOptions * opts, tOptDesc * od) +{ + if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0) { + char const * eqv = (od->optEquivIndex != NO_EQUIVALENT) ? zequiv : zNil; + + fprintf(stderr, ztoo_often_fmt, opts->pzProgName); + + if (od->optMaxCt > 1) + fprintf(stderr, zat_most, od->optMaxCt, od->pz_Name, eqv); + else + fprintf(stderr, zonly_one, od->pz_Name, eqv); + (*opts->pUsageProc)(opts, EXIT_FAILURE); + /* NOTREACHED */ + } + + return FAILURE; +} + +/*=export_func optionAlias + * private: + * + * what: relay an option to its alias + * arg: + tOptions * + opts + program options descriptor + + * arg: + tOptDesc * + old_od + the descriptor for this arg + + * arg: + unsigned int + alias + the aliased-to option index + + * ret-type: int + * + * doc: + * Handle one option as if it had been specified as another. Exactly. + * Returns "-1" if the aliased-to option has appeared too many times. +=*/ +int +optionAlias(tOptions * opts, tOptDesc * old_od, unsigned int alias) +{ + tOptDesc * new_od; + + if (opts <= OPTPROC_EMIT_LIMIT) + return 0; + + new_od = opts->pOptDesc + alias; + if ((unsigned)opts->optCt <= alias) { + fputs(zbad_alias_id, stderr); + option_exits(EXIT_FAILURE); + } + + /* + * Copy over the option instance flags + */ + new_od->fOptState &= OPTST_PERSISTENT_MASK; + new_od->fOptState |= (old_od->fOptState & ~OPTST_PERSISTENT_MASK); + new_od->optArg.argString = old_od->optArg.argString; + + /* + * Keep track of count only for DEFINED (command line) options. + * IF we have too many, build up an error message and bail. + */ + if ( (new_od->fOptState & OPTST_DEFINED) + && (++new_od->optOccCt > new_od->optMaxCt) ) + return too_many_occurrences(opts, new_od); + + /* + * Clear the state bits and counters + */ + old_od->fOptState &= OPTST_PERSISTENT_MASK; + old_od->optOccCt = 0; + + /* + * If there is a procedure to call, call it + */ + if (new_od->pOptProc != NULL) + (*new_od->pOptProc)(opts, new_od); + return 0; +} + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/alias.c */ diff --git a/autoopts/ao-strs.c b/autoopts/ao-strs.c new file mode 100644 index 0000000..7f59372 --- /dev/null +++ b/autoopts/ao-strs.c @@ -0,0 +1,379 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * DO NOT EDIT THIS FILE (ao-strs.c) + * + * It has been AutoGen-ed + * From the definitions ao-strs.def + * and the template file strings + * + * Copyright (C) 2011-2018 Bruce Korb, all rights reserved. + * This is free software. It is licensed for use, modification and + * redistribution under the terms of the + * Modified (3 clause) Berkeley Software Distribution License + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name ``Bruce Korb'' nor the name of any other + * contributor may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * strings IS PROVIDED BY Bruce Korb ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Bruce Korb OR ANY OTHER CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "ao-strs.h" + +char const ao_strs_strtable[6714] = +/* 0 */ "-_^\0" +/* 4 */ " %s%s\n\0" +/* 12 */ "\n\0" +/* 64 */ "\n" + "%s\n\n\0" +/* 70 */ "=file\0" +/* 76 */ "=Mbr\0" +/* 81 */ "=Cplx\0" +/* 87 */ "[=arg]\0" +/* 94 */ "--%2$s%1$s\0" +/* 105 */ "=Tim\0" +/* 110 */ "none\0" +/* 115 */ "# preset/initialization file\n" + "# %s#\n\0" +/* 153 */ " %3s %-14s %s\0" +/* 167 */ "%s\0" +/* 170 */ "T/F\0" +/* 174 */ "\n" + "%s\n\n" + "%s\0" +/* 182 */ "Fil\0" +/* 186 */ "KWd\0" +/* 190 */ "Mbr\0" +/* 194 */ "Cpx\0" +/* 198 */ "no \0" +/* 202 */ "Num\0" +/* 206 */ "opt\0" +/* 210 */ "YES\0" +/* 214 */ "Str\0" +/* 218 */ "Tim\0" +/* 222 */ "\t\t\t\t- \0" +/* 229 */ "\t\t\t\t \0" +/* 236 */ "\t\t\t\t-- and \0" +/* 248 */ "\t\t\t\t%s\n\0" +/* 256 */ " \0" +/* 263 */ " \0" +/* 269 */ " \0" +/* 273 */ " \0" +/* 276 */ "all\0" +/* 280 */ " \t\n" + ":=\0" +/* 286 */ "%s_%s_%d=\0" +/* 296 */ "''\0" +/* 299 */ " ;;\n\n\0" +/* 312 */ "'\n\n\0" +/* 316 */ "\n\0" +/* 323 */ " %s\n\0" +/* 329 */ "%%-%ds\0" +/* 336 */ "\n" + "export %s_%s_%d\n\0" +/* 354 */ "false\0" +/* 360 */ " -* )\n\0" +/* 370 */ "flag\0" +/* 375 */ "INVALID-%d\0" +/* 386 */ "*INVALID*\0" +/* 396 */ "\\n\\\n\0" +/* 401 */ " --* )\n\0" +/* 412 */ "--\0" +/* 415 */ "LONGUSAGE\0" +/* 425 */ " %s\n\0" +/* 441 */ "\\%03o\0" +/* 447 */ "more\0" +/* 452 */ "<%s type=nested>\n\0" +/* 470 */ "%s\n\0" +/* 474 */ "%s\n" + " \0" +/* 480 */ "OPT_ARG_NEEDED=NO\0" +/* 498 */ "<%s/>\n\0" +/* 505 */ "OPT_ARG_NEEDED=OK\0" +/* 523 */ "\t\0" +/* 525 */ "<%s>\0" +/* 530 */ "option\0" +/* 537 */ "\n" + "export %s_%s\n\0" +/* 552 */ "%s_%s=\0" +/* 559 */ " | \0" +/* 563 */ "PAGER\0" +/* 569 */ "%1$s %2$s ; rm -f %2$s\0" +/* 592 */ " + \0" +/* 596 */ " puts(_(%s));\n\0" +/* 612 */ "\\'\0" +/* 615 */ "'%s'\0" +/* 620 */ " -- %s\0" +/* 627 */ "%s_%s_TEXT='\0" +/* 640 */ "#! %s\n\0" +/* 647 */ "\n" + "env | grep '^%s_'\n\0" +/* 667 */ "=%1$lu # 0x%1$lX\n\0" +/* 685 */ "stdout\0" +/* 692 */ "%A %B %e, %Y at %r %Z\0" +/* 714 */ "TMPDIR\0" +/* 721 */ "%s/use-%u.XXXXXX\0" +/* 738 */ "true\0" +/* 743 */ "<%s type=%s>\0" +/* 756 */ "VERSION\0" +/* 764 */ "#x%02X;\0" +/* 772 */ "OPT_ARG_NEEDED=YES\0" +/* 791 */ "\n" + "# %s -- %s\n\0" +/* 804 */ "# DEFAULT: \0" +/* 816 */ "'\\''\0" +/* 821 */ " '%s'\0" +/* 827 */ "libopts misguessed length of string\n\0" +/* 864 */ "\n" + "OPTION_CT=0\n\0" +/* 878 */ "set --\0" +/* 885 */ "/tmp\0" +/* 890 */ " ;;\n\n\0" +/* 907 */ " '%c' )\n\0" +/* 923 */ " '%s' )\n\0" +/* 939 */ " '%s' | \\\n\0" +/* 957 */ "<%1$s type=boolean>%2$s\n\0" +/* 989 */ "# From the %s option definitions\n" + "#\n\0" +/* 1026 */ "echo 'Warning: Cannot load options files' >&2\0" +/* 1073 */ "echo 'Warning: Cannot save options files' >&2\0" +/* 1120 */ "echo 'Warning: Cannot suppress the loading of options files' >&2\0" +/* 1186 */ "<%1$s type=integer>0x%2$lX\n\0" +/* 1221 */ "%1$s_%2$s_TEXT='no %2$s text'\n\0" +/* 1252 */ "%1$s_%2$s_MODE='%3$s'\n" + "export %1$s_%2$s_MODE\n\0" +/* 1297 */ "%1$s_%2$s='%3$s'\n" + "export %1$s_%2$s\n\0" +/* 1332 */ "%1$s_%2$s_CT=%3$d\n" + "export %1$s_%2$s_CT\n\0" +/* 1371 */ "OPTION_CT=%d\n" + "export OPTION_CT\n\0" +/* 1402 */ "%1$s_%2$s=%3$s\n" + "export %1$s_%2$s\n\0" +/* 1435 */ "%1$s_%2$s=%3$d # 0x%3$X\n" + "export %1$s_%2$s\n\0" +/* 1477 */ " case \"${OPT_CODE}\" in\n\0" +/* 1508 */ " if [ $%1$s_%2$s_CT -gt %3$u ] ; then\n" + " echo 'Error: more than %3$d %2$s options'\n" + " echo \"$%1$s_USAGE_TEXT\"\n" + " exit 1\n" + " fi >&2\n\0" +/* 1699 */ "test ${%1$s_%2$s_CT-0} -ge %3$u || {\n" + " echo %1$s_%2$s has not been set\n" + " exit 1\n" + "} 1>&2\n\0" +/* 1791 */ "test -n \"$%1$s_%2$s\" || {\n" + " echo %1$s_%2$s has not been set\n" + " exit 1\n" + "} 1>&2\n\0" +/* 1872 */ " echo \"$%s_%s_TEXT\"\n" + " exit 0\n\0" +/* 1923 */ "\n" + "# # # # # # # # # #\n" + "#\n" + "# END OF AUTOMATED OPTION PROCESSING\n" + "#\n" + "# # # # # # # # # # -- do not modify this marker --\n\0" +/* 2039 */ " if [ -n \"${OPT_ARG_VAL}\" ]\n" + " then\n" + " eval %1$s_${OPT_NAME}${OPT_ELEMENT}=\"'${OPT_ARG_VAL}'\"\n" + " export %1$s_${OPT_NAME}${OPT_ELEMENT}\n" + " fi\n" + "done\n" + "OPTION_COUNT=`expr $ARG_COUNT - $#`\n" + "OPERAND_COUNT=$#\n" + "unset OPT_PROCESS || :\n" + "unset OPT_ELEMENT || :\n" + "unset OPT_ARG || :\n" + "unset OPT_ARG_NEEDED || :\n" + "unset OPT_NAME || :\n" + "unset OPT_CODE || :\n" + "unset OPT_ARG_VAL || :\n\0" +/* 2418 */ " OPT_CODE=`echo \"X${OPT_ARG}\"|sed 's/^X-*//'`\n" + " shift\n" + " OPT_ARG=$1\n" + " case \"${OPT_CODE}\" in *=* )\n" + " OPT_ARG_VAL=`echo \"${OPT_CODE}\"|sed 's/^[^=]*=//'`\n" + " OPT_CODE=`echo \"${OPT_CODE}\"|sed 's/=.*$//'` ;; esac\n\0" +/* 2669 */ " OPT_CODE=`echo \"X${OPT_ARG}\" | sed 's/X-\\(.\\).*/\\1/'`\n" + " OPT_ARG=` echo \"X${OPT_ARG}\" | sed 's/X-.//'`\n\0" +/* 2786 */ "\n" + "ARG_COUNT=$#\n" + "OPT_PROCESS=true\n" + "OPT_ARG=$1\n" + "while ${OPT_PROCESS} && [ $# -gt 0 ]\n" + "do\n" + " OPT_ELEMENT=''\n" + " OPT_ARG_VAL=''\n\n" + " case \"${OPT_ARG}\" in\n" + " -- )\n" + " OPT_PROCESS=false\n" + " shift\n" + " ;;\n\0" +/* 2993 */ " case \"${OPT_ARG_NEEDED}\" in\n" + " NO )\n" + " OPT_ARG_VAL=''\n" + " ;;\n" + " YES )\n" + " if [ -z \"${OPT_ARG_VAL}\" ]\n" + " then\n" + " if [ $# -eq 0 ]\n" + " then\n" + " echo No argument provided for ${OPT_NAME} option\n" + " echo \"$%s_USAGE_TEXT\"\n" + " exit 1\n" + " fi >&2\n" + " OPT_ARG_VAL=${OPT_ARG}\n" + " shift\n" + " OPT_ARG=$1\n" + " fi\n" + " ;;\n" + " OK )\n" + " if [ -z \"${OPT_ARG_VAL}\" ] && [ $# -gt 0 ]\n" + " then\n" + " case \"${OPT_ARG}\" in -* ) ;; * )\n" + " OPT_ARG_VAL=${OPT_ARG}\n" + " shift\n" + " OPT_ARG=$1 ;; esac\n" + " fi\n" + " ;;\n" + " esac\n\0" +/* 3772 */ " %1$s_%2$s_CT=`expr ${%1$s_%2$s_CT} + 1`\n" + " OPT_ELEMENT=\"_${%1$s_%2$s_CT}\"\n" + " OPT_NAME='%2$s'\n\0" +/* 3896 */ "\n" + "if test -z \"${%1$s_%2$s}\"\n" + "then\n" + " %1$s_%2$s_CT=0\n" + " export %1$s_%2$s_CT\n" + "else\n" + " %1$s_%2$s_CT=1\n" + " %1$s_%2$s_1=${%1$s_%2$s}\n" + " export %1$s_%2$s_CT %1$s_%2$s_1\n" + "fi\n\0" +/* 4054 */ " * )\n" + " OPT_PROCESS=false\n" + " ;;\n" + " esac\n\0" +/* 4111 */ " %1$s_%2$s_CT=0\n" + " OPT_ELEMENT=''\n" + " %1$s_%2$s='%3$s'\n" + " export %1$s_%2$s\n" + " OPT_NAME='%2$s'\n\0" +/* 4252 */ " if [ -n \"${%1$s_%2$s}\" ] && ${%1$s_%2$s_set} ; then\n" + " echo 'Error: duplicate %2$s option'\n" + " echo \"$%1$s_USAGE_TEXT\"\n" + " exit 1\n" + " fi >&2\n" + " %1$s_%2$s_set=true\n" + " %1$s_%2$s='%3$s'\n" + " export %1$s_%2$s\n" + " OPT_NAME='%2$s'\n\0" +/* 4569 */ "\n" + "ARG_COUNT=$#\n" + "OPT_ARG=$1\n" + "while [ $# -gt 0 ]\n" + "do\n" + " OPT_ELEMENT=''\n" + " OPT_ARG_VAL=''\n" + " OPT_ARG=${1}\n\0" +/* 4672 */ " case \"${OPT_ARG_NEEDED}\" in\n" + " NO )\n" + " if [ -n \"${OPT_ARG}\" ]\n" + " then\n" + " OPT_ARG=-${OPT_ARG}\n" + " else\n" + " shift\n" + " OPT_ARG=$1\n" + " fi\n" + " ;;\n" + " YES )\n" + " if [ -n \"${OPT_ARG}\" ]\n" + " then\n" + " OPT_ARG_VAL=${OPT_ARG}\n" + " else\n" + " if [ $# -eq 0 ]\n" + " then\n" + " echo No argument provided for ${OPT_NAME} option\n" + " echo \"$%s_USAGE_TEXT\"\n" + " exit 1\n" + " fi >&2\n" + " shift\n" + " OPT_ARG_VAL=$1\n" + " fi\n" + " shift\n" + " OPT_ARG=$1\n" + " ;;\n" + " OK )\n" + " if [ -n \"${OPT_ARG}\" ]\n" + " then\n" + " OPT_ARG_VAL=${OPT_ARG}\n" + " shift\n" + " OPT_ARG=$1\n" + " else\n" + " shift\n" + " if [ $# -gt 0 ]\n" + " then\n" + " case \"$1\" in -* ) ;; * )\n" + " OPT_ARG_VAL=$1\n" + " shift ;; esac\n" + " OPT_ARG=$1\n" + " fi\n" + " fi\n" + " ;;\n" + " esac\n\0" +/* 5826 */ " echo \"$%s_LONGUSAGE_TEXT\" | ${PAGER-more}\n" + " exit 0\n\0" +/* 5900 */ "%s OF %s\n" + "#\n" + "# From here to the next `-- do not modify this marker --',\n" + "# the text has been generated %s\n\0" +/* 6006 */ " eval %1$s_%2$s${OPT_ELEMENT}=true\n" + " export %1$s_%2$s${OPT_ELEMENT}\n\0" +/* 6096 */ " if [ -n \"${%1$s_%2$s}\" ] && ${%1$s_%2$s_set} ; then\n" + " echo 'Error: duplicate %2$s option'\n" + " echo \"$%1$s_USAGE_TEXT\"\n" + " exit 1\n" + " fi >&2\n" + " %1$s_%2$s_set=true\n" + " OPT_NAME='%2$s'\n\0" +/* 6355 */ "\n" + "%1$s_%2$s=${%1$s_%2$s-'%3$s'}\n" + "%1$s_%2$s_set=false\n" + "export %1$s_%2$s\n\0" +/* 6424 */ "\n" + "%1$s_%2$s=${%1$s_%2$s}\n" + "%1$s_%2$s_set=false\n" + "export %1$s_%2$s\n\0" +/* 6486 */ "# # # # # # # # # # -- do not modify this marker --\n" + "#\n" + "# DO NOT EDIT THIS SECTION\n\0" +/* 6569 */ " * )\n" + " echo Unknown %s: \"${OPT_CODE}\" >&2\n" + " echo \"$%s_USAGE_TEXT\" >&2\n" + " exit 1\n" + " ;;\n" + " esac\n"; + +/* end of ao-strs.c */ diff --git a/autoopts/ao-strs.def b/autoopts/ao-strs.def new file mode 100644 index 0000000..3271af1 --- /dev/null +++ b/autoopts/ao-strs.def @@ -0,0 +1,545 @@ +AutoGen Definitions strings; + +/** + * \file ao-strs.def + * + * This file is part of AutoOpts, a companion to AutoGen. + * It contains static immutable strings that are used throughout + * the libopts library code. The strings are split into two groups: + * strings for generating a shell script to parse arguments, and + * everything else. + * + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +#if 0 +string = { nm = ; + str = << _EOStr_ + +_EOStr_; +}; +#endif + +string = { nm = zSepChars; str = "-_^"; }; +string = { nm = zambig_file; str = " %s%s\n"; }; +string = { nm = zCfgAO_Flags; str = "\n"; }; +string = { nm = zGnuBreak; str = "\n%s\n\n"; }; +string = { nm = zGnuFileArg; str = "=file"; }; +string = { nm = zGnuKeyLArg; str = "=Mbr"; }; +string = { nm = zGnuNestArg; str = "=Cplx"; }; +string = { nm = zGnuOptArg; str = "[=arg]"; }; +string = { nm = zGnuOptFmt; str = "--%2$s%1$s"; }; +string = { nm = zGnuTimeArg; str = "=Tim"; }; +string = { nm = zNone; str = "none"; }; +string = { nm = zPresetFile; str = "# preset/initialization file\n# %s#\n";}; +string = { nm = zReqOptFmt; str = " %3s %-14s %s"; }; +string = { nm = zShrtGnuOptFmt; str = "%s"; }; +string = { nm = zStdBoolArg; str = "T/F"; }; +string = { nm = zStdBreak; str = "\n%s\n\n%s"; }; +string = { nm = zStdFileArg; str = "Fil"; }; +string = { nm = zStdKeyArg; str = "KWd"; }; +string = { nm = zStdKeyLArg; str = "Mbr"; }; +string = { nm = zStdNestArg; str = "Cpx"; }; +string = { nm = zStdNoArg; str = "no "; }; +string = { nm = zStdNumArg; str = "Num"; }; +string = { nm = zStdOptArg; str = "opt"; }; +string = { nm = zStdReqArg; str = "YES"; }; +string = { nm = zStdStrArg; str = "Str"; }; +string = { nm = zStdTimeArg; str = "Tim"; }; +string = { nm = zTabHyp; str = "\t\t\t\t- "; }; +string = { nm = zTabSpace; str = "\t\t\t\t "; }; +string = { nm = zTabHypAnd; str = "\t\t\t\t-- and "; }; +string = { nm = zTabout; str = "\t\t\t\t%s\n"; }; +string = { nm = zSixSpaces; str = " "; }; +string = { nm = zFiveSpaces; str = " "; }; +string = { nm = zThreeSpaces; str = " "; }; +string = { nm = zTwoSpaces; str = " "; }; +string = { nm = zAll; str = "all"; }; + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * STRINGS USED IN CREATING OPTION PARSING SHELL CODE + */ +string = { nm = ARG_BREAK_STR; str = " \t\n:="; }; +string = { nm = ARG_BY_NUM_FMT; str = "%s_%s_%d="; }; +string = { nm = EMPTY_ARG; str = "''"; }; +string = { nm = END_OPT_SEL_STR; str = " ;;\n\n"; }; +string = { nm = END_SET_TEXT; str = "'\n\n"; }; +string = { nm = END_XML_FMT; str = "\n"; }; +string = { nm = ENUM_ERR_LINE; str = " %s\n"; }; +string = { nm = ENUM_ERR_WIDTH; str = "%%-%ds"; }; +string = { nm = EXPORT_ARG_FMT; str = "\nexport %s_%s_%d\n"; }; +string = { nm = FALSE_STR; str = "false"; }; +string = { nm = FLAG_OPT_MARK; str = " -* )\n"; }; +string = { nm = FLAG_STR; str = "flag"; }; +string = { nm = INVALID_FMT; str = "INVALID-%d"; }; +string = { nm = INVALID_STR; str = "*INVALID*"; }; +string = { nm = LINE_SPLICE; str = "\\n\\\n"; }; +string = { nm = LONG_OPT_MARK; str = " --* )\n"; }; +string = { nm = LONG_OPT_MARKER; str = "--"; }; +string = { nm = LONG_USE_STR; str = "LONGUSAGE"; }; +string = { nm = LVL3_CMD; str = " %s\n"; }; +string = { nm = MK_STR_OCT_FMT; str = "\\%03o"; }; +string = { nm = MORE_STR; str = "more"; }; +string = { nm = NESTED_OPT_FMT; str = "<%s type=nested>\n"; }; +string = { nm = NLSTR_FMT; str = "%s\n"; }; +string = { nm = NLSTR_SPACE_FMT; str = "%s\n "; }; +string = { nm = NONE_STR; str = "none"; }; +string = { nm = NO_ARG_NEEDED; str = "OPT_ARG_NEEDED=NO"; }; +string = { nm = NULL_ATR_FMT; str = "<%s/>\n"; }; +string = { nm = OK_NEED_OPT_ARG; str = "OPT_ARG_NEEDED=OK"; }; +string = { nm = ONE_TAB_STR; str = "\t"; }; +string = { nm = OPEN_CLOSE_FMT; str = "<%s/>\n"; }; +string = { nm = OPEN_XML_FMT; str = "<%s>"; }; +string = { nm = OPTION_STR; str = "option"; }; +string = { nm = OPT_END_FMT; str = "\nexport %s_%s\n"; }; +string = { nm = OPT_VAL_FMT; str = "%s_%s="; }; +string = { nm = OR_STR; str = " | "; }; +string = { nm = PAGER_NAME; str = "PAGER"; }; +string = { nm = PAGE_USAGE_FMT; str = "%1$s %2$s ; rm -f %2$s"; }; +string = { nm = PLUS_STR; str = " + "; }; +string = { nm = PUTS_FMT; str = " puts(_(%s));\n"; }; +string = { nm = QUOT_APOS; str = "\\'"; }; +string = { nm = QUOT_ARG_FMT; str = "'%s'"; }; +string = { nm = SET_OFF_FMT; str = " -- %s"; }; +string = { nm = SET_TEXT_FMT; str = "%s_%s_TEXT='"; }; +string = { nm = SHELL_MAGIC; str = "#! %s\n"; }; +string = { nm = SHOW_PROG_ENV; str = "\nenv | grep '^%s_'\n"; }; +string = { nm = SHOW_VAL_FMT; str = "=%1$lu # 0x%1$lX\n"; }; +string = { nm = STDOUT; str = "stdout"; }; +string = { nm = TIME_FMT; str = "%A %B %e, %Y at %r %Z"; }; +string = { nm = TMPDIR; str = "TMPDIR"; }; +string = { nm = TMP_FILE_FMT; str = "%s/use-%u.XXXXXX"; }; +string = { nm = TMP_USAGE_FMT; str = "%s/use-%u.XXXXXX"; }; +string = { nm = TRUE_STR; str = "true"; }; +string = { nm = TWO_SPACES_STR; str = " "; }; +string = { nm = TYPE_ATR_FMT; str = "<%s type=%s>"; }; +string = { nm = VER_STR; str = "VERSION"; }; +string = { nm = XML_HEX_BYTE_FMT; str = "#x%02X;"; }; +string = { nm = YES_NEED_OPT_ARG; str = "OPT_ARG_NEEDED=YES"; }; +string = { nm = ao_name_use_fmt; str = "\n# %s -- %s\n"; }; +string = { nm = ao_default_use; str = "# DEFAULT: "; }; +string = { nm = apostrophe; str = "'\\''"; }; +string = { nm = arg_fmt; str = " '%s'"; }; +string = { nm = misguess_len; str = "libopts misguessed length of string\n"; }; +string = { nm = init_optct; str = "\nOPTION_CT=0\n"; }; +string = { nm = set_dash; str = "set --"; }; +string = { nm = tmp_dir; str = "/tmp"; }; +string = { nm = zOptionEndSelect; str = " ;;\n\n"; }; +string = { nm = zOptionFlag; str = " '%c' )\n"; }; +string = { nm = zOptionFullName; str = " '%s' )\n"; }; +string = { nm = zOptionPartName; str = " '%s' | \\\n"; }; + +string = { nm = BOOL_ATR_FMT; + str = "<%1$s type=boolean>%2$s\n"; }; + +string = { nm = END_PRE_FMT; + str = "# From the %s option definitions\n#\n"; }; + +string = { nm = NO_LOAD_WARN; + str = "echo 'Warning: Cannot load options files' >&2"; }; + +string = { nm = NO_SAVE_OPTS; + str = "echo 'Warning: Cannot save options files' >&2"; }; + +string = { nm = NO_SUPPRESS_LOAD; + str = "echo 'Warning: Cannot suppress the loading of options files' >&2"; }; + +string = { nm = NUMB_ATR_FMT; + str = "<%1$s type=integer>0x%2$lX\n"; }; + +string = { nm = SET_NO_TEXT_FMT; + str = "%1$s_%2$s_TEXT='no %2$s text'\n"; }; + +string = { nm = zEquivMode; + str = "%1$s_%2$s_MODE='%3$s'\nexport %1$s_%2$s_MODE\n"; }; + +string = { nm = zFullOptFmt; + str = "%1$s_%2$s='%3$s'\nexport %1$s_%2$s\n"; }; + +string = { nm = zOptCookieCt; + str = "%1$s_%2$s_CT=%3$d\nexport %1$s_%2$s_CT\n"; }; + +string = { nm = zOptCtFmt; + str = "OPTION_CT=%d\nexport OPTION_CT\n"; }; + +string = { nm = zOptDisabl; + str = "%1$s_%2$s=%3$s\nexport %1$s_%2$s\n"; }; + +string = { nm = zOptNumFmt; + str = "%1$s_%2$s=%3$d # 0x%3$X\nexport %1$s_%2$s\n"; }; + +string = { nm = zOptionCase; + str = " case \"${OPT_CODE}\" in\n"; }; + +string = { nm = CHK_MAX_COUNT; + str = << _EOStr_ + if [ $%1$s_%2$s_CT -gt %3$u ] ; then + echo 'Error: more than %3$d %2$s options' + echo "$%1$s_USAGE_TEXT" + exit 1 + fi >&2 + +_EOStr_; +}; + +string = { nm = CHK_MIN_COUNT; + str = <<- _EOStr_ + test ${%1$s_%2$s_CT-0} -ge %3$u || { + echo %1$s_%2$s has not been set + exit 1 + } 1>&2 + + _EOStr_; +}; + +string = { nm = CHK_ONE_REQUIRED; + str = <<- _EOStr_ + test -n "$%1$s_%2$s" || { + echo %1$s_%2$s has not been set + exit 1 + } 1>&2 + + _EOStr_; +}; + +string = { nm = ECHO_N_EXIT; + str = << _EOStr_ + echo "$%s_%s_TEXT" + exit 0 + +_EOStr_; +}; + +string = { nm = END_MARK; + str = <<- _EOStr_ + + # # # # # # # # # # + # + # END OF AUTOMATED OPTION PROCESSING + # + # # # # # # # # # # -- do not modify this marker -- + + _EOStr_; +}; + +string = { nm = FINISH_LOOP; + str = <<- _EOStr_ + if [ -n "${OPT_ARG_VAL}" ] + then + eval %1$s_${OPT_NAME}${OPT_ELEMENT}="'${OPT_ARG_VAL}'" + export %1$s_${OPT_NAME}${OPT_ELEMENT} + fi + done + OPTION_COUNT=`expr $ARG_COUNT - $#` + OPERAND_COUNT=$# + unset OPT_PROCESS || : + unset OPT_ELEMENT || : + unset OPT_ARG || : + unset OPT_ARG_NEEDED || : + unset OPT_NAME || : + unset OPT_CODE || : + unset OPT_ARG_VAL || : + + _EOStr_; +}; + +string = { nm = INIT_LOPT_STR; + str = << _EOStr_ + OPT_CODE=`echo "X${OPT_ARG}"|sed 's/^X-*//'` + shift + OPT_ARG=$1 + case "${OPT_CODE}" in *=* ) + OPT_ARG_VAL=`echo "${OPT_CODE}"|sed 's/^[^=]*=//'` + OPT_CODE=`echo "${OPT_CODE}"|sed 's/=.*$//'` ;; esac + +_EOStr_; +}; + +string = { nm = INIT_OPT_STR; + str = << _EOStr_ + OPT_CODE=`echo "X${OPT_ARG}" | sed 's/X-\(.\).*/\1/'` + OPT_ARG=` echo "X${OPT_ARG}" | sed 's/X-.//'` + +_EOStr_; +}; + +string = { nm = LOOP_STR; + str = <<- _EOStr_ + + ARG_COUNT=$# + OPT_PROCESS=true + OPT_ARG=$1 + while ${OPT_PROCESS} && [ $# -gt 0 ] + do + OPT_ELEMENT='' + OPT_ARG_VAL='' + + case "${OPT_ARG}" in + -- ) + OPT_PROCESS=false + shift + ;; + + _EOStr_; +}; + +string = { nm = LOPT_ARG_FMT; + str = << _EOStr_ + case "${OPT_ARG_NEEDED}" in + NO ) + OPT_ARG_VAL='' + ;; + YES ) + if [ -z "${OPT_ARG_VAL}" ] + then + if [ $# -eq 0 ] + then + echo No argument provided for ${OPT_NAME} option + echo "$%s_USAGE_TEXT" + exit 1 + fi >&2 + OPT_ARG_VAL=${OPT_ARG} + shift + OPT_ARG=$1 + fi + ;; + OK ) + if [ -z "${OPT_ARG_VAL}" ] && [ $# -gt 0 ] + then + case "${OPT_ARG}" in -* ) ;; * ) + OPT_ARG_VAL=${OPT_ARG} + shift + OPT_ARG=$1 ;; esac + fi + ;; + esac + +_EOStr_; +}; + +string = { nm = MULTI_ARG_FMT; + str = << _EOStr_ + %1$s_%2$s_CT=`expr ${%1$s_%2$s_CT} + 1` + OPT_ELEMENT="_${%1$s_%2$s_CT}" + OPT_NAME='%2$s' + +_EOStr_; +}; + +string = { nm = MULTI_DEF_FMT; + str = <<- _EOStr_ + + if test -z "${%1$s_%2$s}" + then + %1$s_%2$s_CT=0 + export %1$s_%2$s_CT + else + %1$s_%2$s_CT=1 + %1$s_%2$s_1=${%1$s_%2$s} + export %1$s_%2$s_CT %1$s_%2$s_1 + fi + + _EOStr_; +}; + +string = { nm = NOT_FOUND_STR; + str = <<- _EOStr_ + * ) + OPT_PROCESS=false + ;; + esac + + _EOStr_; +}; + +string = { nm = NO_MULTI_ARG_FMT; + str = << _EOStr_ + %1$s_%2$s_CT=0 + OPT_ELEMENT='' + %1$s_%2$s='%3$s' + export %1$s_%2$s + OPT_NAME='%2$s' + +_EOStr_; +}; + +string = { nm = NO_SGL_ARG_FMT; + str = << _EOStr_ + if [ -n "${%1$s_%2$s}" ] && ${%1$s_%2$s_set} ; then + echo 'Error: duplicate %2$s option' + echo "$%1$s_USAGE_TEXT" + exit 1 + fi >&2 + %1$s_%2$s_set=true + %1$s_%2$s='%3$s' + export %1$s_%2$s + OPT_NAME='%2$s' + +_EOStr_; +}; + +string = { nm = ONLY_OPTS_LOOP; + str = <<- _EOStr_ + + ARG_COUNT=$# + OPT_ARG=$1 + while [ $# -gt 0 ] + do + OPT_ELEMENT='' + OPT_ARG_VAL='' + OPT_ARG=${1} + + _EOStr_; +}; + +string = { nm = OPT_ARG_FMT; + str = <<- _EOStr_ + case "${OPT_ARG_NEEDED}" in + NO ) + if [ -n "${OPT_ARG}" ] + then + OPT_ARG=-${OPT_ARG} + else + shift + OPT_ARG=$1 + fi + ;; + YES ) + if [ -n "${OPT_ARG}" ] + then + OPT_ARG_VAL=${OPT_ARG} + else + if [ $# -eq 0 ] + then + echo No argument provided for ${OPT_NAME} option + echo "$%s_USAGE_TEXT" + exit 1 + fi >&2 + shift + OPT_ARG_VAL=$1 + fi + shift + OPT_ARG=$1 + ;; + OK ) + if [ -n "${OPT_ARG}" ] + then + OPT_ARG_VAL=${OPT_ARG} + shift + OPT_ARG=$1 + else + shift + if [ $# -gt 0 ] + then + case "$1" in -* ) ;; * ) + OPT_ARG_VAL=$1 + shift ;; esac + OPT_ARG=$1 + fi + fi + ;; + esac + + _EOStr_; +}; + +string = { nm = PAGE_USAGE_TEXT; + str = << _EOStr_ + echo "$%s_LONGUSAGE_TEXT" | ${PAGER-more} + exit 0 + +_EOStr_; +}; + +string = { nm = PREAMBLE_FMT; + str = <<- _EOStr_ + %s OF %s + # + # From here to the next `-- do not modify this marker --', + # the text has been generated %s + + _EOStr_; +}; + +string = { nm = SET_MULTI_ARG; + str = << _EOStr_ + eval %1$s_%2$s${OPT_ELEMENT}=true + export %1$s_%2$s${OPT_ELEMENT} + +_EOStr_; +}; + +string = { nm = SGL_ARG_FMT; + str = << _EOStr_ + if [ -n "${%1$s_%2$s}" ] && ${%1$s_%2$s_set} ; then + echo 'Error: duplicate %2$s option' + echo "$%1$s_USAGE_TEXT" + exit 1 + fi >&2 + %1$s_%2$s_set=true + OPT_NAME='%2$s' + +_EOStr_; +}; + +string = { nm = SGL_DEF_FMT; + str = <<- _EOStr_ + + %1$s_%2$s=${%1$s_%2$s-'%3$s'} + %1$s_%2$s_set=false + export %1$s_%2$s + + _EOStr_; +}; + +string = { nm = SGL_NO_DEF_FMT; + str = <<- _EOStr_ + + %1$s_%2$s=${%1$s_%2$s} + %1$s_%2$s_set=false + export %1$s_%2$s + + _EOStr_; +}; + +string = { nm = START_MARK; + str = <<- _EOStr_ + # # # # # # # # # # -- do not modify this marker -- + # + # DO NOT EDIT THIS SECTION + + _EOStr_; +}; + +string = { nm = UNK_OPT_FMT; + str = <<- _EOStr_ + * ) + echo Unknown %s: "${OPT_CODE}" >&2 + echo "$%s_USAGE_TEXT" >&2 + exit 1 + ;; + esac + + _EOStr_; +}; diff --git a/autoopts/ao-strs.h b/autoopts/ao-strs.h new file mode 100644 index 0000000..95036ef --- /dev/null +++ b/autoopts/ao-strs.h @@ -0,0 +1,338 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * DO NOT EDIT THIS FILE (ao-strs.h) + * + * It has been AutoGen-ed + * From the definitions ao-strs.def + * and the template file strings + * + * Copyright (C) 2011-2018 Bruce Korb, all rights reserved. + * This is free software. It is licensed for use, modification and + * redistribution under the terms of the + * Modified (3 clause) Berkeley Software Distribution License + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name ``Bruce Korb'' nor the name of any other + * contributor may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * strings IS PROVIDED BY Bruce Korb ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Bruce Korb OR ANY OTHER CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef STRINGS_AO_STRS_H_GUARD +#define STRINGS_AO_STRS_H_GUARD 1 +/* + * 146 strings in ao_strs_strtable string table + */ +#define ARG_BREAK_STR (ao_strs_strtable+280) +#define ARG_BREAK_STR_LEN 5 +#define ARG_BY_NUM_FMT (ao_strs_strtable+286) +#define ARG_BY_NUM_FMT_LEN 9 +#define BOOL_ATR_FMT (ao_strs_strtable+957) +#define BOOL_ATR_FMT_LEN 31 +#define CHK_MAX_COUNT (ao_strs_strtable+1508) +#define CHK_MAX_COUNT_LEN 190 +#define CHK_MIN_COUNT (ao_strs_strtable+1699) +#define CHK_MIN_COUNT_LEN 91 +#define CHK_ONE_REQUIRED (ao_strs_strtable+1791) +#define CHK_ONE_REQUIRED_LEN 80 +#define ECHO_N_EXIT (ao_strs_strtable+1872) +#define ECHO_N_EXIT_LEN 50 +#define EMPTY_ARG (ao_strs_strtable+296) +#define EMPTY_ARG_LEN 2 +#define END_MARK (ao_strs_strtable+1923) +#define END_MARK_LEN 115 +#define END_OPT_SEL_STR (ao_strs_strtable+299) +#define END_OPT_SEL_STR_LEN 12 +#define END_PRE_FMT (ao_strs_strtable+989) +#define END_PRE_FMT_LEN 36 +#define END_SET_TEXT (ao_strs_strtable+312) +#define END_SET_TEXT_LEN 3 +#define END_XML_FMT (ao_strs_strtable+316) +#define END_XML_FMT_LEN 6 +#define ENUM_ERR_LINE (ao_strs_strtable+323) +#define ENUM_ERR_LINE_LEN 5 +#define ENUM_ERR_WIDTH (ao_strs_strtable+329) +#define ENUM_ERR_WIDTH_LEN 6 +#define EXPORT_ARG_FMT (ao_strs_strtable+336) +#define EXPORT_ARG_FMT_LEN 17 +#define FALSE_STR (ao_strs_strtable+354) +#define FALSE_STR_LEN 5 +#define FINISH_LOOP (ao_strs_strtable+2039) +#define FINISH_LOOP_LEN 378 +#define FLAG_OPT_MARK (ao_strs_strtable+360) +#define FLAG_OPT_MARK_LEN 9 +#define FLAG_STR (ao_strs_strtable+370) +#define FLAG_STR_LEN 4 +#define INIT_LOPT_STR (ao_strs_strtable+2418) +#define INIT_LOPT_STR_LEN 250 +#define INIT_OPT_STR (ao_strs_strtable+2669) +#define INIT_OPT_STR_LEN 116 +#define INVALID_FMT (ao_strs_strtable+375) +#define INVALID_FMT_LEN 10 +#define INVALID_STR (ao_strs_strtable+386) +#define INVALID_STR_LEN 9 +#define LINE_SPLICE (ao_strs_strtable+396) +#define LINE_SPLICE_LEN 4 +#define LONG_OPT_MARK (ao_strs_strtable+401) +#define LONG_OPT_MARKER (ao_strs_strtable+412) +#define LONG_OPT_MARKER_LEN 2 +#define LONG_OPT_MARK_LEN 10 +#define LONG_USE_STR (ao_strs_strtable+415) +#define LONG_USE_STR_LEN 9 +#define LOOP_STR (ao_strs_strtable+2786) +#define LOOP_STR_LEN 206 +#define LOPT_ARG_FMT (ao_strs_strtable+2993) +#define LOPT_ARG_FMT_LEN 778 +#define LVL3_CMD (ao_strs_strtable+425) +#define LVL3_CMD_LEN 15 +#define MK_STR_OCT_FMT (ao_strs_strtable+441) +#define MK_STR_OCT_FMT_LEN 5 +#define MORE_STR (ao_strs_strtable+447) +#define MORE_STR_LEN 4 +#define MULTI_ARG_FMT (ao_strs_strtable+3772) +#define MULTI_ARG_FMT_LEN 123 +#define MULTI_DEF_FMT (ao_strs_strtable+3896) +#define MULTI_DEF_FMT_LEN 157 +#define NESTED_OPT_FMT (ao_strs_strtable+452) +#define NESTED_OPT_FMT_LEN 17 +#define NLSTR_FMT (ao_strs_strtable+470) +#define NLSTR_FMT_LEN 3 +#define NLSTR_SPACE_FMT (ao_strs_strtable+474) +#define NLSTR_SPACE_FMT_LEN 5 +#define NONE_STR (ao_strs_strtable+110) +#define NONE_STR_LEN 4 +#define NOT_FOUND_STR (ao_strs_strtable+4054) +#define NOT_FOUND_STR_LEN 56 +#define NO_ARG_NEEDED (ao_strs_strtable+480) +#define NO_ARG_NEEDED_LEN 17 +#define NO_LOAD_WARN (ao_strs_strtable+1026) +#define NO_LOAD_WARN_LEN 46 +#define NO_MULTI_ARG_FMT (ao_strs_strtable+4111) +#define NO_MULTI_ARG_FMT_LEN 140 +#define NO_SAVE_OPTS (ao_strs_strtable+1073) +#define NO_SAVE_OPTS_LEN 46 +#define NO_SGL_ARG_FMT (ao_strs_strtable+4252) +#define NO_SGL_ARG_FMT_LEN 316 +#define NO_SUPPRESS_LOAD (ao_strs_strtable+1120) +#define NO_SUPPRESS_LOAD_LEN 65 +#define NULL_ATR_FMT (ao_strs_strtable+498) +#define NULL_ATR_FMT_LEN 6 +#define NUMB_ATR_FMT (ao_strs_strtable+1186) +#define NUMB_ATR_FMT_LEN 34 +#define OK_NEED_OPT_ARG (ao_strs_strtable+505) +#define OK_NEED_OPT_ARG_LEN 17 +#define ONE_TAB_STR (ao_strs_strtable+523) +#define ONE_TAB_STR_LEN 1 +#define ONLY_OPTS_LOOP (ao_strs_strtable+4569) +#define ONLY_OPTS_LOOP_LEN 102 +#define OPEN_CLOSE_FMT (ao_strs_strtable+498) +#define OPEN_CLOSE_FMT_LEN 6 +#define OPEN_XML_FMT (ao_strs_strtable+525) +#define OPEN_XML_FMT_LEN 4 +#define OPTION_STR (ao_strs_strtable+530) +#define OPTION_STR_LEN 6 +#define OPT_ARG_FMT (ao_strs_strtable+4672) +#define OPT_ARG_FMT_LEN 1153 +#define OPT_END_FMT (ao_strs_strtable+537) +#define OPT_END_FMT_LEN 14 +#define OPT_VAL_FMT (ao_strs_strtable+552) +#define OPT_VAL_FMT_LEN 6 +#define OR_STR (ao_strs_strtable+559) +#define OR_STR_LEN 3 +#define PAGER_NAME (ao_strs_strtable+563) +#define PAGER_NAME_LEN 5 +#define PAGE_USAGE_FMT (ao_strs_strtable+569) +#define PAGE_USAGE_FMT_LEN 22 +#define PAGE_USAGE_TEXT (ao_strs_strtable+5826) +#define PAGE_USAGE_TEXT_LEN 73 +#define PLUS_STR (ao_strs_strtable+592) +#define PLUS_STR_LEN 3 +#define PREAMBLE_FMT (ao_strs_strtable+5900) +#define PREAMBLE_FMT_LEN 105 +#define PUTS_FMT (ao_strs_strtable+596) +#define PUTS_FMT_LEN 15 +#define QUOT_APOS (ao_strs_strtable+612) +#define QUOT_APOS_LEN 2 +#define QUOT_ARG_FMT (ao_strs_strtable+615) +#define QUOT_ARG_FMT_LEN 4 +#define SET_MULTI_ARG (ao_strs_strtable+6006) +#define SET_MULTI_ARG_LEN 89 +#define SET_NO_TEXT_FMT (ao_strs_strtable+1221) +#define SET_NO_TEXT_FMT_LEN 30 +#define SET_OFF_FMT (ao_strs_strtable+620) +#define SET_OFF_FMT_LEN 6 +#define SET_TEXT_FMT (ao_strs_strtable+627) +#define SET_TEXT_FMT_LEN 12 +#define SGL_ARG_FMT (ao_strs_strtable+6096) +#define SGL_ARG_FMT_LEN 258 +#define SGL_DEF_FMT (ao_strs_strtable+6355) +#define SGL_DEF_FMT_LEN 68 +#define SGL_NO_DEF_FMT (ao_strs_strtable+6424) +#define SGL_NO_DEF_FMT_LEN 61 +#define SHELL_MAGIC (ao_strs_strtable+640) +#define SHELL_MAGIC_LEN 6 +#define SHOW_PROG_ENV (ao_strs_strtable+647) +#define SHOW_PROG_ENV_LEN 19 +#define SHOW_VAL_FMT (ao_strs_strtable+667) +#define SHOW_VAL_FMT_LEN 17 +#define START_MARK (ao_strs_strtable+6486) +#define START_MARK_LEN 82 +#define STDOUT (ao_strs_strtable+685) +#define STDOUT_LEN 6 +#define TIME_FMT (ao_strs_strtable+692) +#define TIME_FMT_LEN 21 +#define TMPDIR (ao_strs_strtable+714) +#define TMPDIR_LEN 6 +#define TMP_FILE_FMT (ao_strs_strtable+721) +#define TMP_FILE_FMT_LEN 16 +#define TMP_USAGE_FMT (ao_strs_strtable+721) +#define TMP_USAGE_FMT_LEN 16 +#define TRUE_STR (ao_strs_strtable+738) +#define TRUE_STR_LEN 4 +#define TWO_SPACES_STR (ao_strs_strtable+273) +#define TWO_SPACES_STR_LEN 2 +#define TYPE_ATR_FMT (ao_strs_strtable+743) +#define TYPE_ATR_FMT_LEN 12 +#define UNK_OPT_FMT (ao_strs_strtable+6569) +#define UNK_OPT_FMT_LEN 144 +#define VER_STR (ao_strs_strtable+756) +#define VER_STR_LEN 7 +#define XML_HEX_BYTE_FMT (ao_strs_strtable+764) +#define XML_HEX_BYTE_FMT_LEN 7 +#define YES_NEED_OPT_ARG (ao_strs_strtable+772) +#define YES_NEED_OPT_ARG_LEN 18 +#define ao_default_use (ao_strs_strtable+804) +#define ao_default_use_LEN 11 +#define ao_name_use_fmt (ao_strs_strtable+791) +#define ao_name_use_fmt_LEN 12 +#define apostrophe (ao_strs_strtable+816) +#define apostrophe_LEN 4 +#define arg_fmt (ao_strs_strtable+821) +#define arg_fmt_LEN 5 +#define init_optct (ao_strs_strtable+864) +#define init_optct_LEN 13 +#define misguess_len (ao_strs_strtable+827) +#define misguess_len_LEN 36 +#define set_dash (ao_strs_strtable+878) +#define set_dash_LEN 6 +#define tmp_dir (ao_strs_strtable+885) +#define tmp_dir_LEN 4 +#define zAll (ao_strs_strtable+276) +#define zAll_LEN 3 +#define zCfgAO_Flags (ao_strs_strtable+12) +#define zCfgAO_Flags_LEN 14 +#define zCfgProg (ao_strs_strtable+27) +#define zCfgProg_LEN 9 +#define zEquivMode (ao_strs_strtable+1252) +#define zEquivMode_LEN 44 +#define zFiveSpaces (ao_strs_strtable+263) +#define zFiveSpaces_LEN 5 +#define zFmtFmt (ao_strs_strtable+37) +#define zFmtFmt_LEN 11 +#define zFmtProg (ao_strs_strtable+49) +#define zFmtProg_LEN 14 +#define zFullOptFmt (ao_strs_strtable+1297) +#define zFullOptFmt_LEN 34 +#define zGnuBreak (ao_strs_strtable+64) +#define zGnuBreak_LEN 5 +#define zGnuFileArg (ao_strs_strtable+70) +#define zGnuFileArg_LEN 5 +#define zGnuKeyLArg (ao_strs_strtable+76) +#define zGnuKeyLArg_LEN 4 +#define zGnuNestArg (ao_strs_strtable+81) +#define zGnuNestArg_LEN 5 +#define zGnuOptArg (ao_strs_strtable+87) +#define zGnuOptArg_LEN 6 +#define zGnuOptFmt (ao_strs_strtable+94) +#define zGnuOptFmt_LEN 10 +#define zGnuTimeArg (ao_strs_strtable+105) +#define zGnuTimeArg_LEN 4 +#define zNone (ao_strs_strtable+110) +#define zNone_LEN 4 +#define zOptCookieCt (ao_strs_strtable+1332) +#define zOptCookieCt_LEN 38 +#define zOptCtFmt (ao_strs_strtable+1371) +#define zOptCtFmt_LEN 30 +#define zOptDisabl (ao_strs_strtable+1402) +#define zOptDisabl_LEN 32 +#define zOptNumFmt (ao_strs_strtable+1435) +#define zOptNumFmt_LEN 41 +#define zOptionCase (ao_strs_strtable+1477) +#define zOptionCase_LEN 30 +#define zOptionEndSelect (ao_strs_strtable+890) +#define zOptionEndSelect_LEN 16 +#define zOptionFlag (ao_strs_strtable+907) +#define zOptionFlag_LEN 15 +#define zOptionFullName (ao_strs_strtable+923) +#define zOptionFullName_LEN 15 +#define zOptionPartName (ao_strs_strtable+939) +#define zOptionPartName_LEN 17 +#define zPresetFile (ao_strs_strtable+115) +#define zPresetFile_LEN 37 +#define zReqOptFmt (ao_strs_strtable+153) +#define zReqOptFmt_LEN 13 +#define zSepChars (ao_strs_strtable+0) +#define zSepChars_LEN 3 +#define zShrtGnuOptFmt (ao_strs_strtable+167) +#define zShrtGnuOptFmt_LEN 2 +#define zSixSpaces (ao_strs_strtable+256) +#define zSixSpaces_LEN 6 +#define zStdBoolArg (ao_strs_strtable+170) +#define zStdBoolArg_LEN 3 +#define zStdBreak (ao_strs_strtable+174) +#define zStdBreak_LEN 7 +#define zStdFileArg (ao_strs_strtable+182) +#define zStdFileArg_LEN 3 +#define zStdKeyArg (ao_strs_strtable+186) +#define zStdKeyArg_LEN 3 +#define zStdKeyLArg (ao_strs_strtable+190) +#define zStdKeyLArg_LEN 3 +#define zStdNestArg (ao_strs_strtable+194) +#define zStdNestArg_LEN 3 +#define zStdNoArg (ao_strs_strtable+198) +#define zStdNoArg_LEN 3 +#define zStdNumArg (ao_strs_strtable+202) +#define zStdNumArg_LEN 3 +#define zStdOptArg (ao_strs_strtable+206) +#define zStdOptArg_LEN 3 +#define zStdReqArg (ao_strs_strtable+210) +#define zStdReqArg_LEN 3 +#define zStdStrArg (ao_strs_strtable+214) +#define zStdStrArg_LEN 3 +#define zStdTimeArg (ao_strs_strtable+218) +#define zStdTimeArg_LEN 3 +#define zTabHyp (ao_strs_strtable+222) +#define zTabHypAnd (ao_strs_strtable+236) +#define zTabHypAnd_LEN 11 +#define zTabHyp_LEN 6 +#define zTabSpace (ao_strs_strtable+229) +#define zTabSpace_LEN 6 +#define zTabout (ao_strs_strtable+248) +#define zTabout_LEN 7 +#define zThreeSpaces (ao_strs_strtable+269) +#define zThreeSpaces_LEN 3 +#define zTwoSpaces (ao_strs_strtable+273) +#define zTwoSpaces_LEN 2 +#define zambig_file (ao_strs_strtable+4) +#define zambig_file_LEN 7 +extern char const ao_strs_strtable[6714]; + +#endif /* STRINGS_AO_STRS_H_GUARD */ diff --git a/autoopts/ao_string_tokenize.3 b/autoopts/ao_string_tokenize.3 new file mode 100644 index 0000000..fad6dff --- /dev/null +++ b/autoopts/ao_string_tokenize.3 @@ -0,0 +1,86 @@ +.TH ao_string_tokenize 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (ao_string_tokenize.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +ao_string_tokenize - tokenize an input string +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +token_list_t * \fBao_string_tokenize\fP(char const * \fIstring\fP); +.sp 1 +.SH DESCRIPTION +This function will convert one input string into a list of strings. +The list of strings is derived by separating the input based on +white space separation. However, if the input contains either single +or double quote characters, then the text after that character up to +a matching quote will become the string in the list. + +The returned pointer should be deallocated with \fBfree(3C)\fP when +are done using the data. The data are placed in a single block of +allocated memory. Do not deallocate individual token/strings. + +The structure pointed to will contain at least these two fields: +.sp +.IR "tkn_ct" +The number of tokens found in the input string. +.sp +.IR "tok_list" +An array of \fBtkn_ct + 1\fP pointers to substring tokens, with +the last pointer set to NULL. +.br + +There are two types of quoted strings: single quoted (\fB'\fP) and +double quoted (\fB"\fP). Singly quoted strings are fairly raw in that +escape characters (\fB\\\fP) are simply another character, except when +preceding the following characters: +.nf + \fB\\\fP double backslashes reduce to one + \fB'\fP incorporates the single quote into the string + \fB\n\fP suppresses both the backslash and newline character +.fi + +Double quote strings are formed according to the rules of string +constants in ANSI-C programs. +.TP +.IR string +string to be tokenized +.sp 1 +.SH RETURN VALUE +pointer to a structure that lists each token +.sp 1 +.SH ERRORS +NULL is returned and \fBerrno\fP will be set to indicate the problem: +.sp 1ize @bullet +.sp 1 +\fBEINVAL\fP \- There was an unterminated quoted string. +.sp 1 +\fBENOENT\fP \- The input string was empty. +.sp 1 +\fBENOMEM\fP \- There is not enough memory. +@end itemize +.sp 1 +.SH EXAMPLES +.nf +.in +5 +.nf + #include + int ix; + token_list_t * ptl = ao_string_tokenize(some_string) + for (ix = 0; ix < ptl->tkn_ct; ix++) + do_something_with_tkn(ptl->tkn_list[ix]); + free(ptl); +.fi +Note that everything is freed with the one call to \fBfree(3C)\fP. +.in -5 +.fi +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +configFileLoad(3), optionFileLoad(3), optionFindNextValue(3), optionFindValue(3), optionFree(3), optionGetValue(3), optionLoadLine(3), optionMemberList(3), optionNextValue(3), optionOnlyUsage(3), optionPrintVersion(3), optionPrintVersionAndReturn(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), strequate(3), streqvcmp(3), streqvmap(3), strneqvcmp(3), strtransform(3), diff --git a/autoopts/autogen.map b/autoopts/autogen.map new file mode 100644 index 0000000..328b6c7 --- /dev/null +++ b/autoopts/autogen.map @@ -0,0 +1,81 @@ + +%guard +%file ag-char-map.h +%backup +%optimize + +%comment + This file contains the character classifications + used by AutoGen and AutoOpts for identifying tokens. + The table is static scope, so %guard is empty. + + This file is part of AutoOpts, a companion to AutoGen. + AutoOpts is free software. + AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + + AutoOpts is available under any one of two licenses. The license + in use must be one of these two and the choice is under the control + of the user of the license. + + The GNU Lesser General Public License, version 3 or later + See the files "COPYING.lgplv3" and "COPYING.gplv3" + + The Modified Berkeley Software Distribution License + See the file "COPYING.mbsd" + + These files have the following sha256 sums: + + 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd +% + +newline "\n" +nul-byte "\x00" +dir-sep "/\\" +percent "%" +comma "," +colon ":" +underscore "_" +plus "+" +dollar "$" +option-marker "-" + +horiz-white "\t " +alt-white "\v\f\r\b" +whitespace +horiz-white +newline +alt-white +non-nl-white +horiz-white +alt-white +quote "'\"" +parentheses "()" + +graphic "!-~" +inversion "~-" +oct-digit "0-7" +dec-digit "89" +oct-digit +hex-digit "a-fA-F" +dec-digit +lower-case "a-z" +upper-case "A-Z" +alphabetic +lower-case +upper-case +alphanumeric +alphabetic +dec-digit +var-first +underscore +alphabetic +variable-name +var-first +dec-digit +option-name "^-" +variable-name +value-name +colon +option-name +name-sep "[.]" +compound-name +value-name +name-sep +horiz-white +scheme-note +parentheses +quote + +unquotable "!-~" -"#,;<=>[\\]`{}?*" -quote -parentheses +end-xml-token "/>" +whitespace +plus-n-space +plus +whitespace +punctuation "!-~" -alphanumeric -"_" +suffix "-._" +alphanumeric +suffix-fmt +percent +suffix +dir-sep +false-type "nNfF0" +nul-byte +file-name +dir-sep +suffix +end-token +nul-byte +whitespace +end-list-entry +comma +end-token +set-separator "|+-!" +end-list-entry +signed-number +inversion +dec-digit +make-script +dollar +newline +load-line-skip +horiz-white +option-marker diff --git a/autoopts/autoopts-config.1 b/autoopts/autoopts-config.1 new file mode 100644 index 0000000..dddf661 --- /dev/null +++ b/autoopts/autoopts-config.1 @@ -0,0 +1,161 @@ +\" -*- buffer-read-only: t -*- vi: set ro: +\" +\" DO NOT EDIT THIS FILE (autoopts-config.1) +\" +\" It has been AutoGen-ed +\" From the definitions aoconf.def +\" and the template file aoconf.tpl +\" +.TH autoopts-config 1 2018-08-26 "" "Programmer's Manual" +.SH NAME +autoopts-config \- script to get information about installed version of +autoopts +.SH SYNOPSIS +.B autoopts-config +.B { [...] | everything } +.PP +.SH DESCRIPTION +\fBautoopts-config\fP is a tool that is used by configure to determine +the compile and linker flags that should be used to compile and link +programs that use autoopts. \fIvalue-name\fPs may be preceded by +one or more hyphens. They are silently ignored. +.SH "VALUE NAMES" +.TP +.BR autogen +.sp +Print the full path name of the autogen executable. +.br +The unconfigured value is: ${bindir}/autogen${exeext} +.TP +.BR bindir +.sp +The destination directory for executable scripts and programs +installed by the \fIautogen\fP package. +.br +The unconfigured value is: @bindir@ +.TP +.BR cflags +.sp +Print the compiler flags that are necessary to compile an autoopts program. +.br +The unconfigured value is: -I${includedir} +.TP +.BR datadir +.sp +The directory for various data directories. +.br +The unconfigured value is: @datadir@ +.TP +.BR datarootdir +.sp +The root directory for various data directories. +In this case, there is only one, "datadir". +.br +The unconfigured value is: @datarootdir@ +.TP +.BR dotver +.sp +Print the currently installed version of autoopts, in dotted format. +.br +The unconfigured value is: @AO_CURRENT@.@AO_REVISION@.@AO_AGE@ +.TP +.BR everything +.sp +Print the list of all names and values, one per line. +.TP +.BR exec_prefix +.sp +The installation root for libraries and executables. +.br +The unconfigured value is: @exec_prefix@ +.TP +.BR exeext +.sp +The executable file extension used for the autogen executable. +.br +The unconfigured value is: @EXEEXT@ +.TP +.BR includedir +.sp +The directory where the AutoOpts headers are stored. +This does not include the "-I" prefix gotten by specifying "cflags". +.br +The unconfigured value is: @includedir@ +.TP +.BR ldflags +.sp +Print the linker flags that are necessary to link an autoopts program +in the default installation mode (static or dynamic). +.br +The unconfigured value is: -L${libdir} -lopts +.TP +.BR ldopts +.sp +The linker options to use when linking a program to libopts. +.br +The unconfigured value is: @AG_LDFLAGS@ +.TP +.BR libdir +.sp +The libopts installation directory. +.br +The unconfigured value is: @libdir@ +.TP +.BR libs +.sp +an alternate spelling of "\fIldflags\fP". +.br +The unconfigured value is: ${ldflags} +.TP +.BR libsrc +.sp +The full path of the redistributable, tear-off libopts library source. +This file is in gzipped-tarball format. +.br +The unconfigured value is: ${pkgdatadir}/libopts-${dotver}.tar.gz +.TP +.BR package +.sp +The name of the package that provides \fBautoopts\fP. This is always +"\fIautogen\fP". +.br +The unconfigured value is: @PACKAGE@ +.TP +.BR pkgdatadir +.sp +The directory containing support files used by autogen. +.br +The unconfigured value is: ${datadir}/${package} +.TP +.BR prefix +.sp +The \fIautogen\fP package installation prefix. +.br +The unconfigured value is: @prefix@ +.TP +.BR static_libs +.sp +The name of the AR archive of the libopts object code. +.br +The unconfigured value is: ${libdir}/libopts.a +.TP +.BR version +.sp +Print the currently installed version of autoopts. +.br +The unconfigured value is: @AO_CURRENT@:@AO_REVISION@:@AO_AGE@ +.SH "SEE ALSO" +.IR Autogen +Info system documentation. +.SH AUTHORS +AutoGen is the work of Bruce Korb . +.br +Bruce Korb and +.br +Luca Filipozzi +created this manpage. +.PP +AutoOpts is released under either the GNU General Public License with the +Library exception (LGPL), or else the advertising clause free BSD license. +Which license used is at the discretion of the licensee. +\" end of autoopts-config.1 diff --git a/autoopts/autoopts-config.in b/autoopts/autoopts-config.in new file mode 100644 index 0000000..3c966d1 --- /dev/null +++ b/autoopts/autoopts-config.in @@ -0,0 +1,113 @@ +#! @CONFIG_SHELL@ +## --------------------------------------------------------------------- +## autoopts-config.in -- Describe AutoOpts configuration +## +## Autoopts Copyright (C) 1992-2018 by Bruce Korb +## +## DO NOT EDIT THIS FILE (autoopts-config.in) +## +## It has been AutoGen-ed +## From the definitions aoconf.def +## and the template file aoconf.tpl +## + prefix="@prefix@" + datarootdir="@datarootdir@" + datadir="@datadir@" + package="@PACKAGE@" + includedir="@includedir@" + exec_prefix="@exec_prefix@" + bindir="@bindir@" + libdir="@libdir@" + ldopts="@AG_LDFLAGS@" + exeext="@EXEEXT@" + version="@AO_CURRENT@:@AO_REVISION@:@AO_AGE@" + dotver="@AO_CURRENT@.@AO_REVISION@.@AO_AGE@" + pkgdatadir="${datadir}/${package}" + autogen="${bindir}/autogen${exeext}" + ldflags="-L${libdir} -lopts" + libs="${ldflags}" + libsrc="${pkgdatadir}/libopts-${dotver}.tar.gz" + static_libs="${libdir}/libopts.a" + cflags="-I${includedir}" +test 'X@ENABLE_STATIC@' = Xno && static_libs='' +case "${libdir}" in +/lib | /lib64 | /usr/lib | /usr/lib64 | /usr/lib/* ) + ldopts='' + ldflags=-lopts + ;; + +* ) + ldflags="${ldopts} ${ldflags}" + ;; +esac +libs=${ldflags} +test "${includedir}" = "/usr/include" && cflags="" +optlist="\ + autogen bindir cflags datadir datarootdir dotver + everything exec_prefix exeext includedir ldflags ldopts + libdir libs libsrc package pkgdatadir prefix + static_libs version" + +usage() +{ + test $# -gt 0 && { + exec 1>&2 + echo autoopts-config error: "$*" + } + + echo Usage: autoopts-config \<\\> [ ... ] + echo Options may be one or more of: + + for o in $optlist + do echo " ${o}" + done | sed 's,_,-,g' + echo 'NB: "everything" will print out the list of all names and values.' + exit $# +} + +test $# -gt 0 || usage "No value specified" + +# Figure out what's wanted +# +val='' +for o in "$@" ; do + o=`echo ${o} | sed 's,^-*,,;s/-/_/g'` + case "$o" in + help | h | \? ) usage ;; + *[!a-zA-Z0-9_]* ) usage "Invalid name: ${o}" ;; + + prefix ) val="${val} ${prefix}" ;; + datarootdir ) val="${val} ${datarootdir}" ;; + datadir ) val="${val} ${datadir}" ;; + package ) val="${val} ${package}" ;; + includedir ) val="${val} ${includedir}" ;; + exec_prefix ) val="${val} ${exec_prefix}" ;; + bindir ) val="${val} ${bindir}" ;; + libdir ) val="${val} ${libdir}" ;; + ldopts ) val="${val} ${ldopts}" ;; + exeext ) val="${val} ${exeext}" ;; + version ) val="${val} ${version}" ;; + dotver ) val="${val} ${dotver}" ;; + pkgdatadir ) val="${val} ${pkgdatadir}" ;; + autogen ) val="${val} ${autogen}" ;; + ldflags ) val="${val} ${ldflags}" ;; + libs ) val="${val} ${libs}" ;; + libsrc ) val="${val} ${libsrc}" ;; + static_libs ) val="${val} ${static_libs}" ;; + cflags ) val="${val} ${cflags}" ;; + everything ) + for o in ${optlist} + do test ${o} = everything && continue + eval v=\"\${${o}}\" + test -z "${v}" && echo ${o} || \ + printf "%-12s $v\n" ${o} + done + exit 0 + ;; + + * ) usage "Unknown value name: ${o}" ;; + esac +done + +echo "${val}" +## end of autoopts-config.in diff --git a/autoopts/autoopts.c b/autoopts/autoopts.c new file mode 100644 index 0000000..643d277 --- /dev/null +++ b/autoopts/autoopts.c @@ -0,0 +1,391 @@ + +/** + * \file autoopts.c + * + * This file contains all of the routines that must be linked into + * an executable to use the generated option processing. The optional + * routines are in separately compiled modules so that they will not + * necessarily be linked in. + * + * @addtogroup autoopts + * @{ + */ +/* + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +/** + * The number of tab characters to skip when printing continuation lines. + */ + static unsigned int tab_skip_ct = 0; + +#ifndef HAVE_PATHFIND +# define pathfind(_p, _n, _m) option_pathfind(_p, _n, _m) +# include "compat/pathfind.c" +#endif + +#ifndef HAVE_SNPRINTF +# define vsnprintf option_vsnprintf +# define snprintf option_snprintf +# include "compat/snprintf.c" +#endif + +#ifndef HAVE_STRDUP +# define strdup(_s) option_strdup(_s) +# include "compat/strdup.c" +#endif + +#ifndef HAVE_STRCHR +# define strrchr(_s, _c) option_strrchr(_s, _c) +# define strchr(_s, _c) option_strchr(_s, _c) +# include "compat/strchr.c" +#endif + +static void * +ao_malloc(size_t sz) +{ + void * res = malloc(sz); + if (res == NULL) { + fprintf(stderr, zalloc_fail, (int)sz); + option_exits(EXIT_FAILURE); + } + return res; +} + +static void * +ao_realloc(void *p, size_t sz) +{ + void * res = (p == NULL) ? malloc(sz) : realloc(p, sz); + if (res == NULL) { + fprintf(stderr, zrealloc_fail, (int)sz, p); + option_exits(EXIT_FAILURE); + } + return res; +} + +static char * +ao_strdup(char const *str) +{ + char * res = strdup(str); + if (res == NULL) { + fprintf(stderr, zalloc_fail, (int)strlen(str)); + option_exits(EXIT_FAILURE); + } + return res; +} + +/** + * handle an option. + * + * This routine handles equivalencing, sets the option state flags and + * invokes the handler procedure, if any. + */ +static tSuccess +handle_opt(tOptions * opts, tOptState * o_st) +{ + /* + * Save a copy of the option procedure pointer. + * If this is an equivalence class option, we still want this proc. + */ + tOptDesc * od = o_st->pOD; + tOptProc * opt_proc = od->pOptProc; + if (od->fOptState & OPTST_ALLOC_ARG) + AGFREE(od->optArg.argString); + + od->optArg.argString = o_st->pzOptArg; + + /* + * IF we are presetting options, then we will ignore any un-presettable + * options. They are the ones either marked as such. + */ + if ( ((opts->fOptSet & OPTPROC_PRESETTING) != 0) + && ((od->fOptState & OPTST_NO_INIT) != 0) + ) + return PROBLEM; + + /* + * IF this is an equivalence class option, + * THEN + * Save the option value that got us to this option + * entry. (It may not be od->optChar[0], if this is an + * equivalence entry.) + * set the pointer to the equivalence class base + */ + if (od->optEquivIndex != NO_EQUIVALENT) { + tOptDesc * eqv_od = opts->pOptDesc + od->optEquivIndex; + + /* + * IF the current option state has not been defined (set on the + * command line), THEN we will allow continued resetting of + * the value. Once "defined", then it must not change. + */ + if ((od->fOptState & OPTST_DEFINED) != 0) { + /* + * The equivalenced-to option has been found on the command + * line before. Make sure new occurrences are the same type. + * + * IF this option has been previously equivalenced and + * it was not the same equivalenced-to option, + * THEN we have a usage problem. + */ + if (eqv_od->optActualIndex != od->optIndex) { + fprintf(stderr, zmultiway_bug, eqv_od->pz_Name, od->pz_Name, + (opts->pOptDesc + eqv_od->optActualIndex)->pz_Name); + return FAILURE; + } + } else { + /* + * Set the equivalenced-to actual option index to no-equivalent + * so that we set all the entries below. This option may either + * never have been selected before, or else it was selected by + * some sort of "presetting" mechanism. + */ + eqv_od->optActualIndex = NO_EQUIVALENT; + } + + if (eqv_od->optActualIndex != od->optIndex) { + /* + * First time through, copy over the state + * and add in the equivalence flag + */ + eqv_od->optActualValue = od->optValue; + eqv_od->optActualIndex = od->optIndex; + o_st->flags |= OPTST_EQUIVALENCE; + } + + /* + * Copy the most recent option argument. set membership state + * is kept in 'eqv_od->optCookie'. Do not overwrite. + */ + eqv_od->optArg.argString = od->optArg.argString; + od = eqv_od; + + } else { + od->optActualValue = od->optValue; + od->optActualIndex = od->optIndex; + } + + od->fOptState &= OPTST_PERSISTENT_MASK; + od->fOptState |= (o_st->flags & ~OPTST_PERSISTENT_MASK); + + /* + * Keep track of count only for DEFINED (command line) options. + * IF we have too many, build up an error message and bail. + */ + if ( (od->fOptState & OPTST_DEFINED) + && (++od->optOccCt > od->optMaxCt) ) + return too_many_occurrences(opts, od); + /* + * If provided a procedure to call, call it + */ + if (opt_proc != NULL) + (*opt_proc)(opts, od); + + return SUCCESS; +} + +/** + * Find the option descriptor and option argument (if any) for the + * next command line argument. DO NOT modify the descriptor. Put + * all the state in the state argument so that the option can be skipped + * without consequence (side effect). + * + * @param opts the program option descriptor + * @param o_st the state of the next found option + */ +static tSuccess +next_opt(tOptions * opts, tOptState * o_st) +{ + { + tSuccess res = find_opt(opts, o_st); + if (! SUCCESSFUL(res)) + return res; + } + + if ( ((o_st->flags & OPTST_DEFINED) != 0) + && ((o_st->pOD->fOptState & OPTST_NO_COMMAND) != 0)) { + fprintf(stderr, zNotCmdOpt, o_st->pOD->pz_Name); + return FAILURE; + } + + return get_opt_arg(opts, o_st); +} + +/** + * Process all the options from our current position onward. (This allows + * interspersed options and arguments for the few non-standard programs that + * require it.) Thus, do not rewind option indexes because some programs + * choose to re-invoke after a non-option. + * + * @param[in,out] opts program options descriptor + * @returns SUCCESS or FAILURE + */ +static tSuccess +regular_opts(tOptions * opts) +{ + /* assert: opts->fOptSet & OPTPROC_IMMEDIATE == 0 */ + for (;;) { + tOptState opt_st = OPTSTATE_INITIALIZER(DEFINED); + + switch (next_opt(opts, &opt_st)) { + case FAILURE: goto failed_option; + case PROBLEM: return SUCCESS; /* no more args */ + case SUCCESS: break; + } + + /* + * IF this is an immediate action option, + * THEN skip it (unless we are supposed to do it a second time). + */ + if (! DO_NORMALLY(opt_st.flags)) { + if (! DO_SECOND_TIME(opt_st.flags)) + continue; + opt_st.pOD->optOccCt--; /* don't count this repetition */ + } + + if (! SUCCESSFUL(handle_opt(opts, &opt_st))) + break; + } failed_option:; + + if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0) + (*opts->pUsageProc)(opts, EXIT_FAILURE); + + return FAILURE; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * THESE ROUTINES ARE CALLABLE FROM THE GENERATED OPTION PROCESSING CODE + */ +/*=--subblock=arg=arg_type,arg_name,arg_desc =*/ +/*=* + * library: opts + * header: your-opts.h + * + * lib_description: + * + * These are the routines that libopts users may call directly from their + * code. There are several other routines that can be called by code + * generated by the libopts option templates, but they are not to be + * called from any other user code. The @file{options.h} header is + * fairly clear about this, too. +=*/ + +/*=export_func optionProcess + * + * what: this is the main option processing routine + * + * arg: + tOptions * + opts + program options descriptor + + * arg: + int + a_ct + program arg count + + * arg: + char ** + a_v + program arg vector + + * + * ret_type: int + * ret_desc: the count of the arguments processed + * + * doc: + * + * This is the main entry point for processing options. It is intended + * that this procedure be called once at the beginning of the execution of + * a program. Depending on options selected earlier, it is sometimes + * necessary to stop and restart option processing, or to select completely + * different sets of options. This can be done easily, but you generally + * do not want to do this. + * + * The number of arguments processed always includes the program name. + * If one of the arguments is "--", then it is counted and the processing + * stops. If an error was encountered and errors are to be tolerated, then + * the returned value is the index of the argument causing the error. + * A hyphen by itself ("-") will also cause processing to stop and will + * @emph{not} be counted among the processed arguments. A hyphen by itself + * is treated as an operand. Encountering an operand stops option + * processing. + * + * err: Errors will cause diagnostics to be printed. @code{exit(3)} may + * or may not be called. It depends upon whether or not the options + * were generated with the "allow-errors" attribute, or if the + * ERRSKIP_OPTERR or ERRSTOP_OPTERR macros were invoked. +=*/ +int +optionProcess(tOptions * opts, int a_ct, char ** a_v) +{ + if (! SUCCESSFUL(validate_struct(opts, a_v[0]))) + ao_bug(zbad_data_msg); + + /* + * Establish the real program name, the program full path, + * and do all the presetting the first time thru only. + */ + if (! ao_initialize(opts, a_ct, a_v)) + return 0; + + /* + * IF we are (re)starting, + * THEN reset option location + */ + if (opts->curOptIdx <= 0) { + opts->curOptIdx = 1; + opts->pzCurOpt = NULL; + } + + if (! SUCCESSFUL(regular_opts(opts))) + return (int)opts->origArgCt; + + /* + * IF there were no errors + * AND we have RC/INI files + * AND there is a request to save the files + * THEN do that now before testing for conflicts. + * (conflicts are ignored in preset options) + */ + switch (opts->specOptIdx.save_opts) { + case 0: + case NO_EQUIVALENT: + break; + default: + { + tOptDesc * od = opts->pOptDesc + opts->specOptIdx.save_opts; + + if (SELECTED_OPT(od)) { + optionSaveFile(opts); + option_exits(EXIT_SUCCESS); + } + } + } + + /* + * IF we are checking for errors, + * THEN look for too few occurrences of required options + */ + if (((opts->fOptSet & OPTPROC_ERRSTOP) != 0) + && (! is_consistent(opts))) + (*opts->pUsageProc)(opts, EXIT_FAILURE); + + return (int)opts->curOptIdx; +} + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/autoopts.c */ diff --git a/autoopts/autoopts.h b/autoopts/autoopts.h new file mode 100644 index 0000000..36bb43f --- /dev/null +++ b/autoopts/autoopts.h @@ -0,0 +1,494 @@ + +/* + * \file autoopts.h + * + * This file defines all the global structures and special values + * used in the automated option processing library. + * + * @group autoopts + * @{ + */ +/* + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +#ifndef AUTOGEN_AUTOOPTS_H +#define AUTOGEN_AUTOOPTS_H +#include + +#define AO_NAME_LIMIT 127 +#define AO_NAME_SIZE ((size_t)(AO_NAME_LIMIT + 1)) + +#ifndef AG_PATH_MAX +# ifdef PATH_MAX +# define AG_PATH_MAX ((size_t)PATH_MAX) +# else +# ifdef __gnu_hurd__ +# define size_t unsigned long +# endif +# define AG_PATH_MAX ((size_t)4096) +# endif +#else +# if defined(PATH_MAX) && (PATH_MAX > MAXPATHLEN) +# undef AG_PATH_MAX +# define AG_PATH_MAX ((size_t)PATH_MAX) +# endif +#endif + +#undef EXPORT +#define EXPORT + +#ifndef NUL +#define NUL '\0' +#endif +#define BEL '\a' +#define BS '\b' +#define HT '\t' +#define LF '\n' +#define VT '\v' +#define FF '\f' +#define CR '\r' + +#if defined(_WIN32) && !defined(__CYGWIN__) +# define DIRCH '\\' +#else +# define DIRCH '/' +#endif + +#ifndef EX_USAGE + /** + * Command line usage problem + */ +# define EX_USAGE 64 +#endif +#ifndef EX_DATAERR + /** + * The input data was incorrect in some way. + */ +# define EX_DATAERR 64 +#endif +#ifndef EX_NOINPUT + /** + * option state was requested from a file that cannot be loaded. + */ +# define EX_NOINPUT 66 +#endif +#ifndef EX_SOFTWARE + /** + * AutoOpts Software failure. + */ +# define EX_SOFTWARE 70 +#endif +#ifndef EX_OSERR + /** + * Command line usage problem + */ +# define EX_OSERR 71 +#endif + +#define NL '\n' +#ifndef C +/** + * Coercive cast. Compel an address to be interpreted as the type + * of the first argument. No complaints, just do it. + */ +#define C(_t,_p) ((_t)VOIDP(_p)) +#endif + +/* The __attribute__((__warn_unused_result__)) feature + is available in gcc versions 3.4 and newer, + while the typeof feature has been available since 2.7 at least. */ +# if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 4) +# define ignore_val(x) ((void) (x)) +# else +# define ignore_val(x) (({ __typeof__ (x) __x = (x); (void) __x; })) +# endif + +/* + * Convert the number to a list usable in a printf call + */ +#define NUM_TO_VER(n) ((n) >> 12), ((n) >> 7) & 0x001F, (n) & 0x007F + +#define NAMED_OPTS(po) \ + (((po)->fOptSet & (OPTPROC_SHORTOPT | OPTPROC_LONGOPT)) == 0) + +#define SKIP_OPT(p) (((p)->fOptState & OPTST_IMMUTABLE_MASK) != 0) + +typedef int tDirection; +/** + * handling option presets. Start with command line and work through + * config settings in reverse order. + */ +#define DIRECTION_PRESET -1 +/** + * handling normal options. Start with first config file, then environment + * variables and finally the command line. + */ +#define DIRECTION_PROCESS 1 +/** + * An initialzation phase or an option being loaded from program sources. + */ +#define DIRECTION_CALLED 0 + +#define PROCESSING(d) ((d)>0) +#define PRESETTING(d) ((d)<0) +#define CALLED(d) ((d)==0) + +/** + * When loading a line (or block) of text as an option, the value can + * be processed in any of several modes. + */ +typedef enum { + /** + * If the value looks like a quoted string, then process it. Double + * quoted strings are processed the way strings are in "C" programs, + * except they are treated as regular characters if the following + * character is not a well-established escape sequence. Single quoted + * strings (quoted with apostrophies) are handled the way strings are + * handled in shell scripts, *except* that backslash escapes are + * honored before backslash escapes and apostrophies. + */ + OPTION_LOAD_COOKED, + + /** + * Even if the value begins with quote characters, do not do quote + * processing. Strip leading and trailing white space. + */ + OPTION_LOAD_UNCOOKED, + + /** + * Keep every part of the value between the delimiters. + */ + OPTION_LOAD_KEEP +} tOptionLoadMode; + +static tOptionLoadMode option_load_mode; + +/** + * The pager state is used by optionPagedUsage() procedure. + * When it runs, it sets itself up to be called again on exit. + * If, however, a routine needs a child process to do some work + * before it is done, then 'pagerState' must be set to + * 'PAGER_STATE_CHILD' so that optionPagedUsage() will not try + * to run the pager program before its time. + */ +typedef enum { + PAGER_STATE_INITIAL, //@< initial option paging state + + /** + * temp file created and optionPagedUsage is scheduled to run at exit + */ + PAGER_STATE_READY, + + /** + * This is a child process used in creating shell script usage. + */ + PAGER_STATE_CHILD +} tePagerState; + +typedef enum { + ENV_ALL, + ENV_IMM, + ENV_NON_IMM +} teEnvPresetType; + +typedef enum { + TOPT_UNDEFINED = 0, + TOPT_SHORT, + TOPT_LONG, + TOPT_DEFAULT +} teOptType; + +typedef struct { + tOptDesc * pOD; + char const * pzOptArg; + opt_state_mask_t flags; + teOptType optType; +} tOptState; +#define OPTSTATE_INITIALIZER(st) \ + { NULL, NULL, OPTST_ ## st, TOPT_UNDEFINED } + +#define TEXTTO_TABLE \ + _TT_(LONGUSAGE) \ + _TT_(USAGE) \ + _TT_(VERSION) +#define _TT_(n) \ + TT_ ## n , + +typedef enum { TEXTTO_TABLE COUNT_TT } teTextTo; + +#undef _TT_ + +/** + * option argument types. Used to create usage information for + * particular options. + */ +typedef struct { + char const * pzStr; + char const * pzReq; + char const * pzNum; + char const * pzFile; + char const * pzKey; + char const * pzKeyL; + char const * pzBool; + char const * pzNest; + char const * pzOpt; + char const * pzNo; + char const * pzBrk; + char const * pzNoF; + char const * pzSpc; + char const * pzOptFmt; + char const * pzTime; +} arg_types_t; + +#define AGALOC(_c, _w) ao_malloc((size_t)_c) +#define AGREALOC(_p, _c, _w) ao_realloc(VOIDP(_p), (size_t)_c) +#define AGFREE(_p) free(VOIDP(_p)) +#define AGDUPSTR(_p, _s, _w) (_p = ao_strdup(_s)) + +static void * +ao_malloc(size_t sz); + +static void * +ao_realloc(void *p, size_t sz); + +#define ao_free(_p) free(VOIDP(_p)) + +static char * +ao_strdup(char const * str); + +/** + * DO option handling? + * + * Options are examined at two times: at immediate handling time and at + * normal handling time. If an option is disabled, the timing may be + * different from the handling of the undisabled option. The OPTST_DIABLED + * bit indicates the state of the currently discovered option. + * So, here's how it works: + * + * A) handling at "immediate" time, either 1 or 2: + * + * 1. OPTST_DISABLED is not set: + * IMM must be set + * DISABLE_IMM don't care + * TWICE don't care + * DISABLE_TWICE don't care + * 0 -and- 1 x x x + * + * 2. OPTST_DISABLED is set: + * IMM don't care + * DISABLE_IMM must be set + * TWICE don't care + * DISABLE_TWICE don't care + * 1 -and- x 1 x x + */ +#define DO_IMMEDIATELY(_flg) \ + ( (((_flg) & (OPTST_DISABLED|OPTST_IMM)) == OPTST_IMM) \ + || ( ((_flg) & (OPTST_DISABLED|OPTST_DISABLE_IMM)) \ + == (OPTST_DISABLED|OPTST_DISABLE_IMM) )) + +/** + * B) handling at "regular" time because it was not immediate + * + * 1. OPTST_DISABLED is not set: + * IMM must *NOT* be set + * DISABLE_IMM don't care + * TWICE don't care + * DISABLE_TWICE don't care + * 0 -and- 0 x x x + * + * 2. OPTST_DISABLED is set: + * IMM don't care + * DISABLE_IMM don't care + * TWICE must be set + * DISABLE_TWICE don't care + * 1 -and- x x 1 x + */ +#define DO_NORMALLY(_flg) ( \ + (((_flg) & (OPTST_DISABLED|OPTST_IMM)) == 0) \ + || (((_flg) & (OPTST_DISABLED|OPTST_DISABLE_IMM)) == \ + OPTST_DISABLED) ) + +/** + * C) handling at "regular" time because it is to be handled twice. + * The immediate bit was already tested and found to be set: + * + * 3. OPTST_DISABLED is not set: + * IMM is set (but don't care) + * DISABLE_IMM don't care + * TWICE must be set + * DISABLE_TWICE don't care + * 0 -and- ? x 1 x + * + * 4. OPTST_DISABLED is set: + * IMM don't care + * DISABLE_IMM is set (but don't care) + * TWICE don't care + * DISABLE_TWICE must be set + * 1 -and- x ? x 1 + */ +#define DO_SECOND_TIME(_flg) ( \ + (((_flg) & (OPTST_DISABLED|OPTST_TWICE)) == \ + OPTST_TWICE) \ + || (((_flg) & (OPTST_DISABLED|OPTST_DISABLE_TWICE)) == \ + (OPTST_DISABLED|OPTST_DISABLE_TWICE) )) + +/* + * text_mmap structure. Only active on platforms with mmap(2). + */ +#ifdef HAVE_SYS_MMAN_H +# include +#else +# ifndef PROT_READ +# define PROT_READ 0x01 +# endif +# ifndef PROT_WRITE +# define PROT_WRITE 0x02 +# endif +# ifndef MAP_SHARED +# define MAP_SHARED 0x01 +# endif +# ifndef MAP_PRIVATE +# define MAP_PRIVATE 0x02 +# endif +#endif + +#ifndef MAP_FAILED +# define MAP_FAILED VOIDP(-1) +#endif + +#ifndef _SC_PAGESIZE +# ifdef _SC_PAGE_SIZE +# define _SC_PAGESIZE _SC_PAGE_SIZE +# endif +#endif + +#ifndef HAVE_STRCHR +extern char * strchr(char const * s, int c); +extern char * strrchr(char const * s, int c); +#endif + +/** + * INQUERY_CALL() tests whether the option handling function has been + * called by an inquery (help text needed, or option being reset), + * or called by a set-the-option operation. + */ +#define INQUERY_CALL(_o, _d) ( \ + ((_o) <= OPTPROC_EMIT_LIMIT) \ + || ((_d) == NULL) \ + || (((_d)->fOptState & OPTST_RESET) != 0) ) + +/** + * Define and initialize all the user visible strings. + * We do not do translations. If translations are to be done, then + * the client will provide a callback for that purpose. + */ +#undef DO_TRANSLATIONS +#include "autoopts/usage-txt.h" + +/** + * File pointer for usage output + */ +FILE * option_usage_fp; +/** + * If provided in the option structure + */ +static char const * program_pkgdatadir; +/** + * privately exported functions + */ +extern tOptProc optionPrintVersion, optionPagedUsage, optionLoadOpt; + +#ifdef AUTOOPTS_INTERNAL + +#ifndef PKGDATADIR +# define PKGDATADIR "" +#endif +#define APOSTROPHE '\'' + +#define OPTPROC_L_N_S (OPTPROC_LONGOPT | OPTPROC_SHORTOPT) +#if defined(ENABLE_NLS) && defined(HAVE_LIBINTL_H) +# include +#endif + +typedef struct { + size_t fnm_len; + uint32_t fnm_mask; + char const * fnm_name; +} ao_flag_names_t; + +/** + * Automated Options Usage Flags. + * NB: no entry may be a prefix of another entry + */ +#define AOFLAG_TABLE \ + _aof_(gnu, OPTPROC_GNUUSAGE ) \ + _aof_(autoopts, ~OPTPROC_GNUUSAGE) \ + _aof_(no_misuse_usage, OPTPROC_MISUSE ) \ + _aof_(misuse_usage, ~OPTPROC_MISUSE ) \ + _aof_(compute, OPTPROC_COMPUTE ) + +#define _aof_(_n, _f) AOUF_ ## _n ## _ID, +typedef enum { AOFLAG_TABLE AOUF_COUNT } ao_flag_id_t; +#undef _aof_ + +#define _aof_(_n, _f) AOUF_ ## _n = (1 << AOUF_ ## _n ## _ID), +typedef enum { AOFLAG_TABLE } ao_flags_t; +#undef _aof_ + +static char const zNil[] = ""; +static arg_types_t argTypes = { NULL }; +static char line_fmt_buf[32]; +static bool displayEnum = false; +static char const pkgdatadir_default[] = PKGDATADIR; +static char const * program_pkgdatadir = pkgdatadir_default; +static tOptionLoadMode option_load_mode = OPTION_LOAD_UNCOOKED; +static tePagerState pagerState = PAGER_STATE_INITIAL; + +static noreturn void option_exits(int exit_code); +static noreturn void fserr_exit(char const * prog, char const * op, + char const * fname); +static void fserr_warn(char const * prog, char const * op, + char const * fname); +static noreturn void ao_bug(char const * msg); + + FILE * option_usage_fp = NULL; + +static char const * pz_enum_err_fmt; + +tOptions * optionParseShellOptions = NULL; + +static char const * shell_prog = NULL; +static char * script_leader = NULL; +static char * script_trailer = NULL; +static char * script_text = NULL; +static bool print_exit = false; +#endif /* AUTOOPTS_INTERNAL */ + +#endif /* AUTOGEN_AUTOOPTS_H */ +/** + * @} + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/autoopts.h */ diff --git a/autoopts/autoopts.m4 b/autoopts/autoopts.m4 new file mode 100644 index 0000000..065f4c3 --- /dev/null +++ b/autoopts/autoopts.m4 @@ -0,0 +1,223 @@ +dnl -*- Mode: M4 -*- +dnl -------------------------------------------------------------------- +dnl autoopts.m4 --- Configure paths for autoopts +dnl +dnl Author: Gary V. Vaughan +dnl This file is part of AutoOpts, a companion to AutoGen. +dnl AutoOpts is free software. +dnl AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +dnl +dnl AutoOpts is available under any one of two licenses. The license +dnl in use must be one of these two and the choice is under the control +dnl of the user of the license. +dnl +dnl The GNU Lesser General Public License, version 3 or later +dnl See the files "COPYING.lgplv3" and "COPYING.gplv3" +dnl +dnl The Modified Berkeley Software Distribution License +dnl See the file "COPYING.mbsd" +dnl +dnl These files have the following sha256 sums: +dnl +dnl 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +dnl 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +dnl 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd +dnl -------------------------------------------------------------------- +dnl Code: + +# serial 1 + +dnl AG_PATH_AUTOOPTS([MIN-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) +dnl Test for AUTOOPTS, and define AUTOGEN, AUTOOPTS_CFLAGS, AUTOGEN_LDFLAGS +dnl and AUTOOPTS_LIBS. +dnl +AC_DEFUN([AG_PATH_AUTOOPTS], +[dnl Get the cflags and libraries from the autoopts-config script +AC_ARG_WITH(opts-prefix, +[ --with-opts-prefix=PFX Prefix where autoopts is installed (optional)]) + +AC_ARG_WITH(opts-exec-prefix, +[ --with-opts-exec-prefix=PFX + Exec prefix where autoopts is installed (optional)]) + +AC_ARG_ENABLE(opts-test, +[ --disable-opts-test Do not try to run a test AutoOpts program]) + + if test x$with_opts_exec_prefix != x ; then + aocfg_args="$aocfg_args --exec-prefix=$with_opts_exec_prefix" + if test x${AUTOOPTS_CONFIG+set} != xset ; then + AUTOOPTS_CONFIG=$with_opts_exec_prefix/bin/autoopts-config + fi + fi + if test x$with_opts_prefix != x ; then + aocfg_args="$aocfg_args --prefix=$with_opts_prefix" + if test x${AUTOOPTS_CONFIG+set} != xset ; then + AUTOOPTS_CONFIG=$with_opts_prefix/bin/autoopts-config + fi + fi + if test -n "$AUTOOPTS_CONFIG"; then + : + else + AC_PATH_PROG(AUTOOPTS_CONFIG, autoopts-config, no) + fi + AC_MSG_CHECKING(for compatible autoopts version)[ + no_autoopts="" + if test "$AUTOOPTS_CONFIG" = "no" ; then + no_autoopts=yes + else + AUTOGEN=`$AUTOOPTS_CONFIG $aocfg_args --autogen` + AUTOOPTS_CFLAGS=`$AUTOOPTS_CONFIG $aocfg_args --cflags` + AUTOGEN_LDFLAGS=`$AUTOOPTS_CONFIG $aocfg_args --pkgdatadir` + AUTOOPTS_LIBS=`$AUTOOPTS_CONFIG $aocfg_args --libs` + aocfg_version=`$AUTOOPTS_CONFIG $aocfg_args --version` + save_IFS=$IFS + IFS=' :' + set -- $aocfg_version + IFS=$save_IFS + aocfg_current=$1 + aocfg_revision=$2 + aocfg_age=$3 + aocfg_currev=$1.$2 + if test "x$enable_opts_test" != "xno" ; then + AC_LANG_SAVE + AC_LANG_C + ac_save_CFLAGS="$CFLAGS" + ac_save_LDFLAGS="$LDFLAGS" + ac_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $AUTOOPTS_CFLAGS" + LDFLAGS="$LDFLAGS $AUTOOPTS $CFLAGS" + LIBS="$LIBS $AUTOOPTS_LIBS"] + dnl + dnl Now check if the installed AUTOOPTS is sufficiently new. (Also + dnl sanity checks the results of autoopts-config to some extent. + dnl + rm -f confopts.def conf.optstest + AC_TRY_RUN([ +#include +#include +#include +#include +#ifndef OPTIONS_VER_TO_NUM +#define OPTIONS_VER_TO_NUM(_v, _r) (((_v) * 4096) + (_r)) +#endif + +static char const zBadVer[] = "\n\\ +*** 'autoopts-config --version' returned $aocfg_version,\n\\ +*** but autoopts returned %d:%d:0\n\\ +*** and the header file says %s\n\\ +*** These should all be consistent.\n\n\\ +*** If autoopts-config was correct, then it is best to remove the old version\n\\ +*** of autoopts. You may also be able to fix the error by modifying your\n\\ +*** LD_LIBRARY_PATH enviroment variable, or by editing /etc/ld.so.conf.\n\\ +*** Make sure you have run ldconfig if that is required on your system.\n\\ +*** Otherwise, set the environment variable AUTOOPTS_CONFIG to point to\n\\ +*** the correct copy of autoopts-config, and remove the file config.cache\n\\ +*** before re-running configure.\n"; + +int +main (int argc, char ** argv) +{ + int current, revision, ct; + char tmp_version[256]; + + system ("touch conf.optstest"); + + /* + * Test liked library against header file + */ + strcpy(tmp_version, optionVersion()); + ct = sscanf(tmp_version, "%d.%d", ¤t, &revision); + if (ct != 2) { + printf("bad version string: -->>%s<<-- != -->>$aocfg_currev<<--\n", + optionVersion()); + return 1; + } + + if (OPTIONS_VER_TO_NUM(current, revision) != OPTIONS_STRUCT_VERSION) { + printf(zBadVer, current, revision, OPTIONS_VERSION_STRING); + return 1; + } + + /* + * Test autoopts-config against header version + */ + if ( OPTIONS_VER_TO_NUM($aocfg_current, $aocfg_revision) + != OPTIONS_STRUCT_VERSION) { + printf("*** autoopts header file version "OPTIONS_VERSION_STRING"\n" + "*** does not match autoopts-config value $aocfg_version\n" + "*** library version is %d:%d\n", current, revision); + return 1; + } + + return 0; +} +],, no_autoopts=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) + CFLAGS="$ac_save_CFLAGS" + LDFLAGS="$ac_save_LDFLAGS" + LIBS="$ac_save_LIBS" + AC_LANG_RESTORE + fi + fi + + if test "x$no_autoopts" = x ; then + AC_MSG_RESULT(yes) + ifelse([$2], , :, [$2]) + else + AC_MSG_RESULT(no) + if test "$AUTOOPTS_CONFIG" = "no" ; then + cat <<- _EOF_ + *** The autoopts-config script installed by AutoGen could not be found + *** If AutoGen was installed in PREFIX, make sure PREFIX/bin is in + *** your path, or set the AUTOOPTS_CONFIG environment variable to the + *** full path to autoopts-config. + _EOF_ + else + if test -f conf.optstest ; then + : + else + echo "*** Could not run autoopts test program, checking why..." + CFLAGS="$CFLAGS $AUTOOPTS_CFLAGS" + LIBS="$LIBS $AUTOOPTS_LIBS" + AC_LANG_SAVE + AC_LANG_C + AC_TRY_LINK([ +#include +#include +], [return strcmp("$aocfg_current:$aocfg_revision:$aocfg_age", optionVersion());], + [ cat << _EOF_ +*** The test program compiled, but did not run. This usually means that +*** the run-time linker is not finding libopts or finding the wrong version +*** of libopts. If it is not finding libopts, you'll need to set your +*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point +*** to the installed location Also, make sure you have run ldconfig if that +*** is required on your system +*** +*** If you have an old version installed, it is best to remove it, although +*** you may also be able to get things to work by modifying LD_LIBRARY_PATH +_EOF_ +], [cat << _EOF_ +*** The test program failed to compile or link. See the file config.log for +*** the exact error that occured. This usually means AutoGen was incorrectly +*** installed or that you have moved libopts since it was installed. In the +*** latter case, you may want to edit the autoopts-config script: +*** $AUTOOPTS_CONFIG +_EOF_ +]) + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" + AC_LANG_RESTORE + fi + fi + AUTOGEN=: + AUTOOPTS_CFLAGS="" + AUTOOPTS_LIBS="" + ifelse([$3], , :, [$3]) + fi + AC_SUBST(AUTOGEN) + AC_SUBST(AUTOOPTS_CFLAGS) + AC_SUBST(AUTOGEN_LDFLAGS) + AC_SUBST(AUTOOPTS_LIBS) + rm -f confopts.def conf.optstest +]) +dnl +dnl autoopts.m4 ends here diff --git a/autoopts/autoopts/options.h b/autoopts/autoopts/options.h new file mode 100644 index 0000000..08dc546 --- /dev/null +++ b/autoopts/autoopts/options.h @@ -0,0 +1,1263 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * DO NOT EDIT THIS FILE (options.h) + * + * It has been AutoGen-ed + * From the definitions funcs.def + * and the template file options_h + * + * This file defines all the global structures and special values + * used in the automated option processing library. + * + * Automated Options Copyright (C) 1992-2018 by Bruce Korb + * + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ +#ifndef AUTOOPTS_OPTIONS_H_GUARD +#define AUTOOPTS_OPTIONS_H_GUARD 1 +/** \file options.h + * + * @addtogroup autoopts + * @{ + */ +#include +#include + +#ifndef COMPAT_H_GUARD +/* + * This is needed for test compilations where the "compat.h" + * header is not usually available. + */ +# if defined(HAVE_STDINT_H) +# include +# elif defined(HAVE_INTTYPES_H) +# include +# endif /* HAVE_STDINT/INTTYPES_H */ + +# if defined(HAVE_LIMITS_H) +# include +# elif defined(HAVE_SYS_LIMITS_H) +# include +# endif /* HAVE_LIMITS/SYS_LIMITS_H */ + +# if defined(HAVE_SYSEXITS_H) +# include +# endif /* HAVE_SYSEXITS_H */ + +# if defined(HAVE_STDBOOL_H) +# include +# elif ! defined(bool) + typedef enum { false = 0, true = 1 } _Bool; +# define bool _Bool + + /* The other macros must be usable in preprocessor directives. */ +# define false 0 +# define true 1 +# endif /* HAVE_SYSEXITS_H */ +#endif /* COMPAT_H_GUARD */ +// END-CONFIGURED-HEADERS + +/** + * Defined to abnormal value of EX_USAGE. Used to indicate that paged usage + * was requested. It is used to distinguish a --usage from a --help request. + * --usage is abbreviated and --help gives as much help as possible. + */ +#define AO_EXIT_REQ_USAGE 10064 + +#undef VOIDP +/** + * Coerce a value into a void pointer with no const or volatile attributes. + * Somewhere along the line, the above set of includes need to set up + * the "uintptr_t" type. + */ +#define VOIDP(_a) ((void *)(uintptr_t)(_a)) + +/** + * PUBLIC DEFINES + * + * The following defines may be used in applications that need to test the + * state of an option. To test against these masks and values, a pointer + * to an option descriptor must be obtained. There are two ways: + * + * 1. inside an option processing procedure, it is the second argument, + * conventionally "tOptDesc * pOD". + * + * 2. Outside of an option procedure (or to reference a different option + * descriptor), use either "&DESC( opt_name )" or "&pfx_DESC( opt_name )". + * + * See the relevant generated header file to determine which and what + * values for "opt_name" are available. + * @group version + * @{ + */ +/// autoopts structure version +#define OPTIONS_STRUCT_VERSION 172033 +/// autoopts structure version string +#define OPTIONS_VERSION_STRING "42:1:17" +/// minimum version the autoopts library supports +#define OPTIONS_MINIMUM_VERSION 102400 +/// minimum version the autoopts library supports as a string +#define OPTIONS_MIN_VER_STRING "25:0:0" +/// the display version of the autoopts library, as a string +#define OPTIONS_DOTTED_VERSION "42.1" +/// convert a version/release number pair to an integer value +#define OPTIONS_VER_TO_NUM(_v, _r) (((_v) * 4096) + (_r)) +/// @} + +/** + * Option argument types. This must fit in the OPTST_ARG_TYPE_MASK + * field of the fOptState field of an option descriptor (tOptDesc). + * It will be a problem to extend beyond 4 bits. + */ +typedef enum { + OPARG_TYPE_NONE = 0, ///< does not take an argument + OPARG_TYPE_STRING = 1, ///< default type/ vanilla string + OPARG_TYPE_ENUMERATION = 2, ///< opt arg is an enum (keyword list) + OPARG_TYPE_BOOLEAN = 3, ///< opt arg is boolean-valued + OPARG_TYPE_MEMBERSHIP = 4, ///< opt arg sets set membership bits + OPARG_TYPE_NUMERIC = 5, ///< opt arg is a long int + OPARG_TYPE_HIERARCHY = 6, ///< option arg is hierarchical value + OPARG_TYPE_FILE = 7, ///< option arg names a file + OPARG_TYPE_TIME = 8, ///< opt arg is a time duration + OPARG_TYPE_FLOAT = 9, ///< opt arg is a floating point num + OPARG_TYPE_DOUBLE = 10, ///< opt arg is a double prec. float + OPARG_TYPE_LONG_DOUBLE = 11, ///< opt arg is a long double prec. + OPARG_TYPE_LONG_LONG = 12, ///< opt arg is a long long int + OPARG_TYPE_STATIC = 13 ///< +} teOptArgType; + +/** + * value descriptor for sub options + */ +typedef struct optionValue { + teOptArgType valType; ///< which argument type + char * pzName; ///< name of the sub-option + union { + char strVal[1]; ///< OPARG_TYPE_STRING + unsigned int enumVal; ///< OPARG_TYPE_ENUMERATION + unsigned int boolVal; ///< OPARG_TYPE_BOOLEAN + unsigned long setVal; ///< OPARG_TYPE_MEMBERSHIP + long longVal; ///< OPARG_TYPE_NUMERIC + void * nestVal; ///< OPARG_TYPE_HIERARCHY + } v; +} tOptionValue; + +/** + * file argument state and handling. + */ +typedef enum { + FTYPE_MODE_MAY_EXIST = 0x00, ///< may or may not exist + FTYPE_MODE_MUST_EXIST = 0x01, ///< must pre-exist + FTYPE_MODE_MUST_NOT_EXIST = 0x02, ///< must *not* pre-exist + FTYPE_MODE_EXIST_MASK = 0x03, ///< mask for these bits + FTYPE_MODE_NO_OPEN = 0x00, ///< leave file closed + FTYPE_MODE_OPEN_FD = 0x10, ///< call open(2) + FTYPE_MODE_FOPEN_FP = 0x20, ///< call fopen(3) + FTYPE_MODE_OPEN_MASK = 0x30 ///< open/fopen/not open +} teOptFileType; + +/** + * the open flag bits or the mode string, depending on the open type. + */ +typedef union { + int file_flags; ///< open(2) flag bits + char const * file_mode; ///< fopen(3) mode string +} tuFileMode; + +/// initial number of option argument holders to allocate +#define MIN_ARG_ALLOC_CT 6 +/// amount by which to increment the argument holder allocation. +#define INCR_ARG_ALLOC_CT 8 +/** + * an argument list. When an option appears multiple times and + * the values get "stacked". \a apzArgs holds 8 pointers initially + * and is incremented by \a INCR_ARG_ALLOC_CT as needed. + */ +typedef struct { + int useCt; ///< elements in use + + /// allocated elements, mininum \a MIN_ARG_ALLOC_CT + /// steps by \a INCR_ARG_ALLOC_CT + int allocCt; + char const * apzArgs[MIN_ARG_ALLOC_CT]; ///< element array +} tArgList; + +/** + * Bits in the fOptState option descriptor field. + * @{ + */ + +/** integral type for holding opt_state masks */ +typedef uint32_t opt_state_mask_t; + +#define OPTST_ARG_TYPE_SHIFT 12 +/** bits defined for opt_state_mask_t */ +/** Set via the "SET_OPT()" macro */ +#define OPTST_SET 0x0000001U +/** Set via an RC/INI file */ +#define OPTST_PRESET 0x0000002U +/** Set via a command line option */ +#define OPTST_DEFINED 0x0000004U +/** Reset via command line option */ +#define OPTST_RESET 0x0000008U +/** selected by equiv'ed option */ +#define OPTST_EQUIVALENCE 0x0000010U +/** option is in disabled state */ +#define OPTST_DISABLED 0x0000020U +/** pzOptArg was allocated */ +#define OPTST_ALLOC_ARG 0x0000040U +/** option cannot be preset */ +#define OPTST_NO_INIT 0x0000100U +/** opt value (flag) is any digit */ +#define OPTST_NUMBER_OPT 0x0000200U +/** opt uses optionStackArg proc */ +#define OPTST_STACKED 0x0000400U +/** option defaults to enabled */ +#define OPTST_INITENABLED 0x0000800U +/** bit 1 of arg type enum */ +#define OPTST_ARG_TYPE_1 0x0001000U +/** bit 2 of arg type enum */ +#define OPTST_ARG_TYPE_2 0x0002000U +/** bit 3 of arg type enum */ +#define OPTST_ARG_TYPE_3 0x0004000U +/** bit 4 of arg type enum */ +#define OPTST_ARG_TYPE_4 0x0008000U +/** the option arg not required */ +#define OPTST_ARG_OPTIONAL 0x0010000U +/** process opt on first pass */ +#define OPTST_IMM 0x0020000U +/** process disablement immed. */ +#define OPTST_DISABLE_IMM 0x0040000U +/** compiled out of program */ +#define OPTST_OMITTED 0x0080000U +/** must be set or pre-set */ +#define OPTST_MUST_SET 0x0100000U +/** opt is for doc only */ +#define OPTST_DOCUMENT 0x0200000U +/** process opt twice - imm + reg */ +#define OPTST_TWICE 0x0400000U +/** process disabled option twice */ +#define OPTST_DISABLE_TWICE 0x0800000U +/** scaled integer value */ +#define OPTST_SCALED_NUM 0x1000000U +/** disable from cmd line */ +#define OPTST_NO_COMMAND 0x2000000U +/** support is being removed */ +#define OPTST_DEPRECATED 0x4000000U +/** alias for other option */ +#define OPTST_ALIAS 0x8000000U + +/** bits in SET mask: + * set preset reset defined */ +#define OPTST_SET_MASK 0x000000FU + +/** bits in MUTABLE mask: + * set preset reset defined equivalence disabled + * alloc_arg */ +#define OPTST_MUTABLE_MASK 0x000007FU + +/** bits omitted from PERSISTENT mask: + * mutable_mask */ +#define OPTST_PERSISTENT_MASK 0xFFFFF00U + +/** bits in SELECTED mask: + * set defined */ +#define OPTST_SELECTED_MASK 0x0000005U + +/** bits in ARG_TYPE mask: + * arg_type_1 arg_type_2 arg_type_3 arg_type_4 */ +#define OPTST_ARG_TYPE_MASK 0x000F000U + +/** bits in NO_USAGE mask: + * omitted no_command deprecated */ +#define OPTST_NO_USAGE_MASK 0x6080000U + +/** bits in IMMUTABLE mask: + * document omitted */ +#define OPTST_IMMUTABLE_MASK 0x0280000U + +/** bits in DO_NOT_SAVE mask: + * document omitted no_init */ +#define OPTST_DO_NOT_SAVE_MASK 0x0280100U + +/** bits in NO_OUTPUT mask: + * document omitted alias */ +#define OPTST_NO_OUTPUT_MASK 0x8280000U + +/** all bits in opt_state_mask_t masks */ +#define OPTST_MASK_ALL 0xFFFFF7FU + +/** no bits in opt_state_mask_t */ +#define OPTST_INIT 0x0000000U +/** @} */ + +#ifdef NO_OPTIONAL_OPT_ARGS +# undef OPTST_ARG_OPTIONAL +# define OPTST_ARG_OPTIONAL 0 +#endif + +#define VENDOR_OPTION_VALUE 'W' + +#define SELECTED_OPT(_od) ((_od)->fOptState & OPTST_SELECTED_MASK) +#define UNUSED_OPT( _od) (((_od)->fOptState & OPTST_SET_MASK) == 0) +#define DISABLED_OPT(_od) ((_od)->fOptState & OPTST_DISABLED) +#define OPTION_STATE(_od) ((_od)->fOptState) +#define OPTST_SET_ARGTYPE(_n) ((_n) << OPTST_ARG_TYPE_SHIFT) +#define OPTST_GET_ARGTYPE(_f) \ + (((_f)&OPTST_ARG_TYPE_MASK) >> OPTST_ARG_TYPE_SHIFT) + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * PRIVATE INTERFACES + * + * The following values are used in the generated code to communicate + * with the option library procedures. They are not for public use + * and may be subject to change. + */ + +/** + * Define the processing state flags + * @{ + */ + +/** integral type for holding proc_state masks */ +typedef uint32_t proc_state_mask_t; + +/** bits defined for proc_state_mask_t */ +/** Process long style options */ +#define OPTPROC_LONGOPT 0x000001U +/** Process short style "flags" */ +#define OPTPROC_SHORTOPT 0x000002U +/** Stop on argument errors */ +#define OPTPROC_ERRSTOP 0x000004U +/** Current option is disabled */ +#define OPTPROC_DISABLEDOPT 0x000008U +/** no options are required */ +#define OPTPROC_NO_REQ_OPT 0x000010U +/** there is a number option */ +#define OPTPROC_NUM_OPT 0x000020U +/** have inits been done? */ +#define OPTPROC_INITDONE 0x000040U +/** any negation options? */ +#define OPTPROC_NEGATIONS 0x000080U +/** check environment? */ +#define OPTPROC_ENVIRON 0x000100U +/** Disallow remaining arguments */ +#define OPTPROC_NO_ARGS 0x000200U +/** Require args after options */ +#define OPTPROC_ARGS_REQ 0x000400U +/** reorder operands after opts */ +#define OPTPROC_REORDER 0x000800U +/** emit usage in GNU style */ +#define OPTPROC_GNUUSAGE 0x001000U +/** Translate strings in tOptions */ +#define OPTPROC_TRANSLATE 0x002000U +/** no usage on usage error */ +#define OPTPROC_MISUSE 0x004000U +/** immediate options active */ +#define OPTPROC_IMMEDIATE 0x008000U +/** suppress for config only */ +#define OPTPROC_NXLAT_OPT_CFG 0x010000U +/** suppress xlation always */ +#define OPTPROC_NXLAT_OPT 0x020000U +/** vendor options active */ +#define OPTPROC_VENDOR_OPT 0x040000U +/** opt processing in preset state */ +#define OPTPROC_PRESETTING 0x080000U +/** Ignore pzFullUsage, compute usage text */ +#define OPTPROC_COMPUTE 0x100000U +/** Program outputs digested option state for shell scripts. Usage text + * always written to stderr */ +#define OPTPROC_SHELL_OUTPUT 0x200000U + +/** bits in NO_XLAT mask: + * nxlat_opt_cfg nxlat_opt */ +#define OPTPROC_NO_XLAT_MASK 0x030000U + +/** all bits in proc_state_mask_t masks */ +#define OPTPROC_MASK_ALL 0x3FFFFFU + +/** no bits in proc_state_mask_t */ +#define OPTPROC_NONE 0x000000U +/** @} */ + +#define STMTS(s) do { s; } while (false) + +/** + * Abbreviation for const memory character. + */ +#define tCC char const + +/** + * Magical values for the program's option pointer + * @{ + */ +typedef enum { + OP_VAL_EMIT_USAGE = 1, ///< request for usage + OP_VAL_EMIT_SHELL = 2, ///< emit value for Bourne shell evaluation + OP_VAL_RETURN_VALNAME = 3, ///< return the value as a string + OP_VAL_EMIT_LIMIT = 15 ///< limit for magic values +} opt_proc_vals_t; + +/// \a OPT_VAL_EMIT_USAGE cast as a pointer +#define OPTPROC_EMIT_USAGE ((tOptions *)OP_VAL_EMIT_USAGE) + +/// \a OPT_VAL_EMIT_SHELL cast as a pointer +#define OPTPROC_EMIT_SHELL ((tOptions *)OP_VAL_EMIT_SHELL) + +/// \a OPT_VAL_RETURN_VALNAME cast as a pointer +#define OPTPROC_RETURN_VALNAME ((tOptions *)OP_VAL_RETURN_VALNAME) + +/// \a OPT_VAL_EMIT_LIMIT cast as a pointer +#define OPTPROC_EMIT_LIMIT ((tOptions *)OP_VAL_EMIT_LIMIT) +/** @} */ + +/** group option processing procedure types + * @{ + */ +/** forward declaration for tOptDesc */ +typedef struct opt_desc tOptDesc; +/** forward declaration for tOptiond */ +typedef struct options tOptions; + +/** + * The option procedures do the special processing for each + * option flag that needs it. + */ +typedef void (tOptProc)(tOptions * pOpts, tOptDesc * pOptDesc); + +/** + * a pointer to an option processing procedure + */ +typedef tOptProc * tpOptProc; + +/** + * The usage procedure will never return. It calls "exit(2)" + * with the "exitCode" argument passed to it. + */ +// coverity[+kill] +typedef void (tUsageProc)(tOptions * pOpts, int exitCode); + +/** + * a pointer to a procedure that prints usage and exits. + */ +typedef tUsageProc * tpUsageProc; +/** @} */ + +/** + * Special definitions. "NOLIMIT" is the 'max' value to use when + * a flag may appear multiple times without limit. "NO_EQUIVALENT" + * is an illegal value for 'optIndex' (option description index). + * @{ + */ +#define NOLIMIT USHRT_MAX ///< no occurrance count limit +#define OPTION_LIMIT SHRT_MAX ///< maximum number of option types +/// option index to indicate no equivalance or alias +#define NO_EQUIVALENT (OPTION_LIMIT+1) +/** @} */ + +/** + * Option argument value. Which is valid is determined by: + * (fOptState & OPTST_ARG_TYPE_MASK) >> OPTST_ARG_TYPE_SHIFT + * which will yield one of the teOptArgType values. + */ +typedef union { + char const * argString; ///< as a string + uintptr_t argEnum; ///< as an enumeration value + uintptr_t argIntptr; ///< as an integer big enough to hold pointer + long argInt; ///< as a long integer + unsigned long argUint; ///< as an unsigned long ingeger + unsigned int argBool; ///< as a boolean value + FILE * argFp; ///< as a FILE * pointer + int argFd; ///< as a file descriptor (int) +} opt_arg_union_t; + +/// Compatibility define: \a pzLastArg is now \a optArg.argString +#define pzLastArg optArg.argString +/// The old amorphous argument bucket is now the opt_arg_union_t union. +#define optArgBucket_t opt_arg_union_t + +/** + * Enumeration of AutoOpts defined options. The enumeration is used in + * marking each option that is defined by AutoOpts so libopts can find + * the correct descriptor. This renders \a option_spec_idx_t redundant. + */ +typedef enum { + AOUSE_USER_DEFINED = 0, ///< user specified option + AOUSE_RESET_OPTION, ///< reset option state option + AOUSE_VERSION, ///< request version + AOUSE_HELP, ///< request usage help + AOUSE_MORE_HELP, ///< request paged usage + AOUSE_USAGE, ///< request short usage + AOUSE_SAVE_OPTS, ///< save option state + AOUSE_LOAD_OPTS, ///< load options from file + AOUSE_VENDOR_OPT ///< specify a vendor option +} opt_usage_t; + +/** + * Descriptor structure for each option. + * Only the fields marked "PUBLIC" are for public use. + */ +struct opt_desc { + /// Public, the index of this descriptor + uint16_t const optIndex; + /// Public, the flag character (value) + uint16_t const optValue; + /// Public, the index of the option used to activate option + uint16_t optActualIndex; + /// Public, the flag character of the activating option + uint16_t optActualValue; + + /// Public, the index of the equivalenced-to option. + /// This is NO_EQUIVALENT unless activated. + uint16_t const optEquivIndex; + /// Private, the minimum occurrance count + uint16_t const optMinCt; + /// Private, the maximum occurrance count (NOLIMIT, if unlimited) + uint16_t const optMaxCt; + /// Public, the actual occurrance count + uint16_t optOccCt; + + /// Public, the option processing state + opt_state_mask_t fOptState; + /// Private, how the option is used (opt_usage_t) + uint32_t optUsage; + /// Public, The current option argument value + opt_arg_union_t optArg; + /// Public, data that is actually private to the code that handles + /// this particular option. It is public IFF you have your own + /// handling function. + void * optCookie; + + /// Private, a list of options that must be specified when this option + /// has been specified + int const * const pOptMust; + + /// Private, a list of options that cannot be specified when this option + /// has been specified + int const * const pOptCant; + + /// Private, the function to call for handling this option + tpOptProc const pOptProc; + + /// Private, usage information about this option + char const * const pzText; + + /// Public, the UPPER CASE, shell variable name syntax name of the option + char const * const pz_NAME; + + /// the unmodified name of the option + char const * const pz_Name; + + /// the option name to use to disable the option. Long options names + /// must be active. + char const * const pz_DisableName; + + /// the special prefix that makes the normal option name become the + /// disablement name. + char const * const pz_DisablePfx; +}; + +/** + * Some options need special processing, so we store their + * indexes in a known place. + */ +typedef struct { + uint16_t const more_help; ///< passes help text through pager + uint16_t const save_opts; ///< stores option state to a file + uint16_t const number_option; ///< the option "name" is an integer + /// all arguments are options, this is the default option that must + /// take an argument. That argument is the unrecognized option. + uint16_t const default_opt; +} option_spec_idx_t; + +/** + * The procedure generated for translating option text + */ +typedef void (tOptionXlateProc)(void); + +/** + * Everything marked "PUBLIC" is also marked "const". Public access is not + * a license to modify. Other fields are used and modified by the library. + * They are also subject to change without any notice. + * Do not even look at these outside of libopts. + */ +struct options { + int const structVersion; ///< The version of this struct + unsigned int origArgCt; ///< program argument count + char ** origArgVect; ///< program argument vector + proc_state_mask_t fOptSet; ///< option proc. state flags + unsigned int curOptIdx; ///< current option index + char * pzCurOpt; ///< current option text + + /// Public, the full path of the program + char const * const pzProgPath; + /// Public, the name of the executable, without any path + char const * const pzProgName; + /// Public, the upper-cased, shell variable syntax-ed program name + char const * const pzPROGNAME; + /// the name of the "rc file" (configuration file) + char const * const pzRcName; + /// the copyright text + char const * const pzCopyright; + /// the full copyright notice + char const * const pzCopyNotice; + /// a string with the program name, project name and version + char const * const pzFullVersion; + /// a list of pointers to directories to search for the config file + char const * const * const papzHomeList; + /// the title line for usage + char const * const pzUsageTitle; + /// some added explanation for what this program is trying to do + char const * const pzExplain; + /// a detailed explanation of the program's purpose, for use when + /// full help has been requested + char const * const pzDetail; + /// The public array of option descriptors + tOptDesc * const pOptDesc; + /// the email address for reporting bugs + char const * const pzBugAddr; + + /// Reserved for future use + void * pExtensions; + /// A copy of the option state when optionSaveState was called. + void * pSavedState; + + /// The procedure to call to print usage text + /* __attribute__((__noreturn__)) */ + // coverity[+kill] + tpUsageProc pUsageProc; + /// The procedure to call to translate translatable option messages + tOptionXlateProc * pTransProc; + + /// Special option indexes. + option_spec_idx_t specOptIdx; + /// the total number of options for the program + int const optCt; + /// The number of "presettable" options, though some may be marked + /// "no-preset". Includes all user specified options, plus a few + /// that are specified by AutoOpts. + int const presetOptCt; + /// user specified full usage text + char const * pzFullUsage; + /// user specifed short usage (usage error triggered) message + char const * pzShortUsage; + /// The option argument settings active when optionSaveState was called + opt_arg_union_t const * const originalOptArgArray; + /// any saved cookie value + void * const * const originalOptArgCookie; + /// the package data directory (e.g. global configuration files) + char const * const pzPkgDataDir; + /// email address of the project packager + char const * const pzPackager; +}; + +/* + * Versions where in various fields first appear: + * ($AO_CURRENT * 4096 + $AO_REVISION, but $AO_REVISION must be zero) + */ +/** + * The version that first stored the original argument vector + */ +#define originalOptArgArray_STRUCT_VERSION 0x20000 /* AO_CURRENT = 32 */ +#define HAS_originalOptArgArray(_opt) \ + ((_opt)->structVersion >= originalOptArgArray_STRUCT_VERSION) + +/** + * The version that first stored the package data directory + */ +#define pzPkgDataDir_STRUCT_VERSION 0x22000 /* AO_CURRENT = 34 */ +#define HAS_pzPkgDataDir(_opt) \ + ((_opt)->structVersion >= pzPkgDataDir_STRUCT_VERSION) + +/** + * The version that first stored the option usage in each option descriptor + */ +#define opt_usage_t_STRUCT_VERSION 0x26000 /* AO_CURRENT = 38 */ +#define HAS_opt_usage_t(_opt) \ + ((_opt)->structVersion >= opt_usage_t_STRUCT_VERSION) + +/** + * "token list" structure returned by "string_tokenize()" + */ +typedef struct { + unsigned long tkn_ct; ///< number of tokens found + unsigned char * tkn_list[1]; ///< array of pointers to tokens +} token_list_t; + +/* + * Hide the interface - it pollutes a POSIX claim, but leave it for + * anyone #include-ing this header + */ +#define strneqvcmp option_strneqvcmp +#define streqvcmp option_streqvcmp +#define streqvmap option_streqvmap +#define strequate option_strequate +#define strtransform option_strtransform + +/** + * Everything needed to be known about an mmap-ed file. + * + * This is an output only structure used by text_mmap and text_munmap. + * Clients must not alter the contents and must provide it to both + * the text_mmap and text_munmap procedures. BE ADVISED: if you are + * mapping the file with PROT_WRITE the NUL byte at the end MIGHT NOT + * BE WRITABLE. In any event, that byte is not be written back + * to the source file. ALSO: if "txt_data" is valid and "txt_errno" + * is not zero, then there *may* not be a terminating NUL. + */ +typedef struct { + void * txt_data; ///< text file data + size_t txt_size; ///< actual file size + size_t txt_full_size; ///< mmaped mem size + int txt_fd; ///< file descriptor + int txt_zero_fd; ///< fd for /dev/zero + int txt_errno; ///< warning code + int txt_prot; ///< "prot" flags + int txt_flags; ///< mapping type +} tmap_info_t; + +/** + * mmap result wrapper that yields "true" when mmap has failed. + */ +#define TEXT_MMAP_FAILED_ADDR(a) (VOIDP(a) == VOIDP(MAP_FAILED)) + +#ifdef __cplusplus +#define CPLUSPLUS_OPENER extern "C" { +CPLUSPLUS_OPENER +#define CPLUSPLUS_CLOSER } +#else +#define CPLUSPLUS_CLOSER +#endif + +/** + * The following routines may be coded into AutoOpts client code: + */ + +/** + * ao_string_tokenize - tokenize an input string + * + * This function will convert one input string into a list of strings. + * The list of strings is derived by separating the input based on + * white space separation. However, if the input contains either single + * or double quote characters, then the text after that character up to + * a matching quote will become the string in the list. + * + * The returned pointer should be deallocated with @code{free(3C)} when + * are done using the data. The data are placed in a single block of + * allocated memory. Do not deallocate individual token/strings. + * + * The structure pointed to will contain at least these two fields: + * @table @samp + * @item tkn_ct + * The number of tokens found in the input string. + * @item tok_list + * An array of @code{tkn_ct + 1} pointers to substring tokens, with + * the last pointer set to NULL. + * @end table + * + * There are two types of quoted strings: single quoted (@code{'}) and + * double quoted (@code{"}). Singly quoted strings are fairly raw in that + * escape characters (@code{\\}) are simply another character, except when + * preceding the following characters: + * @example + * @code{\\} double backslashes reduce to one + * @code{'} incorporates the single quote into the string + * @code{\n} suppresses both the backslash and newline character + * @end example + * + * Double quote strings are formed according to the rules of string + * constants in ANSI-C programs. + * + * @param string string to be tokenized + * + * @return token_list_t * - pointer to a structure that lists each token + */ +extern token_list_t * ao_string_tokenize(char const *); + + +/** + * configFileLoad - parse a configuration file + * + * This routine will load a named configuration file and parse the + * text as a hierarchically valued option. The option descriptor + * created from an option definition file is not used via this interface. + * The returned value is "named" with the input file name and is of + * type "@code{OPARG_TYPE_HIERARCHY}". It may be used in calls to + * @code{optionGetValue()}, @code{optionNextValue()} and + * @code{optionUnloadNested()}. + * + * @param fname the file to load + * + * @return const tOptionValue * - An allocated, compound value structure + */ +extern const tOptionValue * configFileLoad(char const *); + + +/** + * optionFileLoad - Load the locatable config files, in order + * + * This function looks in all the specified directories for a configuration + * file ("rc" file or "ini" file) and processes any found twice. The first + * time through, they are processed in reverse order (last file first). At + * that time, only "immediate action" configurables are processed. For + * example, if the last named file specifies not processing any more + * configuration files, then no more configuration files will be processed. + * Such an option in the @strong{first} named directory will have no effect. + * + * Once the immediate action configurables have been handled, then the + * directories are handled in normal, forward order. In that way, later + * config files can override the settings of earlier config files. + * + * See the AutoOpts documentation for a thorough discussion of the + * config file format. + * + * Configuration files not found or not decipherable are simply ignored. + * + * @param opts program options descriptor + * @param prog program name + * + * @return int - 0 -> SUCCESS, -1 -> FAILURE + */ +extern int optionFileLoad(tOptions *, char const *); + + +/** + * optionFindNextValue - find a hierarcicaly valued option instance + * + * This routine will find the next entry in a nested value option or + * configurable. It will search through the list and return the next entry + * that matches the criteria. + * + * @param odesc an option with a nested arg type + * @param pPrevVal the last entry + * @param name name of value to find + * @param value the matching value + * + * @return const tOptionValue * - a compound value structure + */ +extern const tOptionValue * optionFindNextValue(const tOptDesc *, const tOptionValue *, char const *, char const *); + + +/** + * optionFindValue - find a hierarcicaly valued option instance + * + * This routine will find an entry in a nested value option or configurable. + * It will search through the list and return a matching entry. + * + * @param odesc an option with a nested arg type + * @param name name of value to find + * @param val the matching value + * + * @return const tOptionValue * - a compound value structure + */ +extern const tOptionValue * optionFindValue(const tOptDesc *, char const *, char const *); + + +/** + * optionFree - free allocated option processing memory + * + * AutoOpts sometimes allocates memory and puts pointers to it in the + * option state structures. This routine deallocates all such memory. + * + * @param pOpts program options descriptor + */ +extern void optionFree(tOptions *); + + +/** + * optionGetValue - get a specific value from a hierarcical list + * + * This routine will find an entry in a nested value option or configurable. + * If "valueName" is NULL, then the first entry is returned. Otherwise, + * the first entry with a name that exactly matches the argument will be + * returned. If there is no matching value, NULL is returned and errno is + * set to ENOENT. If the provided option value is not a hierarchical value, + * NULL is also returned and errno is set to EINVAL. + * + * @param pOptValue a hierarchcal value + * @param valueName name of value to get + * + * @return const tOptionValue * - a compound value structure + */ +extern const tOptionValue * optionGetValue(const tOptionValue *, char const *); + + +/** + * optionLoadLine - process a string for an option name and value + * + * This is a client program callable routine for setting options from, for + * example, the contents of a file that they read in. Only one option may + * appear in the text. It will be treated as a normal (non-preset) option. + * + * When passed a pointer to the option struct and a string, it will find + * the option named by the first token on the string and set the option + * argument to the remainder of the string. The caller must NUL terminate + * the string. The caller need not skip over any introductory hyphens. + * Any embedded new lines will be included in the option + * argument. If the input looks like one or more quoted strings, then the + * input will be "cooked". The "cooking" is identical to the string + * formation used in AutoGen definition files (@pxref{basic expression}), + * except that you may not use backquotes. + * + * @param opts program options descriptor + * @param line NUL-terminated text + */ +extern void optionLoadLine(tOptions *, char const *); + + +/** + * optionMemberList - Get the list of members of a bit mask set + * + * This converts the OPT_VALUE_name mask value to a allocated string. + * It is the caller's responsibility to free the string. + * + * @param od the set membership option description + * + * @return char * - the names of the set bits + */ +extern char * optionMemberList(tOptDesc *); + + +/** + * optionNextValue - get the next value from a hierarchical list + * + * This routine will return the next entry after the entry passed in. At the + * end of the list, NULL will be returned. If the entry is not found on the + * list, NULL will be returned and "@var{errno}" will be set to EINVAL. + * The "@var{pOldValue}" must have been gotten from a prior call to this + * routine or to "@code{opitonGetValue()}". + * + * @param pOptValue a hierarchcal list value + * @param pOldValue a value from this list + * + * @return const tOptionValue * - a compound value structure + */ +extern const tOptionValue * optionNextValue(const tOptionValue *, const tOptionValue *); + + +/** + * optionOnlyUsage - Print usage text for just the options + * + * This routine will print only the usage for each option. + * This function may be used when the emitted usage must incorporate + * information not available to AutoOpts. + * + * @param pOpts program options descriptor + * @param ex_code exit code for calling exit(3) + */ +extern void optionOnlyUsage(tOptions *, int); + + +/** + * optionPrintVersion - Print the program version + * + * This routine will print the version to stdout. + * + * @param opts program options descriptor + * @param od the descriptor for this arg + */ +extern void optionPrintVersion(tOptions *, tOptDesc *); + + +/** + * optionPrintVersionAndReturn - Print the program version + * + * This routine will print the version to stdout and return + * instead of exiting. Please see the source for the + * @code{print_ver} funtion for details on selecting how + * verbose to be after this function returns. + * + * @param opts program options descriptor + * @param od the descriptor for this arg + */ +extern void optionPrintVersionAndReturn(tOptions *, tOptDesc *); + + +/** + * optionProcess - this is the main option processing routine + * + * This is the main entry point for processing options. It is intended + * that this procedure be called once at the beginning of the execution of + * a program. Depending on options selected earlier, it is sometimes + * necessary to stop and restart option processing, or to select completely + * different sets of options. This can be done easily, but you generally + * do not want to do this. + * + * The number of arguments processed always includes the program name. + * If one of the arguments is "--", then it is counted and the processing + * stops. If an error was encountered and errors are to be tolerated, then + * the returned value is the index of the argument causing the error. + * A hyphen by itself ("-") will also cause processing to stop and will + * @emph{not} be counted among the processed arguments. A hyphen by itself + * is treated as an operand. Encountering an operand stops option + * processing. + * + * @param opts program options descriptor + * @param a_ct program arg count + * @param a_v program arg vector + * + * @return int - the count of the arguments processed + */ +extern int optionProcess(tOptions *, int, char **); + + +/** + * optionRestore - restore option state from memory copy + * + * Copy back the option state from saved memory. + * The allocated memory is left intact, so this routine can be + * called repeatedly without having to call optionSaveState again. + * If you are restoring a state that was saved before the first call + * to optionProcess(3AO), then you may change the contents of the + * argc/argv parameters to optionProcess. + * + * @param pOpts program options descriptor + */ +extern void optionRestore(tOptions *); + + +/** + * optionSaveFile - saves the option state to a file + * + * This routine will save the state of option processing to a file. The name + * of that file can be specified with the argument to the @code{--save-opts} + * option, or by appending the @code{rcfile} attribute to the last + * @code{homerc} attribute. If no @code{rcfile} attribute was specified, it + * will default to @code{.@i{programname}rc}. If you wish to specify another + * file, you should invoke the @code{SET_OPT_SAVE_OPTS(@i{filename})} macro. + * + * The recommend usage is as follows: + * @example + * optionProcess(&progOptions, argc, argv); + * if (i_want_a_non_standard_place_for_this) + * SET_OPT_SAVE_OPTS("myfilename"); + * optionSaveFile(&progOptions); + * @end example + * + * @param opts program options descriptor + */ +extern void optionSaveFile(tOptions *); + + +/** + * optionSaveState - saves the option state to memory + * + * This routine will allocate enough memory to save the current option + * processing state. If this routine has been called before, that memory + * will be reused. You may only save one copy of the option state. This + * routine may be called before optionProcess(3AO). If you do call it + * before the first call to optionProcess, then you may also change the + * contents of argc/argv after you call optionRestore(3AO) + * + * In fact, more strongly put: it is safest to only use this function + * before having processed any options. In particular, the saving and + * restoring of stacked string arguments and hierarchical values is + * disabled. The values are not saved. + * + * @param pOpts program options descriptor + */ +extern void optionSaveState(tOptions *); + + +/** + * optionUnloadNested - Deallocate the memory for a nested value + * + * A nested value needs to be deallocated. The pointer passed in should + * have been gotten from a call to @code{configFileLoad()} (See + * @pxref{libopts-configFileLoad}). + * + * @param pOptVal the hierarchical value + */ +extern void optionUnloadNested(tOptionValue const *); + + +/** + * optionVersion - return the compiled AutoOpts version number + * + * Returns the full version string compiled into the library. + * The returned string cannot be modified. + * + * @return char const * - the version string in constant memory + */ +extern char const * optionVersion(void); + + +/** + * strequate - map a list of characters to the same value + * + * Each character in the input string get mapped to the first character + * in the string. + * This function name is mapped to option_strequate so as to not conflict + * with the POSIX name space. + * + * @param ch_list characters to equivalence + */ +extern void strequate(char const *); + + +/** + * streqvcmp - compare two strings with an equivalence mapping + * + * Using a character mapping, two strings are compared for "equivalence". + * Each input character is mapped to a comparison character and the + * mapped-to characters are compared for the two NUL terminated input strings. + * This function name is mapped to option_streqvcmp so as to not conflict + * with the POSIX name space. + * + * @param str1 first string + * @param str2 second string + * + * @return int - the difference between two differing characters + */ +extern int streqvcmp(char const *, char const *); + + +/** + * streqvmap - Set the character mappings for the streqv functions + * + * Set the character mapping. If the count (@code{ct}) is set to zero, then + * the map is cleared by setting all entries in the map to their index + * value. Otherwise, the "@code{From}" character is mapped to the "@code{To}" + * character. If @code{ct} is greater than 1, then @code{From} and @code{To} + * are incremented and the process repeated until @code{ct} entries have been + * set. For example, + * @example + * streqvmap('a', 'A', 26); + * @end example + * @noindent + * will alter the mapping so that all English lower case letters + * will map to upper case. + * + * This function name is mapped to option_streqvmap so as to not conflict + * with the POSIX name space. + * + * @param from Input character + * @param to Mapped-to character + * @param ct compare length + */ +extern void streqvmap(char, char, int); + + +/** + * strneqvcmp - compare two strings with an equivalence mapping + * + * Using a character mapping, two strings are compared for "equivalence". + * Each input character is mapped to a comparison character and the + * mapped-to characters are compared for the two NUL terminated input strings. + * The comparison is limited to @code{ct} bytes. + * This function name is mapped to option_strneqvcmp so as to not conflict + * with the POSIX name space. + * + * @param str1 first string + * @param str2 second string + * @param ct compare length + * + * @return int - the difference between two differing characters + */ +extern int strneqvcmp(char const *, char const *, int); + + +/** + * strtransform - convert a string into its mapped-to value + * + * Each character in the input string is mapped and the mapped-to + * character is put into the output. + * This function name is mapped to option_strtransform so as to not conflict + * with the POSIX name space. + * + * The source and destination may be the same. + * + * @param dest output string + * @param src input string + */ +extern void strtransform(char *, char const *); + +/* AutoOpts PRIVATE FUNCTIONS: */ +tOptProc optionStackArg, optionUnstackArg, optionBooleanVal, optionNumericVal; + +extern char * ao_string_cook(char *, int *); + +extern unsigned int ao_string_cook_escape_char(char const *, char *, unsigned int); + +extern void genshelloptUsage(tOptions *, int); + +extern int optionAlias(tOptions *, tOptDesc *, unsigned int); + +extern void optionBooleanVal(tOptions *, tOptDesc *); + +extern uintptr_t optionEnumerationVal(tOptions *, tOptDesc *, char const * const *, unsigned int); + +extern void optionFileCheck(tOptions *, tOptDesc *, teOptFileType, tuFileMode); + +extern char const * optionKeywordName(tOptDesc *, unsigned int); + +extern void optionLoadOpt(tOptions *, tOptDesc *); + +extern bool optionMakePath(char *, int, char const *, char const *); + +extern void optionNestedVal(tOptions *, tOptDesc *); + +extern void optionNumericVal(tOptions *, tOptDesc *); + +extern void optionPagedUsage(tOptions *, tOptDesc *); + +extern void optionParseShell(tOptions *); + +extern void optionPrintParagraphs(char const *, bool, FILE *); + +extern void optionPutShell(tOptions *); + +extern char const * optionQuoteString(char const *, char const *); + +extern void optionResetOpt(tOptions *, tOptDesc *); + +extern void optionSetMembers(tOptions *, tOptDesc *, char const * const *, unsigned int); + +extern void optionShowRange(tOptions *, tOptDesc *, void *, int); + +extern void optionStackArg(tOptions *, tOptDesc *); + +extern void optionTimeDate(tOptions *, tOptDesc *); + +extern void optionTimeVal(tOptions *, tOptDesc *); + +extern void optionUnstackArg(tOptions *, tOptDesc *); + +extern void optionUsage(tOptions *, int); + +extern void optionVendorOption(tOptions *, tOptDesc *); + +extern void optionVersionStderr(tOptions *, tOptDesc *); + +extern void * text_mmap(char const *, int, int, tmap_info_t *); + +extern int text_munmap(tmap_info_t *); + +CPLUSPLUS_CLOSER +#endif /* AUTOOPTS_OPTIONS_H_GUARD */ +/** @} + * + * Local Variables: + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * options.h ends here */ diff --git a/autoopts/autoopts/usage-txt.h b/autoopts/autoopts/usage-txt.h new file mode 100644 index 0000000..e94337d --- /dev/null +++ b/autoopts/autoopts/usage-txt.h @@ -0,0 +1,651 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * DO NOT EDIT THIS FILE (usage-txt.h) + * + * It has been AutoGen-ed + * From the definitions usage-txt.def + * and the template file usage-txt.tpl + * + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2017 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ +/** @file usage-txt.h + * + * This file handles all the bookkeeping required for tracking all the little + * tiny strings used by the AutoOpts library. There are 107 + * of them. This is not versioned because it is entirely internal to the + * library and accessed by client code only in a very well-controlled way: + * they may substitute translated strings using a procedure that steps through + * all the string pointers. + */ +#ifndef AUTOOPTS_USAGE_TXT_H_GUARD +#define AUTOOPTS_USAGE_TXT_H_GUARD 1 + +/* + * One structure to hold all the pointers to all the translatable strings. + */ +typedef struct { + int field_ct; + char * utpz_GnuBoolArg; + char * utpz_GnuKeyArg; + char * utpz_GnuNumArg; + char * utpz_GnuStrArg; + char const * apz_str[103]; +} usage_text_t; + +/* + * Declare the global structure with all the pointers to translatable + * strings and the text array containing untranslatable strings. + */ +extern usage_text_t option_xlateable_txt; +extern char const option_lib_text[4267]; + +#if defined(AUTOOPTS_INTERNAL) +/* + * Provide a mapping from a short name to either the text directly + * (for untranslatable strings), or to pointers to the text, rendering + * them translatable. + */ +#define zalloc_fail (option_xlateable_txt.apz_str[ 0]) +#define zno_opt_arg (option_xlateable_txt.apz_str[ 1]) +#define ztoo_new (option_xlateable_txt.apz_str[ 2]) +#define zwrong_ver (option_xlateable_txt.apz_str[ 3]) +#define zrealloc_fail (option_xlateable_txt.apz_str[ 4]) +#define ztoo_old (option_xlateable_txt.apz_str[ 5]) +#define zao_ver_fmt (option_xlateable_txt.apz_str[ 6]) +#define zao_bug_msg (option_xlateable_txt.apz_str[ 7]) +#define zno_reset (option_xlateable_txt.apz_str[ 8]) +#define zmissing_help_msg (option_xlateable_txt.apz_str[ 9]) +#define zbad_data_msg (option_xlateable_txt.apz_str[ 10]) +#define zbad_arg_type_msg (option_xlateable_txt.apz_str[ 11]) +#define zbad_default_msg (option_xlateable_txt.apz_str[ 12]) +#define zbad_alias_id (option_xlateable_txt.apz_str[ 13]) +#define zambiguous_key (option_xlateable_txt.apz_str[ 14]) +#define zambig_list_msg (option_xlateable_txt.apz_str[ 15]) +#define zambig_opt_fmt (option_xlateable_txt.apz_str[ 16]) +#define zargs_must (option_xlateable_txt.apz_str[ 17]) +#define zat_most (option_xlateable_txt.apz_str[ 18]) +#define zfserr_fmt (option_xlateable_txt.apz_str[ 19]) +#define zinter_proc_pipe (option_xlateable_txt.apz_str[ 20]) +#define zBadVerArg (option_xlateable_txt.apz_str[ 21]) +#define zconflict_fmt (option_xlateable_txt.apz_str[ 22]) +#define zDisabledErr (option_xlateable_txt.apz_str[ 23]) +#define zequiv (option_xlateable_txt.apz_str[ 24]) +#define zGnuBoolArg (option_xlateable_txt.utpz_GnuBoolArg) +#define zGnuKeyArg (option_xlateable_txt.utpz_GnuKeyArg) +#define zGnuNumArg (option_xlateable_txt.utpz_GnuNumArg) +#define zGnuStrArg (option_xlateable_txt.utpz_GnuStrArg) +#define zIllOptChr (option_xlateable_txt.apz_str[ 25]) +#define zIllOptStr (option_xlateable_txt.apz_str[ 26]) +#define zIllVendOptStr (option_xlateable_txt.apz_str[ 27]) +#define zIntRange (option_xlateable_txt.apz_str[ 28]) +#define zbad_od (option_xlateable_txt.apz_str[ 29]) +#define zInvalOptName (option_xlateable_txt.apz_str[ 30]) +#define zMisArg (option_xlateable_txt.apz_str[ 31]) +#define zmultiway_bug (option_xlateable_txt.apz_str[ 32]) +#define zneed_one (option_xlateable_txt.apz_str[ 33]) +#define zNoArg (option_xlateable_txt.apz_str[ 34]) +#define zNoArgs (option_xlateable_txt.apz_str[ 35]) +#define zNoCreat (option_xlateable_txt.apz_str[ 36]) +#define zNoKey (option_xlateable_txt.apz_str[ 37]) +#define zreset_arg (option_xlateable_txt.apz_str[ 38]) +#define zNoStat (option_xlateable_txt.apz_str[ 39]) +#define zNoState (option_xlateable_txt.apz_str[ 40]) +#define zNotCmdOpt (option_xlateable_txt.apz_str[ 41]) +#define zNotDate (option_xlateable_txt.apz_str[ 42]) +#define zNotDuration (option_xlateable_txt.apz_str[ 43]) +#define zneed_more (option_xlateable_txt.apz_str[ 44]) +#define zNotNumber (option_xlateable_txt.apz_str[ 45]) +#define znum_too_large (option_xlateable_txt.apz_str[ 46]) +#define zoffer_usage_fmt (option_xlateable_txt.apz_str[ 47]) +#define zonly_one (option_xlateable_txt.apz_str[ 48]) +#define zstdout_name (option_xlateable_txt.apz_str[ 49]) +#define zstderr_name (option_xlateable_txt.apz_str[ 50]) +#define zwriting (option_xlateable_txt.apz_str[ 51]) +#define zRangeErr (option_xlateable_txt.apz_str[ 52]) +#define zneed_fmt (option_xlateable_txt.apz_str[ 53]) +#define zsave_warn (option_xlateable_txt.apz_str[ 54]) +#define zalt_opt (option_xlateable_txt.apz_str[ 55]) +#define zAuto (option_xlateable_txt.apz_str[ 56]) +#define zDefaultOpt (option_xlateable_txt.apz_str[ 57]) +#define zDis (option_xlateable_txt.apz_str[ 58]) +#define zDisabledOpt (option_xlateable_txt.apz_str[ 59]) +#define zDisabledWhy (option_xlateable_txt.apz_str[ 60]) +#define zEnab (option_xlateable_txt.apz_str[ 61]) +#define ztoo_often_fmt (option_xlateable_txt.apz_str[ 62]) +#define zExamineFmt (option_xlateable_txt.apz_str[ 63]) +#define zFileCannotExist (option_xlateable_txt.apz_str[ 64]) +#define zFileMustExist (option_xlateable_txt.apz_str[ 65]) +#define zFlagOkay (option_xlateable_txt.apz_str[ 66]) +#define zGenshell (option_xlateable_txt.apz_str[ 67]) +#define zLowerBits (option_xlateable_txt.apz_str[ 68]) +#define zMembers (option_xlateable_txt.apz_str[ 69]) +#define zMust (option_xlateable_txt.apz_str[ 70]) +#define zNoFlags (option_xlateable_txt.apz_str[ 71]) +#define zNoLim (option_xlateable_txt.apz_str[ 72]) +#define zNoPreset (option_xlateable_txt.apz_str[ 73]) +#define zNoRq_NoShrtTtl (option_xlateable_txt.apz_str[ 74]) +#define zNoRq_ShrtTtl (option_xlateable_txt.apz_str[ 75]) +#define zNrmOptFmt (option_xlateable_txt.apz_str[ 76]) +#define zNumberOpt (option_xlateable_txt.apz_str[ 77]) +#define zOptsOnly (option_xlateable_txt.apz_str[ 78]) +#define zPathFmt (option_xlateable_txt.apz_str[ 79]) +#define zPlsSendBugs (option_xlateable_txt.apz_str[ 80]) +#define zPreset (option_xlateable_txt.apz_str[ 81]) +#define zPresetIntro (option_xlateable_txt.apz_str[ 82]) +#define zProhib (option_xlateable_txt.apz_str[ 83]) +#define zProhibOne (option_xlateable_txt.apz_str[ 84]) +#define zRange (option_xlateable_txt.apz_str[ 85]) +#define zRangeAbove (option_xlateable_txt.apz_str[ 86]) +#define zRangeExact (option_xlateable_txt.apz_str[ 87]) +#define zRangeLie (option_xlateable_txt.apz_str[ 88]) +#define zRangeOnly (option_xlateable_txt.apz_str[ 89]) +#define zRangeOr (option_xlateable_txt.apz_str[ 90]) +#define zRangeScaled (option_xlateable_txt.apz_str[ 91]) +#define zRangeUpto (option_xlateable_txt.apz_str[ 92]) +#define zReorder (option_xlateable_txt.apz_str[ 93]) +#define zReqOne (option_xlateable_txt.apz_str[ 94]) +#define zReqThese (option_xlateable_txt.apz_str[ 95]) +#define zReq_NoShrtTtl (option_xlateable_txt.apz_str[ 96]) +#define zReq_ShrtTtl (option_xlateable_txt.apz_str[ 97]) +#define zSetMemberSettings (option_xlateable_txt.apz_str[ 98]) +#define zUpTo (option_xlateable_txt.apz_str[ 99]) +#define zValidKeys (option_xlateable_txt.apz_str[100]) +#define zVendIntro (option_xlateable_txt.apz_str[101]) +#define zVendOptsAre (option_xlateable_txt.apz_str[102]) + + /* + * First, set up the strings. Some of these are writable. These are all in + * English. This gets compiled into libopts and is distributed here so that + * xgettext (or equivalents) can extract these strings for translation. + */ +static char eng_zGnuBoolArg[] = "=T/F"; +static char eng_zGnuKeyArg[] = "=KWd"; +static char eng_zGnuNumArg[] = "=num"; +static char eng_zGnuStrArg[] = "=str"; +char const option_lib_text[4267] = +/* 0 */ "allocation of %d bytes failed\n\0" +/* 31 */ "AutoOpts function called without option descriptor\n\0" +/* 83 */ "\tThis exceeds the compiled library version: \0" +/* 129 */ "Automated Options Processing Error!\n" + "\t%s called AutoOpts function with structure version %d:%d:%d.\n\0" +/* 228 */ "realloc of %d bytes at 0x%p failed\n\0" +/* 264 */ "\tThis is less than the minimum library version: \0" +/* 314 */ "Automated Options version %s\n" + "\tCopyright (C) 1999-2017 by Bruce Korb - all rights reserved\n\0" +/* 405 */ "(AutoOpts bug): %s.\n\0" +/* 427 */ "optionResetOpt() called, but reset-option not configured\0" +/* 484 */ "could not locate the 'help' option\0" +/* 519 */ "optionProcess() was called with invalid data\0" +/* 564 */ "invalid argument type specified\0" +/* 596 */ "defaulted to option with optional arg\0" +/* 634 */ "aliasing option is out of range.\0" +/* 667 */ "%s error: the keyword '%s' is ambiguous for %s\n\0" +/* 716 */ " The following options match:\n\0" +/* 748 */ "%s: ambiguous option name: %s (matches %d options)\n\0" +/* 800 */ "%s: Command line arguments required\n\0" +/* 837 */ "%d %s%s options allowed\n\0" +/* 862 */ "%s error %d (%s) calling %s for '%s'\n\0" +/* 900 */ "interprocess pipe\0" +/* 918 */ "error: version option argument '%c' invalid. Use:\n" + "\t'v' - version only\n" + "\t'c' - version and copyright\n" + "\t'n' - version and full copyright notice\n\0" +/* 1060 */ "%s error: the '%s' and '%s' options conflict\n\0" +/* 1107 */ "%s: The '%s' option has been disabled.\0" +/* 1146 */ "-equivalence\0" +/* 1159 */ "%s: illegal option -- %c\n\0" +/* 1185 */ "%s: illegal option -- %s\n\0" +/* 1211 */ "%s: unknown vendor extension option -- %s\n\0" +/* 1254 */ " or an integer from %d through %d\n\0" +/* 1290 */ "%s error: invalid option descriptor for %s\n\0" +/* 1335 */ "%s: invalid option name: %s\n\0" +/* 1364 */ "%s: The '%s' option requires an argument.\n\0" +/* 1407 */ "(AutoOpts bug): Equivalenced option '%s' was equivalenced to both\n" + "\t'%s' and '%s'.\0" +/* 1490 */ "%s error: The %s option is required\n\0" +/* 1528 */ "%s: The '%s' option cannot have an argument.\n\0" +/* 1574 */ "%s: Command line arguments are not allowed.\n\0" +/* 1619 */ "error %d (%s) creating %s\n\0" +/* 1646 */ "%s error: '%s' does not match any %s keywords.\n\0" +/* 1695 */ "%s error: The '%s' option requires an argument.\n\0" +/* 1744 */ "error %d (%s) stat-ing %s\n\0" +/* 1771 */ "%s error: no saved option state\n\0" +/* 1804 */ "'%s' is not a command line option.\n\0" +/* 1840 */ "%s error: '%s' is not a recognizable date/time.\n\0" +/* 1890 */ "%s error: '%s' is not a recognizable time duration.\n\0" +/* 1944 */ "%s error: The %s option must appear %d times.\n\0" +/* 1992 */ "%s error: '%s' is not a recognizable number.\n\0" +/* 2039 */ "%s error: %s exceeds %s keyword count\n\0" +/* 2079 */ "Try '%s %s' for more information.\n\0" +/* 2114 */ "one %s%s option allowed\n\0" +/* 2139 */ "standard output\0" +/* 2155 */ "standard error\0" +/* 2170 */ "write\0" +/* 2176 */ "%s error: %s option value %ld is out of range.\n\0" +/* 2225 */ "%s error: %s option requires the %s option\n\0" +/* 2270 */ "%s warning: cannot save options - %s not regular file\n\0" +/* 2326 */ "\t\t\t\t- an alternate for '%s'\n\0" +/* 2355 */ "Version, usage and configuration options:\0" +/* 2397 */ "\t\t\t\t- default option for unnamed options\n\0" +/* 2439 */ "\t\t\t\t- disabled as '--%s'\n\0" +/* 2465 */ " --- %-14s %s\n\0" +/* 2480 */ "This option has been disabled\0" +/* 2510 */ "\t\t\t\t- enabled by default\n\0" +/* 2536 */ "%s error: only \0" +/* 2553 */ " - examining environment variables named %s_*\n\0" +/* 2600 */ "\t\t\t\t- file must not pre-exist\n\0" +/* 2631 */ "\t\t\t\t- file must pre-exist\n\0" +/* 2658 */ "Options are specified by doubled hyphens and their name or by a single\n" + "hyphen and the flag character.\n\0" +/* 2761 */ "\n" + "= = = = = = = =\n\n" + "This incarnation of genshell will produce\n" + "a shell script to parse the options for %s:\n\n\0" +/* 2867 */ " or an integer mask with any of the lower %d bits set\n\0" +/* 2923 */ "\t\t\t\t- is a set membership option\n\0" +/* 2957 */ "\t\t\t\t- must appear between %d and %d times\n\0" +/* 3000 */ "Options are specified by single or double hyphens and their name.\n\0" +/* 3067 */ "\t\t\t\t- may appear multiple times\n\0" +/* 3100 */ "\t\t\t\t- may not be preset\n\0" +/* 3125 */ " Arg Option-Name Description\n\0" +/* 3160 */ " Flg Arg Option-Name Description\n\0" +/* 3198 */ " %3s %s\0" +/* 3206 */ "The '-#' option may omit the hash char\n\0" +/* 3254 */ "All arguments are named options.\n\0" +/* 3288 */ " - reading file %s\0" +/* 3307 */ "\n" + "Please send bug reports to: <%s>\n\0" +/* 3343 */ "\t\t\t\t- may NOT appear - preset only\n\0" +/* 3379 */ "\n" + "The following option preset mechanisms are supported:\n\0" +/* 3435 */ "prohibits these options:\n\0" +/* 3461 */ "prohibits the option '%s'\n\0" +/* 3488 */ "%s%ld to %ld\0" +/* 3501 */ "%sgreater than or equal to %ld\0" +/* 3532 */ "%s%ld exactly\0" +/* 3546 */ "%sit must lie in one of the ranges:\n\0" +/* 3583 */ "%sit must be in the range:\n\0" +/* 3611 */ ", or\n\0" +/* 3617 */ "%sis scalable with a suffix: k/K/m/M/g/G/t/T\n\0" +/* 3663 */ "%sless than or equal to %ld\0" +/* 3691 */ "Operands and options may be intermixed. They will be reordered.\n\0" +/* 3757 */ "requires the option '%s'\n\0" +/* 3783 */ "requires these options:\n\0" +/* 3808 */ " Arg Option-Name Req? Description\n\0" +/* 3848 */ " Flg Arg Option-Name Req? Description\n\0" +/* 3891 */ "or you may use a numeric representation. Preceding these with a '!'\n" + "will clear the bits, specifying 'none' will clear all bits, and 'all'\n" + "will set them all. Multiple entries may be passed as an option\n" + "argument list.\n\0" +/* 4110 */ "\t\t\t\t- may appear up to %d times\n\0" +/* 4143 */ "The valid \"%s\" option keywords are:\n\0" +/* 4180 */ "The next option supports vendor supported extra options:\0" +/* 4237 */ "These additional options are:"; + +/* + * Now, define (and initialize) the structure that contains + * the pointers to all these strings. + * Aren't you glad you don't maintain this by hand? + */ +usage_text_t option_xlateable_txt = { + 107, + eng_zGnuBoolArg, eng_zGnuKeyArg, eng_zGnuNumArg, eng_zGnuStrArg, + { + option_lib_text + 0, option_lib_text + 31, option_lib_text + 83, + option_lib_text + 129, option_lib_text + 228, option_lib_text + 264, + option_lib_text + 314, option_lib_text + 405, option_lib_text + 427, + option_lib_text + 484, option_lib_text + 519, option_lib_text + 564, + option_lib_text + 596, option_lib_text + 634, option_lib_text + 667, + option_lib_text + 716, option_lib_text + 748, option_lib_text + 800, + option_lib_text + 837, option_lib_text + 862, option_lib_text + 900, + option_lib_text + 918, option_lib_text + 1060, option_lib_text + 1107, + option_lib_text + 1146, option_lib_text + 1159, option_lib_text + 1185, + option_lib_text + 1211, option_lib_text + 1254, option_lib_text + 1290, + option_lib_text + 1335, option_lib_text + 1364, option_lib_text + 1407, + option_lib_text + 1490, option_lib_text + 1528, option_lib_text + 1574, + option_lib_text + 1619, option_lib_text + 1646, option_lib_text + 1695, + option_lib_text + 1744, option_lib_text + 1771, option_lib_text + 1804, + option_lib_text + 1840, option_lib_text + 1890, option_lib_text + 1944, + option_lib_text + 1992, option_lib_text + 2039, option_lib_text + 2079, + option_lib_text + 2114, option_lib_text + 2139, option_lib_text + 2155, + option_lib_text + 2170, option_lib_text + 2176, option_lib_text + 2225, + option_lib_text + 2270, option_lib_text + 2326, option_lib_text + 2355, + option_lib_text + 2397, option_lib_text + 2439, option_lib_text + 2465, + option_lib_text + 2480, option_lib_text + 2510, option_lib_text + 2536, + option_lib_text + 2553, option_lib_text + 2600, option_lib_text + 2631, + option_lib_text + 2658, option_lib_text + 2761, option_lib_text + 2867, + option_lib_text + 2923, option_lib_text + 2957, option_lib_text + 3000, + option_lib_text + 3067, option_lib_text + 3100, option_lib_text + 3125, + option_lib_text + 3160, option_lib_text + 3198, option_lib_text + 3206, + option_lib_text + 3254, option_lib_text + 3288, option_lib_text + 3307, + option_lib_text + 3343, option_lib_text + 3379, option_lib_text + 3435, + option_lib_text + 3461, option_lib_text + 3488, option_lib_text + 3501, + option_lib_text + 3532, option_lib_text + 3546, option_lib_text + 3583, + option_lib_text + 3611, option_lib_text + 3617, option_lib_text + 3663, + option_lib_text + 3691, option_lib_text + 3757, option_lib_text + 3783, + option_lib_text + 3808, option_lib_text + 3848, option_lib_text + 3891, + option_lib_text + 4110, option_lib_text + 4143, option_lib_text + 4180, + option_lib_text + 4237 + } }; +#endif /* AUTOOPTS_INTERNAL */ + +#ifdef XGETTEXT_SCAN_DO_NOT_COMPILE +do not compile this section. +/* TRANSLATORS: The following dummy functions were crated solely so that + * xgettext can extract the correct strings. These strings are actually + * referenced where the preceding "#line" directive states, though you will + * not see the literal string there. The literal string is defined above in + * the @code{option_lib_text} table and referenced via a #define name that + * redirects into the @code{option_xlateable_txt} structure above. When + * translating is activated, the pointers in @code{option_xlateable_txt} are + * updated to point to translated strings. + */ +static void dummy_func(void) { + /* LIBOPTS-MESSAGES: */ +#line 67 "../autoopts.c" + puts(_("allocation of %d bytes failed\n")); +#line 89 "../autoopts.c" + puts(_("allocation of %d bytes failed\n")); +#line 48 "../init.c" + puts(_("AutoOpts function called without option descriptor\n")); +#line 81 "../init.c" + puts(_("\tThis exceeds the compiled library version: ")); +#line 79 "../init.c" + puts(_("Automated Options Processing Error!\n" + "\t%s called AutoOpts function with structure version %d:%d:%d.\n")); +#line 78 "../autoopts.c" + puts(_("realloc of %d bytes at 0x%p failed\n")); +#line 83 "../init.c" + puts(_("\tThis is less than the minimum library version: ")); +#line 121 "../version.c" + puts(_("Automated Options version %s\n" + "\tCopyright (C) 1999-2017 by Bruce Korb - all rights reserved\n")); +#line 49 "../makeshell.c" + puts(_("(AutoOpts bug): %s.\n")); +#line 90 "../reset.c" + puts(_("optionResetOpt() called, but reset-option not configured")); +#line 241 "../usage.c" + puts(_("could not locate the 'help' option")); +#line 330 "../autoopts.c" + puts(_("optionProcess() was called with invalid data")); +#line 697 "../usage.c" + puts(_("invalid argument type specified")); +#line 568 "../find.c" + puts(_("defaulted to option with optional arg")); +#line 76 "../alias.c" + puts(_("aliasing option is out of range.")); +#line 210 "../enum.c" + puts(_("%s error: the keyword '%s' is ambiguous for %s\n")); +#line 78 "../find.c" + puts(_(" The following options match:\n")); +#line 263 "../find.c" + puts(_("%s: ambiguous option name: %s (matches %d options)\n")); +#line 161 "../check.c" + puts(_("%s: Command line arguments required\n")); +#line 43 "../alias.c" + puts(_("%d %s%s options allowed\n")); +#line 56 "../makeshell.c" + puts(_("%s error %d (%s) calling %s for '%s'\n")); +#line 268 "../makeshell.c" + puts(_("interprocess pipe")); +#line 171 "../version.c" + puts(_("error: version option argument '%c' invalid. Use:\n" + "\t'v' - version only\n" + "\t'c' - version and copyright\n" + "\t'n' - version and full copyright notice\n")); +#line 58 "../check.c" + puts(_("%s error: the '%s' and '%s' options conflict\n")); +#line 187 "../find.c" + puts(_("%s: The '%s' option has been disabled.")); +#line 400 "../find.c" + puts(_("%s: The '%s' option has been disabled.")); +#line 38 "../alias.c" + puts(_("-equivalence")); +#line 439 "../find.c" + puts(_("%s: illegal option -- %c\n")); +#line 110 "../reset.c" + puts(_("%s: illegal option -- %c\n")); +#line 241 "../find.c" + puts(_("%s: illegal option -- %s\n")); +#line 740 "../find.c" + puts(_("%s: illegal option -- %s\n")); +#line 118 "../reset.c" + puts(_("%s: illegal option -- %s\n")); +#line 305 "../find.c" + puts(_("%s: unknown vendor extension option -- %s\n")); +#line 135 "../enum.c" + puts(_(" or an integer from %d through %d\n")); +#line 145 "../enum.c" + puts(_(" or an integer from %d through %d\n")); +#line 696 "../usage.c" + puts(_("%s error: invalid option descriptor for %s\n")); +#line 1030 "../usage.c" + puts(_("%s error: invalid option descriptor for %s\n")); +#line 355 "../find.c" + puts(_("%s: invalid option name: %s\n")); +#line 497 "../find.c" + puts(_("%s: The '%s' option requires an argument.\n")); +#line 150 "../autoopts.c" + puts(_("(AutoOpts bug): Equivalenced option '%s' was equivalenced to both\n" + "\t'%s' and '%s'.")); +#line 94 "../check.c" + puts(_("%s error: The %s option is required\n")); +#line 602 "../find.c" + puts(_("%s: The '%s' option cannot have an argument.\n")); +#line 151 "../check.c" + puts(_("%s: Command line arguments are not allowed.\n")); +#line 568 "../save.c" + puts(_("error %d (%s) creating %s\n")); +#line 210 "../enum.c" + puts(_("%s error: '%s' does not match any %s keywords.\n")); +#line 93 "../reset.c" + puts(_("%s error: The '%s' option requires an argument.\n")); +#line 122 "../save.c" + puts(_("error %d (%s) stat-ing %s\n")); +#line 175 "../save.c" + puts(_("error %d (%s) stat-ing %s\n")); +#line 143 "../restore.c" + puts(_("%s error: no saved option state\n")); +#line 225 "../autoopts.c" + puts(_("'%s' is not a command line option.\n")); +#line 113 "../time.c" + puts(_("%s error: '%s' is not a recognizable date/time.\n")); +#line 50 "../time.c" + puts(_("%s error: '%s' is not a recognizable time duration.\n")); +#line 92 "../check.c" + puts(_("%s error: The %s option must appear %d times.\n")); +#line 165 "../numeric.c" + puts(_("%s error: '%s' is not a recognizable number.\n")); +#line 176 "../enum.c" + puts(_("%s error: %s exceeds %s keyword count\n")); +#line 279 "../usage.c" + puts(_("Try '%s %s' for more information.\n")); +#line 45 "../alias.c" + puts(_("one %s%s option allowed\n")); +#line 170 "../makeshell.c" + puts(_("standard output")); +#line 905 "../makeshell.c" + puts(_("standard output")); +#line 223 "../usage.c" + puts(_("standard output")); +#line 364 "../usage.c" + puts(_("standard output")); +#line 574 "../usage.c" + puts(_("standard output")); +#line 178 "../version.c" + puts(_("standard output")); +#line 223 "../usage.c" + puts(_("standard error")); +#line 364 "../usage.c" + puts(_("standard error")); +#line 574 "../usage.c" + puts(_("standard error")); +#line 178 "../version.c" + puts(_("standard error")); +#line 170 "../makeshell.c" + puts(_("write")); +#line 905 "../makeshell.c" + puts(_("write")); +#line 222 "../usage.c" + puts(_("write")); +#line 363 "../usage.c" + puts(_("write")); +#line 573 "../usage.c" + puts(_("write")); +#line 177 "../version.c" + puts(_("write")); +#line 60 "../numeric.c" + puts(_("%s error: %s option value %ld is out of range.\n")); +#line 44 "../check.c" + puts(_("%s error: %s option requires the %s option\n")); +#line 121 "../save.c" + puts(_("%s warning: cannot save options - %s not regular file\n")); +#line 174 "../save.c" + puts(_("%s warning: cannot save options - %s not regular file\n")); +#line 193 "../save.c" + puts(_("%s warning: cannot save options - %s not regular file\n")); +#line 567 "../save.c" + puts(_("%s warning: cannot save options - %s not regular file\n")); + /* END-LIBOPTS-MESSAGES */ + + /* USAGE-TEXT: */ +#line 822 "../usage.c" + puts(_("\t\t\t\t- an alternate for '%s'\n")); +#line 1097 "../usage.c" + puts(_("Version, usage and configuration options:")); +#line 873 "../usage.c" + puts(_("\t\t\t\t- default option for unnamed options\n")); +#line 786 "../usage.c" + puts(_("\t\t\t\t- disabled as '--%s'\n")); +#line 1066 "../usage.c" + puts(_(" --- %-14s %s\n")); +#line 1064 "../usage.c" + puts(_("This option has been disabled")); +#line 813 "../usage.c" + puts(_("\t\t\t\t- enabled by default\n")); +#line 40 "../alias.c" + puts(_("%s error: only ")); +#line 1143 "../usage.c" + puts(_(" - examining environment variables named %s_*\n")); +#line 168 "../file.c" + puts(_("\t\t\t\t- file must not pre-exist\n")); +#line 172 "../file.c" + puts(_("\t\t\t\t- file must pre-exist\n")); +#line 329 "../usage.c" + puts(_("Options are specified by doubled hyphens and their name or by a single\n" + "hyphen and the flag character.\n")); +#line 882 "../makeshell.c" + puts(_("\n" + "= = = = = = = =\n\n" + "This incarnation of genshell will produce\n" + "a shell script to parse the options for %s:\n\n")); +#line 142 "../enum.c" + puts(_(" or an integer mask with any of the lower %d bits set\n")); +#line 846 "../usage.c" + puts(_("\t\t\t\t- is a set membership option\n")); +#line 867 "../usage.c" + puts(_("\t\t\t\t- must appear between %d and %d times\n")); +#line 331 "../usage.c" + puts(_("Options are specified by single or double hyphens and their name.\n")); +#line 853 "../usage.c" + puts(_("\t\t\t\t- may appear multiple times\n")); +#line 840 "../usage.c" + puts(_("\t\t\t\t- may not be preset\n")); +#line 1258 "../usage.c" + puts(_(" Arg Option-Name Description\n")); +#line 1194 "../usage.c" + puts(_(" Flg Arg Option-Name Description\n")); +#line 1252 "../usage.c" + puts(_(" Flg Arg Option-Name Description\n")); +#line 1253 "../usage.c" + puts(_(" %3s %s")); +#line 1259 "../usage.c" + puts(_(" %3s %s")); +#line 336 "../usage.c" + puts(_("The '-#' option may omit the hash char\n")); +#line 332 "../usage.c" + puts(_("All arguments are named options.\n")); +#line 920 "../usage.c" + puts(_(" - reading file %s")); +#line 358 "../usage.c" + puts(_("\n" + "Please send bug reports to: <%s>\n")); +#line 100 "../version.c" + puts(_("\n" + "Please send bug reports to: <%s>\n")); +#line 129 "../version.c" + puts(_("\n" + "Please send bug reports to: <%s>\n")); +#line 852 "../usage.c" + puts(_("\t\t\t\t- may NOT appear - preset only\n")); +#line 893 "../usage.c" + puts(_("\n" + "The following option preset mechanisms are supported:\n")); +#line 1141 "../usage.c" + puts(_("\n" + "The following option preset mechanisms are supported:\n")); +#line 631 "../usage.c" + puts(_("prohibits these options:\n")); +#line 626 "../usage.c" + puts(_("prohibits the option '%s'\n")); +#line 81 "../numeric.c" + puts(_("%s%ld to %ld")); +#line 79 "../numeric.c" + puts(_("%sgreater than or equal to %ld")); +#line 75 "../numeric.c" + puts(_("%s%ld exactly")); +#line 68 "../numeric.c" + puts(_("%sit must lie in one of the ranges:\n")); +#line 68 "../numeric.c" + puts(_("%sit must be in the range:\n")); +#line 88 "../numeric.c" + puts(_(", or\n")); +#line 66 "../numeric.c" + puts(_("%sis scalable with a suffix: k/K/m/M/g/G/t/T\n")); +#line 77 "../numeric.c" + puts(_("%sless than or equal to %ld")); +#line 339 "../usage.c" + puts(_("Operands and options may be intermixed. They will be reordered.\n")); +#line 601 "../usage.c" + puts(_("requires the option '%s'\n")); +#line 604 "../usage.c" + puts(_("requires these options:\n")); +#line 1270 "../usage.c" + puts(_(" Arg Option-Name Req? Description\n")); +#line 1264 "../usage.c" + puts(_(" Flg Arg Option-Name Req? Description\n")); +#line 143 "../enum.c" + puts(_("or you may use a numeric representation. Preceding these with a '!'\n" + "will clear the bits, specifying 'none' will clear all bits, and 'all'\n" + "will set them all. Multiple entries may be passed as an option\n" + "argument list.\n")); +#line 859 "../usage.c" + puts(_("\t\t\t\t- may appear up to %d times\n")); +#line 52 "../enum.c" + puts(_("The valid \"%s\" option keywords are:\n")); +#line 1101 "../usage.c" + puts(_("The next option supports vendor supported extra options:")); +#line 722 "../usage.c" + puts(_("These additional options are:")); + /* END-USAGE-TEXT */ +} +#endif /* XGETTEXT_SCAN_DO_NOT_COMPILE */ +#endif /* AUTOOPTS_USAGE_TXT_H_GUARD */ diff --git a/autoopts/boolean.c b/autoopts/boolean.c new file mode 100644 index 0000000..80e0b0e --- /dev/null +++ b/autoopts/boolean.c @@ -0,0 +1,95 @@ + +/** + * \file boolean.c + * + * Handle options with true/false values for arguments. + * + * @addtogroup autoopts + * @{ + */ +/* + * This routine will run run-on options through a pager so the + * user may examine, print or edit them at their leisure. + * + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +/*=export_func optionBooleanVal + * private: + * + * what: Decipher a boolean value + * arg: + tOptions * + opts + program options descriptor + + * arg: + tOptDesc * + od + the descriptor for this arg + + * + * doc: + * Decipher a true or false value for a boolean valued option argument. + * The value is true, unless it starts with 'n' or 'f' or "#f" or + * it is an empty string or it is a number that evaluates to zero. +=*/ +void +optionBooleanVal(tOptions * opts, tOptDesc * od) +{ + char * pz; + bool res = true; + + if (INQUERY_CALL(opts, od)) + return; + + if (od->optArg.argString == NULL) { + od->optArg.argBool = false; + return; + } + + switch (*(od->optArg.argString)) { + case '0': + { + long val = strtol(od->optArg.argString, &pz, 0); + if ((val != 0) || (*pz != NUL)) + break; + } + /* FALLTHROUGH */ + case 'N': + case 'n': + case 'F': + case 'f': + case NUL: + res = false; + break; + case '#': + if (od->optArg.argString[1] != 'f') + break; + res = false; + } + + if (od->fOptState & OPTST_ALLOC_ARG) { + AGFREE(od->optArg.argString); + od->fOptState &= ~OPTST_ALLOC_ARG; + } + od->optArg.argBool = res; +} +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/boolean.c */ diff --git a/autoopts/bootstrap.dir b/autoopts/bootstrap.dir new file mode 100644 index 0000000..8eb579e --- /dev/null +++ b/autoopts/bootstrap.dir @@ -0,0 +1,259 @@ +#! /bin/echo This_file_must_be_sourced,_not_executed +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +burn_aover() { + agvars=$(egrep '^A[GO]_' ../VERSION) + eval "${agvars}" + vers_curr=$(expr '(' $AO_CURRENT '*' 4096 ')' + $AO_REVISION) + + cd tpl + for f in *.sh *.pl *.pm + do g=${f%.sh} ; g=${g%.pl} + test "$f" = "$g" || { + cat $f > $g + chmod +x $g + } + done + cd - +} + +add_files_to_mf() { + # Regenerate the "genshell.h" 'cuz we just altered the template to + # contain the header version number. + # + ${ag_aopts} -Tagman3.tpl funcs.def || \ + die "FAILED: ${ag_aopts} -Tagman3.tpl funcs.def" + + local tmpl=$( + ndst="" + sfil='' + pdta="autoopts.m4${nl}tpl/usage.tlib${nl}" + edta="bootstrap.dir${nl}autoopts-config.in${nl}autogen.map${nl}" + edta="${edta}mk-tpl-config.sh${nl}mk-autoopts-pc.in${nl}" + edta="${edta}install-hook.sh${nl}po${nl}" + + for f in man mdoc texi + do + for g in man mdoc texi + do + sfil=${sfil}tpl/${f}2${g}${nl} + done + done + + for f in tpl/*.* + do + case $f in + ( tpl-config* ) : ;; + + ( *.in | *.pl | *.sh ) + g=${f%.??} + g=${g//-tlib/.tlib} + ndst+=${g}${nl} # installed file + edta+=${f}${nl} # distributed file + ;; + + ( *tpl-config.tlib | *tpl/usage* ) : ;; + + ( *.tlib | *.tpl | *.def | *.lic | *.pm ) + pdta=${pdta}${f}${nl} ;; # installed & distributed file + esac + done + + echo "local ndst='${ndst%${nl}}'" + echo "local pdta='${pdta%${nl}}'" + echo "local edta='${edta%${nl}}'" + echo "local sfil='${sfil%${nl}}'" + ) + + eval "$tmpl" + + { + ls -1 *.3 | \ + sed '/^pathfind.3$/d' | \ + columns -I4 --spread=1 --line=' \' + + printf '\nnodist_pkgdata_DATA = $(libsrc) \\\n' + echo "${ndst}" | sort -u | columns -I4 --spread=1 --line=' \' + + printf '\nnodist_libdata_DATA = %s\n' tpl/tpl-config.tlib + + printf '\npkgdata_DATA = \\\n' + echo "${pdta}" | sort -u | columns -I4 --spread=1 --line=' \' + + printf '\nEXTRA_DATA = $(pkgdata_DATA) \\\n' + echo "${edta}" | sort -u | columns -I4 --spread=1 --line=' \' + + printf '\nGENSCRIPTS = $(srcdir)/funcs.def \\\n' + echo "${sfil}" | columns -I4 --spread=1 --line=' \' + echo + + sed -n '/^## begin/,/^## end/{ + s/^##.*// + /^$/d + p + }' gnulib.mk + + } > Makefile.lists + + sed '/^GENMAN /r Makefile.lists' Makefile.am.pre > Makefile.am + rm -f Makefile.lists gnulib.mk *.3 +} + +make_funcs_def() +{ + ${char_mapper:-char-mapper} autogen.map || die "FAILED: char-mapper" + ${ag_aopts} save-flags.def || die "cannot rebuild save-flags - exited $?" + ${ag_aopts} ao-strs.def || die "cannot make strings - exited $?" + + declare cmd_list=$( + sed -n '/case *XAT_CMD_/{;s/.*XAT_CMD_/cmd = /;s/:/;/;p;}' \ + configfile.c | tr '[A-Z_]' '[a-z-]') + + ${ag_aopts} <<- _EOF_ + AutoGen Definitions str2enum; + base-name = option-xat-attribute; + prefix = xat; + no-name; + $cmd_list + _EOF_ + test $? -eq 0 || \ + die "FAILED: option-xat-attribute enumeration" + + cmd_list=$( + sed -n '/case *VTP_CMD_/{;s/.*VTP_CMD_/cmd = /;s/:/;/;p;}' \ + configfile.c | tr '[A-Z_]' '[a-z-]') + ${ag_aopts} <<- _EOF_ + AutoGen Definitions str2enum; + base-name = option-value-type; + prefix = vtp; + no-name; + $cmd_list + _EOF_ + test $? -eq 0 || \ + die "FAILED: ${s2enum} --base-name=option-value-type" + burn_aover + + test -d autoopts || mkdir autoopts + test -d po || mkdir po + ${ag_aopts} genshell.def || \ + die "FAILED: ${ag_aopts} genshell.def" + + ${ag_aopts} usage-txt.def || \ + die "FAILED: ${ag_aopts} usage-txt.def" + mv -f usage-txt.h autoopts/. + mv -f usage-txt.pot po/. + + files=$(sed -n '/^CSRC/,/\.c$/p' Makefile.am.pre | \ + sed '/^CSRC/d;s/[=\\]//' + ) + + getdefs linenum srcfile template=options_h output=funcs.def $files + chmod u+w funcs.def + vers_min=$(expr '(' $AO_CURRENT - $AO_AGE ')' '*' 4096) + cat >> funcs.def <<- _END_VERS_INFO_ + vers-curr = "${vers_curr}"; + vers-min = "${vers_min}"; + vers-min-str = "$(expr $AO_CURRENT - $AO_AGE):0:0"; + vers-sovers = "${AO_SOVERS}"; + display-ver = "${AO_CURRENT}.${AO_REVISION}"; + library = opts; + + /* + * THIS FILE IS DISTRIBUTED + * + * This file is used to construct options.h + doc files. Because it is + * such a nuisance to get the build ordering correct, we distribute + * this. It should be constructed after all binaries are built. + */ + _END_VERS_INFO_ + + ${ag_aopts} funcs.def || \ + die "FAILED: ${ag_aopts} funcs.def" + test -f options.h || \ + die "options.h not created" + mv -f options.h autoopts/. + cp project.h autoopts/. + + add_files_to_mf + make_proto + + ${ag_aopts} aoconf.def || \ + die "FAILED: ${ag_aopts} aoconf.def" +} + +test "X${mainpid}" = X && { + echo SOURCING BOOTSTRAP.SHLIB + \cd ${top_srcdir-..} + top_srcdir=`pwd` + . config/bootstrap.shlib + cd autoopts + free_trap=true + echo DONE SOURCING BOOTSTRAP.SHLIB +} || { + free_trap=false +} + +${skip_gen} || \ + export ag_aopts=${AGexe-autogen}\ -L${top_srcdir}/autoopts/tpl + +case "$1" in +*genshell.c ) + if ${skip_gen} + then + test -f ${top_srcdir}/autoopts/genshell.c || \ + die "No autogen for building genshell.c" + else + ${ag_aopts} genshell.def || \ + die "FAILED: ${ag_aopts} genshell.def" + fi + ;; + +*libopts.texi ) + if ${skip_gen} + then + test -f ${top_srcdir}/autoopts/libopts.texi || \ + die "No autogen for building libopts.texi" + else + agopts='-Taginfo3.tpl -DLEVEL=subsection -blibopts funcs.def' + ${ag_aopts} ${agopts} || \ + die "FAILED: ${ag_aopts} ${agopts}" + fi + ;; + +aoconf ) + if ${skip_gen} + then untar_touch gen-src.tgz + else make_funcs_def + fi || die "could not rebuild files in $PWD" + ;; +esac + +${free_trap} && trap '' 0 +true + +# Local Variables: +# mode:shell-script +# sh-indentation:4 +# sh-basic-offset:4 +# indent-tabs-mode: nil +# End: + +# bootstrap.dir ends here diff --git a/autoopts/check.c b/autoopts/check.c new file mode 100644 index 0000000..7e75e7e --- /dev/null +++ b/autoopts/check.c @@ -0,0 +1,177 @@ +/** + * @file check.c + * + * @brief option consistency checks. + * + * @addtogroup autoopts + * @{ + */ +/* + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +/** + * Check for conflicts based on "must" and "cannot" attributes. + */ +static bool +has_conflict(tOptions * pOpts, tOptDesc * od) +{ + if (od->pOptMust != NULL) { + int const * must = od->pOptMust; + + while (*must != NO_EQUIVALENT) { + tOptDesc * p = pOpts->pOptDesc + *(must++); + if (UNUSED_OPT(p)) { + const tOptDesc * ood = pOpts->pOptDesc + must[-1]; + fprintf(stderr, zneed_fmt, pOpts->pzProgName, + od->pz_Name, ood->pz_Name); + return true; + } + } + } + + if (od->pOptCant != NULL) { + int const * cant = od->pOptCant; + + while (*cant != NO_EQUIVALENT) { + tOptDesc * p = pOpts->pOptDesc + *(cant++); + if (SELECTED_OPT(p)) { + const tOptDesc * ood = pOpts->pOptDesc + cant[-1]; + fprintf(stderr, zconflict_fmt, pOpts->pzProgName, + od->pz_Name, ood->pz_Name); + return true; + } + } + } + + return false; +} + +/** + * Check that the option occurs often enough. Too often is already checked. + */ +static bool +occurs_enough(tOptions * pOpts, tOptDesc * pOD) +{ + (void)pOpts; + + /* + * IF the occurrence counts have been satisfied, + * THEN there is no problem. + */ + if (pOD->optOccCt >= pOD->optMinCt) + return true; + + /* + * IF MUST_SET means SET and PRESET are okay, + * so min occurrence count doesn't count + */ + if ( (pOD->fOptState & OPTST_MUST_SET) + && (pOD->fOptState & (OPTST_PRESET | OPTST_SET)) ) + return true; + + if (pOD->optMinCt > 1) + fprintf(stderr, zneed_more, pOpts->pzProgName, pOD->pz_Name, + pOD->optMinCt); + else fprintf(stderr, zneed_one, pOpts->pzProgName, pOD->pz_Name); + return false; +} + +/** + * Verify option consistency. + * + * Make sure that the argument list passes our consistency tests. + */ +static bool +is_consistent(tOptions * pOpts) +{ + tOptDesc * pOD = pOpts->pOptDesc; + int oCt = pOpts->presetOptCt; + + /* + * FOR each of "oCt" options, ... + */ + for (;;) { + /* + * IF the current option was provided on the command line + * THEN ensure that any "MUST" requirements are not + * "DEFAULT" (unspecified) *AND* ensure that any + * "CANT" options have not been SET or DEFINED. + */ + if (SELECTED_OPT(pOD)) { + if (has_conflict(pOpts, pOD)) + return false; + } + + /* + * IF this option is not equivalenced to another, + * OR it is equivalenced to itself (is the equiv. root) + * THEN we need to make sure it occurs often enough. + */ + if ( (pOD->optEquivIndex == NO_EQUIVALENT) + || (pOD->optEquivIndex == pOD->optIndex) ) + + if (! occurs_enough(pOpts, pOD)) + return false; + + if (--oCt <= 0) + break; + pOD++; + } + + /* + * IF we are stopping on errors, check to see if any remaining + * arguments are required to be there or prohibited from being there. + */ + if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0) { + + /* + * Check for prohibition + */ + if ((pOpts->fOptSet & OPTPROC_NO_ARGS) != 0) { + if (pOpts->origArgCt > pOpts->curOptIdx) { + fprintf(stderr, zNoArgs, pOpts->pzProgName); + return false; + } + } + + /* + * ELSE not prohibited, check for being required + */ + else if ((pOpts->fOptSet & OPTPROC_ARGS_REQ) != 0) { + if (pOpts->origArgCt <= pOpts->curOptIdx) { + fprintf(stderr, zargs_must, pOpts->pzProgName); + return false; + } + } + } + + return true; +} + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/check.c */ diff --git a/autoopts/configFileLoad.3 b/autoopts/configFileLoad.3 new file mode 100644 index 0000000..5a85983 --- /dev/null +++ b/autoopts/configFileLoad.3 @@ -0,0 +1,50 @@ +.TH configFileLoad 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (configFileLoad.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +configFileLoad - parse a configuration file +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +const tOptionValue * \fBconfigFileLoad\fP(char const * \fIfname\fP); +.sp 1 +.SH DESCRIPTION +This routine will load a named configuration file and parse the +text as a hierarchically valued option. The option descriptor +created from an option definition file is not used via this interface. +The returned value is "named" with the input file name and is of +type "\fBOPARG_TYPE_HIERARCHY\fP". It may be used in calls to +\fBoptionGetValue()\fP, \fBoptionNextValue()\fP and +\fBoptionUnloadNested()\fP. +.TP +.IR fname +the file to load +.sp 1 +.SH RETURN VALUE +An allocated, compound value structure +.sp 1 +.SH ERRORS +If the file cannot be loaded or processed, \fBNULL\fP is returned and +\fBerrno\fP is set. It may be set by a call to either \fBopen(2)\fP +\fBmmap(2)\fP or other file system calls, or it may be: +.sp 1ize @bullet +.sp 1 +\fBENOENT\fP \- the file was not found. +.sp 1 +\fBENOMSG\fP \- the file was empty. +.sp 1 +\fBEINVAL\fP \- the file contents are invalid \-- not properly formed. +.sp 1 +\fBENOMEM\fP \- not enough memory to allocate the needed structures. +@end itemize +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +ao_string_tokenize(3), optionFileLoad(3), optionFindNextValue(3), optionFindValue(3), optionFree(3), optionGetValue(3), optionLoadLine(3), optionMemberList(3), optionNextValue(3), optionOnlyUsage(3), optionPrintVersion(3), optionPrintVersionAndReturn(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), strequate(3), streqvcmp(3), streqvmap(3), strneqvcmp(3), strtransform(3), diff --git a/autoopts/configfile.c b/autoopts/configfile.c new file mode 100644 index 0000000..783a9d8 --- /dev/null +++ b/autoopts/configfile.c @@ -0,0 +1,1337 @@ +/** + * \file configfile.c + * + * configuration/rc/ini file handling. + * + * @addtogroup autoopts + * @{ + */ +/* + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +/** + * Skip over some unknown attribute + * @param[in] txt start of skpped text + * @returns character after skipped text + */ +inline static char const * +skip_unkn(char const * txt) +{ + txt = BRK_END_XML_TOKEN_CHARS(txt); + return (*txt == NUL) ? NULL : txt; +} + +/*=export_func configFileLoad + * + * what: parse a configuration file + * arg: + char const * + fname + the file to load + + * + * ret_type: const tOptionValue * + * ret_desc: An allocated, compound value structure + * + * doc: + * This routine will load a named configuration file and parse the + * text as a hierarchically valued option. The option descriptor + * created from an option definition file is not used via this interface. + * The returned value is "named" with the input file name and is of + * type "@code{OPARG_TYPE_HIERARCHY}". It may be used in calls to + * @code{optionGetValue()}, @code{optionNextValue()} and + * @code{optionUnloadNested()}. + * + * err: + * If the file cannot be loaded or processed, @code{NULL} is returned and + * @var{errno} is set. It may be set by a call to either @code{open(2)} + * @code{mmap(2)} or other file system calls, or it may be: + * @itemize @bullet + * @item + * @code{ENOENT} - the file was not found. + * @item + * @code{ENOMSG} - the file was empty. + * @item + * @code{EINVAL} - the file contents are invalid -- not properly formed. + * @item + * @code{ENOMEM} - not enough memory to allocate the needed structures. + * @end itemize +=*/ +const tOptionValue * +configFileLoad(char const * fname) +{ + tmap_info_t cfgfile; + tOptionValue * res = NULL; + tOptionLoadMode save_mode = option_load_mode; + + char * txt = text_mmap(fname, PROT_READ, MAP_PRIVATE, &cfgfile); + + if (TEXT_MMAP_FAILED_ADDR(txt)) + return NULL; /* errno is set */ + + option_load_mode = OPTION_LOAD_COOKED; + res = optionLoadNested(txt, fname, strlen(fname)); + + if (res == NULL) { + int err = errno; + text_munmap(&cfgfile); + errno = err; + } else + text_munmap(&cfgfile); + + option_load_mode = save_mode; + return res; +} + + +/*=export_func optionFindValue + * + * what: find a hierarcicaly valued option instance + * arg: + const tOptDesc * + odesc + an option with a nested arg type + + * arg: + char const * + name + name of value to find + + * arg: + char const * + val + the matching value + + * + * ret_type: const tOptionValue * + * ret_desc: a compound value structure + * + * doc: + * This routine will find an entry in a nested value option or configurable. + * It will search through the list and return a matching entry. + * + * err: + * The returned result is NULL and errno is set: + * @itemize @bullet + * @item + * @code{EINVAL} - the @code{pOptValue} does not point to a valid + * hierarchical option value. + * @item + * @code{ENOENT} - no entry matched the given name. + * @end itemize +=*/ +const tOptionValue * +optionFindValue(const tOptDesc * odesc, char const * name, char const * val) +{ + const tOptionValue * res = NULL; + + if ( (odesc == NULL) + || (OPTST_GET_ARGTYPE(odesc->fOptState) != OPARG_TYPE_HIERARCHY)) { + errno = EINVAL; + } + + else if (odesc->optCookie == NULL) { + errno = ENOENT; + } + + else do { + tArgList * argl = odesc->optCookie; + int argct = argl->useCt; + void ** poptv = (void **)(argl->apzArgs); + + if (argct == 0) { + errno = ENOENT; + break; + } + + if (name == NULL) { + res = (tOptionValue *)*poptv; + break; + } + + while (--argct >= 0) { + const tOptionValue * ov = *(poptv++); + const tOptionValue * rv = optionGetValue(ov, name); + + if (rv == NULL) + continue; + + if (val == NULL) { + res = ov; + break; + } + } + if (res == NULL) + errno = ENOENT; + } while (false); + + return res; +} + + +/*=export_func optionFindNextValue + * + * FIXME: the handling of 'pzName' and 'pzVal' is just wrong. + * + * what: find a hierarcicaly valued option instance + * arg: + const tOptDesc * + odesc + an option with a nested arg type + + * arg: + const tOptionValue * + pPrevVal + the last entry + + * arg: + char const * + name + name of value to find + + * arg: + char const * + value + the matching value + + * + * ret_type: const tOptionValue * + * ret_desc: a compound value structure + * + * doc: + * This routine will find the next entry in a nested value option or + * configurable. It will search through the list and return the next entry + * that matches the criteria. + * + * err: + * The returned result is NULL and errno is set: + * @itemize @bullet + * @item + * @code{EINVAL} - the @code{pOptValue} does not point to a valid + * hierarchical option value. + * @item + * @code{ENOENT} - no entry matched the given name. + * @end itemize +=*/ +tOptionValue const * +optionFindNextValue(const tOptDesc * odesc, const tOptionValue * pPrevVal, + char const * pzName, char const * pzVal) +{ + bool old_found = false; + tOptionValue * res = NULL; + + (void)pzName; + (void)pzVal; + + if ( (odesc == NULL) + || (OPTST_GET_ARGTYPE(odesc->fOptState) != OPARG_TYPE_HIERARCHY)) { + errno = EINVAL; + } + + else if (odesc->optCookie == NULL) { + errno = ENOENT; + } + + else do { + tArgList * argl = odesc->optCookie; + int ct = argl->useCt; + void ** poptv = (void **)argl->apzArgs; + + while (--ct >= 0) { + tOptionValue * pOV = *(poptv++); + if (old_found) { + res = pOV; + break; + } + if (pOV == pPrevVal) + old_found = true; + } + if (res == NULL) + errno = ENOENT; + } while (false); + + return res; +} + + +/*=export_func optionGetValue + * + * what: get a specific value from a hierarcical list + * arg: + const tOptionValue * + pOptValue + a hierarchcal value + + * arg: + char const * + valueName + name of value to get + + * + * ret_type: const tOptionValue * + * ret_desc: a compound value structure + * + * doc: + * This routine will find an entry in a nested value option or configurable. + * If "valueName" is NULL, then the first entry is returned. Otherwise, + * the first entry with a name that exactly matches the argument will be + * returned. If there is no matching value, NULL is returned and errno is + * set to ENOENT. If the provided option value is not a hierarchical value, + * NULL is also returned and errno is set to EINVAL. + * + * err: + * The returned result is NULL and errno is set: + * @itemize @bullet + * @item + * @code{EINVAL} - the @code{pOptValue} does not point to a valid + * hierarchical option value. + * @item + * @code{ENOENT} - no entry matched the given name. + * @end itemize +=*/ +tOptionValue const * +optionGetValue(tOptionValue const * oov, char const * vname) +{ + tArgList * arg_list; + tOptionValue * res = NULL; + + if ((oov == NULL) || (oov->valType != OPARG_TYPE_HIERARCHY)) { + errno = EINVAL; + return res; + } + arg_list = oov->v.nestVal; + + if (arg_list->useCt > 0) { + int ct = arg_list->useCt; + void ** ovlist = (void **)(arg_list->apzArgs); + + if (vname == NULL) { + res = (tOptionValue *)*ovlist; + + } else do { + tOptionValue * opt_val = *(ovlist++); + if (strcmp(opt_val->pzName, vname) == 0) { + res = opt_val; + break; + } + } while (--ct > 0); + } + if (res == NULL) + errno = ENOENT; + return res; +} + +/*=export_func optionNextValue + * + * what: get the next value from a hierarchical list + * arg: + const tOptionValue * + pOptValue + a hierarchcal list value + + * arg: + const tOptionValue * + pOldValue + a value from this list + + * + * ret_type: const tOptionValue * + * ret_desc: a compound value structure + * + * doc: + * This routine will return the next entry after the entry passed in. At the + * end of the list, NULL will be returned. If the entry is not found on the + * list, NULL will be returned and "@var{errno}" will be set to EINVAL. + * The "@var{pOldValue}" must have been gotten from a prior call to this + * routine or to "@code{opitonGetValue()}". + * + * err: + * The returned result is NULL and errno is set: + * @itemize @bullet + * @item + * @code{EINVAL} - the @code{pOptValue} does not point to a valid + * hierarchical option value or @code{pOldValue} does not point to a + * member of that option value. + * @item + * @code{ENOENT} - the supplied @code{pOldValue} pointed to the last entry. + * @end itemize +=*/ +tOptionValue const * +optionNextValue(tOptionValue const * ov_list,tOptionValue const * oov ) +{ + tArgList * arg_list; + tOptionValue * res = NULL; + int err = EINVAL; + + if ((ov_list == NULL) || (ov_list->valType != OPARG_TYPE_HIERARCHY)) { + errno = EINVAL; + return NULL; + } + arg_list = ov_list->v.nestVal; + { + int ct = arg_list->useCt; + void ** o_list = (void **)(arg_list->apzArgs); + + while (ct-- > 0) { + tOptionValue * nov = *(o_list++); + if (nov == oov) { + if (ct == 0) { + err = ENOENT; + + } else { + err = 0; + res = (tOptionValue *)*o_list; + } + break; + } + } + } + if (err != 0) + errno = err; + return res; +} + +/** + * Load a file containing presetting information (a configuration file). + */ +static void +file_preset(tOptions * opts, char const * fname, int dir) +{ + tmap_info_t cfgfile; + tOptState optst = OPTSTATE_INITIALIZER(PRESET); + opt_state_mask_t st_flags = optst.flags; + opt_state_mask_t fl_save = opts->fOptSet; + char * ftext = + text_mmap(fname, PROT_READ|PROT_WRITE, MAP_PRIVATE, &cfgfile); + + if (TEXT_MMAP_FAILED_ADDR(ftext)) + return; + + /* + * While processing config files, we ignore errors. + */ + opts->fOptSet &= ~OPTPROC_ERRSTOP; + + if (dir == DIRECTION_CALLED) { + st_flags = OPTST_DEFINED; + dir = DIRECTION_PROCESS; + } + + /* + * IF this is called via "optionProcess", then we are presetting. + * This is the default and the PRESETTING bit will be set. + * If this is called via "optionFileLoad", then the bit is not set + * and we consider stuff set herein to be "set" by the client program. + */ + if ((opts->fOptSet & OPTPROC_PRESETTING) == 0) + st_flags = OPTST_SET; + + do { + optst.flags = st_flags; + ftext = SPN_WHITESPACE_CHARS(ftext); + + if (IS_VAR_FIRST_CHAR(*ftext)) { + ftext = handle_cfg(opts, &optst, ftext, dir); + + } else switch (*ftext) { + case '<': + if (IS_VAR_FIRST_CHAR(ftext[1])) + ftext = handle_struct(opts, &optst, ftext, dir); + + else switch (ftext[1]) { + case '?': + ftext = handle_directive(opts, ftext); + break; + + case '!': + ftext = handle_comment(ftext); + break; + + case '/': + ftext = strchr(ftext + 2, '>'); + if (ftext++ != NULL) + break; + /* FALLTHROUGH */ + + default: + ftext = NULL; + } + if (ftext == NULL) + goto all_done; + break; + + case '[': + ftext = handle_section(opts, ftext); + break; + + case '#': + ftext = strchr(ftext + 1, NL); + break; + + default: + goto all_done; /* invalid format */ + } + } while (ftext != NULL); + + all_done: + text_munmap(&cfgfile); + opts->fOptSet = fl_save; +} + +/** + * "txt" points to a "". + */ +static char * +handle_comment(char * txt) +{ + char * pz = strstr(txt, "-->"); + if (pz != NULL) + pz += 3; + return pz; +} + +/** + * "txt" points to the start of some value name. + * The end of the entry is the end of the line that is not preceded by + * a backslash escape character. The string value is always processed + * in "cooked" mode. + */ +static char * +handle_cfg(tOptions * opts, tOptState * ost, char * txt, int dir) +{ + char * pzName = txt++; + char * pzEnd = strchr(txt, NL); + + if (pzEnd == NULL) + return txt + strlen(txt); + + txt = SPN_VALUE_NAME_CHARS(txt); + txt = SPN_WHITESPACE_CHARS(txt); + if (txt > pzEnd) { + name_only: + *pzEnd++ = NUL; + load_opt_line(opts, ost, pzName, dir, OPTION_LOAD_UNCOOKED); + return pzEnd; + } + + /* + * Either the first character after the name is a ':' or '=', + * or else we must have skipped over white space. Anything else + * is an invalid format and we give up parsing the text. + */ + if ((*txt == '=') || (*txt == ':')) { + txt = SPN_WHITESPACE_CHARS(txt+1); + if (txt > pzEnd) + goto name_only; + } else if (! IS_WHITESPACE_CHAR(txt[-1])) + return NULL; + + /* + * IF the value is continued, remove the backslash escape and push "pzEnd" + * on to a newline *not* preceded by a backslash. + */ + if (pzEnd[-1] == '\\') { + char * pcD = pzEnd-1; + char * pcS = pzEnd; + + for (;;) { + char ch = *(pcS++); + switch (ch) { + case NUL: + pcS = NULL; + /* FALLTHROUGH */ + + case NL: + *pcD = NUL; + pzEnd = pcS; + goto copy_done; + + case '\\': + if (*pcS == NL) + ch = *(pcS++); + /* FALLTHROUGH */ + default: + *(pcD++) = ch; + } + } copy_done:; + + } else { + /* + * The newline was not preceded by a backslash. NUL it out + */ + *(pzEnd++) = NUL; + } + + /* + * "pzName" points to what looks like text for one option/configurable. + * It is NUL terminated. Process it. + */ + load_opt_line(opts, ost, pzName, dir, OPTION_LOAD_UNCOOKED); + + return pzEnd; +} + +/** + * "txt" points to a "'); + if (txt != NULL) + txt++; + return txt; +# undef DIRECTIVE_TABLE +} + +/** + * handle AutoOpts mode flags. + * + * @param[in,out] opts program option descriptor + * @param[in] txt scanning pointer + * @returns the next character to look at + */ +static char * +aoflags_directive(tOptions * opts, char * txt) +{ + char * pz; + + pz = SPN_WHITESPACE_CHARS(txt+1); + txt = strchr(pz, '>'); + if (txt != NULL) { + + size_t len = (unsigned)(txt - pz); + char * ftxt = AGALOC(len + 1, "aoflags"); + + memcpy(ftxt, pz, len); + ftxt[len] = NUL; + set_usage_flags(opts, ftxt); + AGFREE(ftxt); + + txt++; + } + + return txt; +} + +/** + * handle program segmentation of config file. + * + * @param[in,out] opts program option descriptor + * @param[in] txt scanning pointer + * @returns the next character to look at + */ +static char * +program_directive(tOptions * opts, char * txt) +{ + size_t name_len = strlen(opts->pzProgName); + + for (;; txt += zCfgProg_LEN) { + txt = SPN_WHITESPACE_CHARS(txt); + + if ( (strneqvcmp(txt, opts->pzProgName, (int)name_len) == 0) + && (IS_END_XML_TOKEN_CHAR(txt[name_len])) ) + + return txt + name_len; + + txt = strstr(txt, zCfgProg); + if (txt == NULL) + return txt; + } + + for (;;) { + if (*txt == NUL) + return NULL; + + if (*(txt++) == '>') + return txt; + } +} + +/** + * "txt" points to a '[' character. + * The "traditional" [PROG_NAME] segmentation of the config file. + * Do not ever mix with the "" variation. + * The templates reject program names over 16 characters. + * + * @param[in,out] opts program option descriptor + * @param[in] txt scanning pointer + * @returns the next character to look at + */ +static char * +handle_section(tOptions * opts, char * txt) +{ + size_t len = strlen(opts->pzPROGNAME); + if ( (strncmp(txt+1, opts->pzPROGNAME, len) == 0) + && (txt[len+1] == ']')) + return strchr(txt + len + 2, NL); + + if (len > 16) + return NULL; + + { + char z[24] = "["; + memcpy(z+1, opts->pzPROGNAME, len); + z[++len] = ']'; + z[++len] = NUL; + txt = strstr(txt, z); + } + + if (txt != NULL) + txt = strchr(txt, NL); + return txt; +} + +/** + * parse XML encodings + */ +static int +parse_xml_encoding(char ** ppz) +{ +# define XMLTABLE \ + _xmlNm_(amp, '&') \ + _xmlNm_(lt, '<') \ + _xmlNm_(gt, '>') \ + _xmlNm_(ff, '\f') \ + _xmlNm_(ht, '\t') \ + _xmlNm_(cr, '\r') \ + _xmlNm_(vt, '\v') \ + _xmlNm_(bel, '\a') \ + _xmlNm_(nl, NL) \ + _xmlNm_(space, ' ') \ + _xmlNm_(quot, '"') \ + _xmlNm_(apos, '\'') + + static struct { + char const * const nm_str; + unsigned short nm_len; + short nm_val; + } const xml_names[] = { +# define _xmlNm_(_n, _v) { #_n ";", sizeof(#_n), _v }, + XMLTABLE +# undef _xmlNm_ +# undef XMLTABLE + }; + + static int const nm_ct = sizeof(xml_names) / sizeof(xml_names[0]); + int base = 10; + + char * pz = *ppz; + + if (*pz == '#') { + pz++; + goto parse_number; + } + + if (IS_DEC_DIGIT_CHAR(*pz)) { + unsigned long v; + + parse_number: + switch (*pz) { + case 'x': case 'X': + /* + * Some forms specify hex with: &#xNN; + */ + base = 16; + pz++; + break; + + case '0': + /* + *  is hex and  is decimal. Cool. + * Ya gotta love it. + */ + if (pz[1] == '0') + base = 16; + break; + } + + v = strtoul(pz, &pz, base); + if ((*pz != ';') || (v > 0x7F)) + return NUL; + *ppz = pz + 1; + return (int)v; + } + + { + int ix = 0; + do { + if (strncmp(pz, xml_names[ix].nm_str, xml_names[ix].nm_len) + == 0) { + *ppz = pz + xml_names[ix].nm_len; + return xml_names[ix].nm_val; + } + } while (++ix < nm_ct); + } + + return NUL; +} + +/** + * Find the end marker for the named section of XML. + * Trim that text there, trimming trailing white space for all modes + * except for OPTION_LOAD_UNCOOKED. + */ +static char * +trim_xml_text(char * intxt, char const * pznm, tOptionLoadMode mode) +{ + size_t nm_len = strlen(pznm); + char * etext; + + { + char z[64], *pz = z; + + if (nm_len + 4 >= sizeof(z)) + pz = AGALOC(nm_len + 4, "scan name"); + + pz[0] = '<'; + pz[1] = '/'; + memcpy(pz+2, pznm, nm_len); + nm_len += 2; + pz[nm_len++] = '>'; + pz[nm_len] = NUL; + + *intxt = ' '; + etext = strstr(intxt, pz); + if (pz != z) AGFREE(pz); + } + + if (etext == NULL) + return etext; + + { + char * result = etext + nm_len; + + if (mode != OPTION_LOAD_UNCOOKED) + etext = SPN_WHITESPACE_BACK(intxt, etext); + + *etext = NUL; + return result; + } +} + +/** + */ +static void +cook_xml_text(char * pzData) +{ + char * pzs = pzData; + char * pzd = pzData; + char bf[4]; + bf[2] = NUL; + + for (;;) { + int ch = ((int)*(pzs++)) & 0xFF; + switch (ch) { + case NUL: + *pzd = NUL; + return; + + case '&': + ch = parse_xml_encoding(&pzs); + *(pzd++) = (char)ch; + if (ch == NUL) + return; + break; + + case '%': + bf[0] = *(pzs++); + bf[1] = *(pzs++); + if ((bf[0] == NUL) || (bf[1] == NUL)) { + *pzd = NUL; + return; + } + + ch = (int)strtoul(bf, NULL, 16); + /* FALLTHROUGH */ + + default: + *(pzd++) = (char)ch; + } + } +} + +/** + * "txt" points to a '<' character, followed by an alpha. + * The end of the entry is either the "/>" following the name, or else a + * "" string. + */ +static char * +handle_struct(tOptions * opts, tOptState * ost, char * txt, int dir) +{ + tOptionLoadMode mode = option_load_mode; + tOptionValue valu; + + char * pzName = ++txt; + char * pzData; + char * pcNulPoint; + + txt = SPN_VALUE_NAME_CHARS(txt); + pcNulPoint = txt; + valu.valType = OPARG_TYPE_STRING; + + switch (*txt) { + case ' ': + case '\t': + txt = VOIDP(parse_attrs( + opts, SPN_WHITESPACE_CHARS(txt), &mode, &valu)); + if (txt == NULL) + return txt; + if (*txt == '>') + break; + if (*txt != '/') + return NULL; + /* FALLTHROUGH */ + + case '/': + if (txt[1] != '>') + return NULL; + *txt = NUL; + txt += 2; + load_opt_line(opts, ost, pzName, dir, mode); + return txt; + + case '>': + break; + + default: + txt = strchr(txt, '>'); + if (txt != NULL) + txt++; + return txt; + } + + /* + * If we are here, we have a value. "txt" points to a closing angle + * bracket. Separate the name from the value for a moment. + */ + *pcNulPoint = NUL; + pzData = ++txt; + txt = trim_xml_text(txt, pzName, mode); + if (txt == NULL) + return txt; + + /* + * Rejoin the name and value for parsing by "load_opt_line()". + * Erase any attributes parsed by "parse_attrs()". + */ + memset(pcNulPoint, ' ', (size_t)(pzData - pcNulPoint)); + + /* + * If we are getting a "string" value that is to be cooked, + * then process the XML-ish &xx; XML-ish and %XX hex characters. + */ + if ( (valu.valType == OPARG_TYPE_STRING) + && (mode == OPTION_LOAD_COOKED)) + cook_xml_text(pzData); + + /* + * "pzName" points to what looks like text for one option/configurable. + * It is NUL terminated. Process it. + */ + load_opt_line(opts, ost, pzName, dir, mode); + + return txt; +} + +/** + * Load a configuration file. This may be invoked either from + * scanning the "homerc" list, or from a specific file request. + * (see "optionFileLoad()", the implementation for --load-opts) + */ +static void +intern_file_load(tOptions * opts) +{ + uint32_t svfl; + int idx; + int inc; + char f_name[ AG_PATH_MAX+1 ]; + + if (opts->papzHomeList == NULL) + return; + + svfl = opts->fOptSet; + inc = DIRECTION_PRESET; + + /* + * Never stop on errors in config files. + */ + opts->fOptSet &= ~OPTPROC_ERRSTOP; + + /* + * Find the last RC entry (highest priority entry) + */ + for (idx = 0; opts->papzHomeList[ idx+1 ] != NULL; ++idx) ; + + /* + * For every path in the home list, ... *TWICE* We start at the last + * (highest priority) entry, work our way down to the lowest priority, + * handling the immediate options. + * Then we go back up, doing the normal options. + */ + for (;;) { + struct stat sb; + cch_t * path; + + /* + * IF we've reached the bottom end, change direction + */ + if (idx < 0) { + inc = DIRECTION_PROCESS; + idx = 0; + } + + path = opts->papzHomeList[ idx ]; + + /* + * IF we've reached the top end, bail out + */ + if (path == NULL) + break; + + idx += inc; + + if (! optionMakePath(f_name, (int)sizeof(f_name), + path, opts->pzProgPath)) + continue; + + /* + * IF the file name we constructed is a directory, + * THEN append the Resource Configuration file name + * ELSE we must have the complete file name + */ + if (stat(f_name, &sb) != 0) + continue; /* bogus name - skip the home list entry */ + + if (S_ISDIR(sb.st_mode)) { + size_t len = strlen(f_name); + size_t nln = strlen(opts->pzRcName) + 1; + char * pz = f_name + len; + + if (len + 1 + nln >= sizeof(f_name)) + continue; + + if (pz[-1] != DIRCH) + *(pz++) = DIRCH; + memcpy(pz, opts->pzRcName, nln); + } + + file_preset(opts, f_name, inc); + + /* + * IF we are now to skip config files AND we are presetting, + * THEN change direction. We must go the other way. + */ + { + tOptDesc * od = opts->pOptDesc + opts->specOptIdx.save_opts + 1; + if (DISABLED_OPT(od) && PRESETTING(inc)) { + idx -= inc; /* go back and reprocess current file */ + inc = DIRECTION_PROCESS; + } + } + } /* twice for every path in the home list, ... */ + + opts->fOptSet = svfl; +} + +/*=export_func optionFileLoad + * + * what: Load the locatable config files, in order + * + * arg: + tOptions * + opts + program options descriptor + + * arg: + char const * + prog + program name + + * + * ret_type: int + * ret_desc: 0 -> SUCCESS, -1 -> FAILURE + * + * doc: + * + * This function looks in all the specified directories for a configuration + * file ("rc" file or "ini" file) and processes any found twice. The first + * time through, they are processed in reverse order (last file first). At + * that time, only "immediate action" configurables are processed. For + * example, if the last named file specifies not processing any more + * configuration files, then no more configuration files will be processed. + * Such an option in the @strong{first} named directory will have no effect. + * + * Once the immediate action configurables have been handled, then the + * directories are handled in normal, forward order. In that way, later + * config files can override the settings of earlier config files. + * + * See the AutoOpts documentation for a thorough discussion of the + * config file format. + * + * Configuration files not found or not decipherable are simply ignored. + * + * err: Returns the value, "-1" if the program options descriptor + * is out of date or indecipherable. Otherwise, the value "0" will + * always be returned. +=*/ +int +optionFileLoad(tOptions * opts, char const * prog) +{ + if (! SUCCESSFUL(validate_struct(opts, prog))) + return -1; + + /* + * The pointer to the program name is "const". However, the + * structure is in writable memory, so we coerce the address + * of this pointer to point to writable memory. + */ + { + char const ** pp = VOIDP(&(opts->pzProgName)); + *pp = prog; + } + + intern_file_load(opts); + return 0; +} + +/*=export_func optionLoadOpt + * private: + * + * what: Load an option rc/ini file + * arg: + tOptions * + opts + program options descriptor + + * arg: + tOptDesc * + odesc + the descriptor for this arg + + * + * doc: + * Processes the options found in the file named with + * odesc->optArg.argString. +=*/ +void +optionLoadOpt(tOptions * opts, tOptDesc * odesc) +{ + struct stat sb; + + if (opts <= OPTPROC_EMIT_LIMIT) + return; + + /* + * IF the option is not being disabled, THEN load the file. There must + * be a file. (If it is being disabled, then the disablement processing + * already took place. It must be done to suppress preloading of ini/rc + * files.) + */ + if ( DISABLED_OPT(odesc) + || ((odesc->fOptState & OPTST_RESET) != 0)) + return; + + if (stat(odesc->optArg.argString, &sb) != 0) { + if ((opts->fOptSet & OPTPROC_ERRSTOP) == 0) + return; + + fserr_exit(opts->pzProgName, "stat", odesc->optArg.argString); + /* NOT REACHED */ + } + + if (! S_ISREG(sb.st_mode)) { + if ((opts->fOptSet & OPTPROC_ERRSTOP) == 0) + return; + errno = EINVAL; + fserr_exit(opts->pzProgName, "stat", odesc->optArg.argString); + /* NOT REACHED */ + } + + file_preset(opts, odesc->optArg.argString, DIRECTION_CALLED); +} + +/** + * Parse the various attributes of an XML-styled config file entry + * + * @returns NULL on failure, otherwise the scan point + */ +static char const * +parse_attrs(tOptions * opts, char const * txt, tOptionLoadMode * pMode, + tOptionValue * pType) +{ + size_t len = 0; + + for (;;) { + len = (size_t)(SPN_LOWER_CASE_CHARS(txt) - txt); + + /* + * The enumeration used in this switch is derived from this switch + * statement itself. The "find_option_xat_attribute_cmd" function + * will return XAT_CMD_MEMBERS for the "txt" string value + * "members", etc. + */ + switch (find_option_xat_attribute_cmd(txt, len)) { + case XAT_CMD_TYPE: + txt = parse_value(txt+len, pType); + break; + + case XAT_CMD_WORDS: + txt = parse_keyword(opts, txt+len, pType); + break; + + case XAT_CMD_MEMBERS: + txt = parse_set_mem(opts, txt+len, pType); + break; + + case XAT_CMD_COOKED: + txt += len; + if (! IS_END_XML_TOKEN_CHAR(*txt)) + goto invalid_kwd; + + *pMode = OPTION_LOAD_COOKED; + break; + + case XAT_CMD_UNCOOKED: + txt += len; + if (! IS_END_XML_TOKEN_CHAR(*txt)) + goto invalid_kwd; + + *pMode = OPTION_LOAD_UNCOOKED; + break; + + case XAT_CMD_KEEP: + txt += len; + if (! IS_END_XML_TOKEN_CHAR(*txt)) + goto invalid_kwd; + + *pMode = OPTION_LOAD_KEEP; + break; + + default: + case XAT_INVALID_CMD: + invalid_kwd: + pType->valType = OPARG_TYPE_NONE; + return skip_unkn(txt); + } + + if (txt == NULL) + return NULL; + txt = SPN_WHITESPACE_CHARS(txt); + switch (*txt) { + case '/': pType->valType = OPARG_TYPE_NONE; + /* FALLTHROUGH */ + case '>': return txt; + } + if (! IS_LOWER_CASE_CHAR(*txt)) + return NULL; + } +} + +/** + * "txt" points to the character after "words=". + * What should follow is a name of a keyword (enumeration) list. + * + * @param opts unused + * @param[in] txt keyword to skip over + * @param type unused value type + * @returns pointer after skipped text + */ +static char const * +parse_keyword(tOptions * opts, char const * txt, tOptionValue * typ) +{ + (void)opts; + (void)typ; + + return skip_unkn(txt); +} + +/** + * "txt" points to the character after "members=" + * What should follow is a name of a "set membership". + * A collection of bit flags. + * + * @param opts unused + * @param[in] txt keyword to skip over + * @param type unused value type + * @returns pointer after skipped text + */ +static char const * +parse_set_mem(tOptions * opts, char const * txt, tOptionValue * typ) +{ + (void)opts; + (void)typ; + + return skip_unkn(txt); +} + +/** + * parse the type. The keyword "type" was found, now figure out + * the type that follows the type. + * + * @param[in] txt points to the '=' character after the "type" keyword. + * @param[out] typ where to store the type found + * @returns the next byte after the type name + */ +static char const * +parse_value(char const * txt, tOptionValue * typ) +{ + size_t len = 0; + + if (*(txt++) != '=') + goto woops; + + len = (size_t)(SPN_OPTION_NAME_CHARS(txt) - txt); + + if ((len == 0) || (! IS_END_XML_TOKEN_CHAR(txt[len]))) { + woops: + typ->valType = OPARG_TYPE_NONE; + return skip_unkn(txt + len); + } + + /* + * The enumeration used in this switch is derived from this switch + * statement itself. The "find_option_value_type_cmd" function + * will return VTP_CMD_INTEGER for the "txt" string value + * "integer", etc. + */ + switch (find_option_value_type_cmd(txt, len)) { + default: + case VTP_INVALID_CMD: goto woops; + + case VTP_CMD_STRING: + typ->valType = OPARG_TYPE_STRING; + break; + + case VTP_CMD_INTEGER: + typ->valType = OPARG_TYPE_NUMERIC; + break; + + case VTP_CMD_BOOL: + case VTP_CMD_BOOLEAN: + typ->valType = OPARG_TYPE_BOOLEAN; + break; + + case VTP_CMD_KEYWORD: + typ->valType = OPARG_TYPE_ENUMERATION; + break; + + case VTP_CMD_SET: + case VTP_CMD_SET_MEMBERSHIP: + typ->valType = OPARG_TYPE_MEMBERSHIP; + break; + + case VTP_CMD_NESTED: + case VTP_CMD_HIERARCHY: + typ->valType = OPARG_TYPE_HIERARCHY; + } + + return txt + len; +} + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/configfile.c */ diff --git a/autoopts/cook.c b/autoopts/cook.c new file mode 100644 index 0000000..5240540 --- /dev/null +++ b/autoopts/cook.c @@ -0,0 +1,320 @@ +/** + * \file cook.c + * + * This file contains the routines that deal with processing quoted strings + * into an internal format. + * + * @addtogroup autoopts + * @{ + */ +/* + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +/*=export_func ao_string_cook_escape_char + * private: + * + * what: escape-process a string fragment + * arg: + char const * + pzScan + points to character after the escape + + * arg: + char * + pRes + Where to put the result byte + + * arg: + unsigned int + nl_ch + replacement char if scanned char is \n + + * + * ret-type: unsigned int + * ret-desc: The number of bytes consumed processing the escaped character. + * + * doc: + * + * This function converts "t" into "\t" and all your other favorite + * escapes, including numeric ones: hex and ocatal, too. + * The returned result tells the caller how far to advance the + * scan pointer (passed in). The default is to just pass through the + * escaped character and advance the scan by one. + * + * Some applications need to keep an escaped newline, others need to + * suppress it. This is accomplished by supplying a '\n' replacement + * character that is different from \n, if need be. For example, use + * 0x7F and never emit a 0x7F. + * + * err: @code{NULL} is returned if the string is mal-formed. +=*/ +unsigned int +ao_string_cook_escape_char(char const * pzIn, char * pRes, uint_t nl) +{ + unsigned int res = 1; + + switch (*pRes = *pzIn++) { + case NUL: /* NUL - end of input string */ + return 0; + case '\r': + if (*pzIn != NL) + return 1; + res++; + /* FALLTHROUGH */ + case NL: /* NL - emit newline */ + *pRes = (char)nl; + return res; + + case 'a': *pRes = '\a'; break; + case 'b': *pRes = '\b'; break; + case 'f': *pRes = '\f'; break; + case 'n': *pRes = NL; break; + case 'r': *pRes = '\r'; break; + case 't': *pRes = '\t'; break; + case 'v': *pRes = '\v'; break; + + case 'x': + case 'X': /* HEX Escape */ + if (IS_HEX_DIGIT_CHAR(*pzIn)) { + char z[4]; + unsigned int ct = 0; + + do { + z[ct] = pzIn[ct]; + if (++ct >= 2) + break; + } while (IS_HEX_DIGIT_CHAR(pzIn[ct])); + z[ct] = NUL; + *pRes = (char)strtoul(z, NULL, 16); + return ct + 1; + } + break; + + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + { + /* + * IF the character copied was an octal digit, + * THEN set the output character to an octal value. + * The 3 octal digit result might exceed 0xFF, so check it. + */ + char z[4]; + unsigned long val; + unsigned int ct = 0; + + z[ct++] = *--pzIn; + while (IS_OCT_DIGIT_CHAR(pzIn[ct])) { + z[ct] = pzIn[ct]; + if (++ct >= 3) + break; + } + + z[ct] = NUL; + val = strtoul(z, NULL, 8); + if (val > 0xFF) + val = 0xFF; + *pRes = (char)val; + return ct; + } + + default: /* quoted character is result character */; + } + + return res; +} + +/** + * count newlines between start and end + */ +static char * +nl_count(char * start, char * end, int * lnct_p) +{ + while (start < end) { + if (*(start++) == NL) + (*lnct_p)++; + } + return end; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * A quoted string has been found. + * Find the end of it and compress any escape sequences. + */ +static bool +contiguous_quote(char ** pps, char * pq, int * lnct_p) +{ + char * ps = *pps + 1; + + for (;;) { + while (IS_WHITESPACE_CHAR(*ps)) + if (*(ps++) == NL) + (*lnct_p)++; + + /* + * IF the next character is a quote character, + * THEN we will concatenate the strings. + */ + switch (*ps) { + case '"': + case '\'': + *pq = *(ps++); /* assign new quote character and return */ + *pps = ps; + return true; + + case '/': + /* + * Allow for a comment embedded in the concatenated string. + */ + switch (ps[1]) { + default: + goto fail_return; + + case '/': + /* + * Skip to end of line + */ + ps = strchr(ps, NL); + if (ps == NULL) + goto fail_return; + break; + + case '*': + ps = nl_count(ps + 2, strstr(ps + 2, "*/"), lnct_p); + if (ps == NULL) + goto fail_return; + ps += 2; + } + continue; + + default: + /* + * The next non-whitespace character is not a quote. + * The series of quoted strings has come to an end. + */ + *pps = ps; + return false; + } + } + + fail_return: + *pps = NULL; + return false; +} + +/*=export_func ao_string_cook + * private: + * + * what: concatenate and escape-process strings + * arg: + char * + pzScan + The *MODIFIABLE* input buffer + + * arg: + int * + lnct_p + The (possibly NULL) pointer to a line count + + * + * ret-type: char * + * ret-desc: The address of the text following the processed strings. + * The return value is NULL if the strings are ill-formed. + * + * doc: + * + * A series of one or more quoted strings are concatenated together. + * If they are quoted with double quotes (@code{"}), then backslash + * escapes are processed per the C programming language. If they are + * single quote strings, then the backslashes are honored only when they + * precede another backslash or a single quote character. + * + * err: @code{NULL} is returned if the string(s) is/are mal-formed. +=*/ +char * +ao_string_cook(char * pzScan, int * lnct_p) +{ + int l = 0; + char q = *pzScan; + + /* + * It is a quoted string. Process the escape sequence characters + * (in the set "abfnrtv") and make sure we find a closing quote. + */ + char * pzD = pzScan++; + char * pzS = pzScan; + + if (lnct_p == NULL) + lnct_p = &l; + + for (;;) { + /* + * IF the next character is the quote character, THEN we may end the + * string. We end it unless the next non-blank character *after* the + * string happens to also be a quote. If it is, then we will change + * our quote character to the new quote character and continue + * condensing text. + */ + while (*pzS == q) { + *pzD = NUL; /* This is probably the end of the line */ + if (! contiguous_quote(&pzS, &q, lnct_p)) + return pzS; + } + + /* + * We are inside a quoted string. Copy text. + */ + switch (*(pzD++) = *(pzS++)) { + case NUL: + return NULL; + + case NL: + (*lnct_p)++; + break; + + case '\\': + /* + * IF we are escaping a new line, + * THEN drop both the escape and the newline from + * the result string. + */ + if (*pzS == NL) { + pzS++; + pzD--; + (*lnct_p)++; + } + + /* + * ELSE IF the quote character is '"' or '`', + * THEN we do the full escape character processing + */ + else if (q != '\'') { + unsigned int ct; + ct = ao_string_cook_escape_char(pzS, pzD-1, (uint_t)NL); + if (ct == 0) + return NULL; + + pzS += ct; + } /* if (q != '\'') */ + + /* + * OTHERWISE, we only process "\\", "\'" and "\#" sequences. + * The latter only to easily hide preprocessing directives. + */ + else switch (*pzS) { + case '\\': + case '\'': + case '#': + pzD[-1] = *pzS++; + } + } /* switch (*(pzD++) = *(pzS++)) */ + } /* for (;;) */ +} + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/cook.c */ diff --git a/autoopts/enum.c b/autoopts/enum.c new file mode 100644 index 0000000..7f92e0b --- /dev/null +++ b/autoopts/enum.c @@ -0,0 +1,628 @@ + +/** + * \file enumeration.c + * + * Handle options with enumeration names and bit mask bit names + * for their arguments. + * + * @addtogroup autoopts + * @{ + */ +/* + * This routine will run run-on options through a pager so the + * user may examine, print or edit them at their leisure. + * + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +static void +enum_err(tOptions * pOpts, tOptDesc * pOD, + char const * const * paz_names, int name_ct) +{ + size_t max_len = 0; + size_t ttl_len = 0; + int ct_down = name_ct; + int hidden = 0; + + /* + * A real "pOpts" pointer means someone messed up. Give a real error. + */ + if (pOpts > OPTPROC_EMIT_LIMIT) + fprintf(option_usage_fp, pz_enum_err_fmt, pOpts->pzProgName, + pOD->optArg.argString, pOD->pz_Name); + + fprintf(option_usage_fp, zValidKeys, pOD->pz_Name); + + /* + * If the first name starts with this funny character, then we have + * a first value with an unspellable name. You cannot specify it. + * So, we don't list it either. + */ + if (**paz_names == 0x7F) { + paz_names++; + hidden = 1; + ct_down = --name_ct; + } + + /* + * Figure out the maximum length of any name, plus the total length + * of all the names. + */ + { + char const * const * paz = paz_names; + + do { + size_t len = strlen(*(paz++)) + 1; + if (len > max_len) + max_len = len; + ttl_len += len; + } while (--ct_down > 0); + + ct_down = name_ct; + } + + /* + * IF any one entry is about 1/2 line or longer, print one per line + */ + if (max_len > 35) { + do { + fprintf(option_usage_fp, ENUM_ERR_LINE, *(paz_names++)); + } while (--ct_down > 0); + } + + /* + * ELSE IF they all fit on one line, then do so. + */ + else if (ttl_len < 76) { + fputc(' ', option_usage_fp); + do { + fputc(' ', option_usage_fp); + fputs(*(paz_names++), option_usage_fp); + } while (--ct_down > 0); + fputc(NL, option_usage_fp); + } + + /* + * Otherwise, columnize the output + */ + else { + unsigned int ent_no = 0; + char fmt[16]; /* format for all-but-last entries on a line */ + + if (snprintf(fmt, 16, ENUM_ERR_WIDTH, (int)max_len) >= 16) + option_exits(EXIT_FAILURE); + max_len = 78 / max_len; /* max_len is now max entries on a line */ + fputs(TWO_SPACES_STR, option_usage_fp); + + /* + * Loop through all but the last entry + */ + ct_down = name_ct; + while (--ct_down > 0) { + if (++ent_no == max_len) { + /* + * Last entry on a line. Start next line, too. + */ + fprintf(option_usage_fp, NLSTR_SPACE_FMT, *(paz_names++)); + ent_no = 0; + } + + else + fprintf(option_usage_fp, fmt, *(paz_names++) ); + } + fprintf(option_usage_fp, NLSTR_FMT, *paz_names); + } + + if (pOpts > OPTPROC_EMIT_LIMIT) { + fprintf(option_usage_fp, zIntRange, hidden, name_ct - 1 + hidden); + + (*(pOpts->pUsageProc))(pOpts, EXIT_FAILURE); + /* NOTREACHED */ + } + + if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_MEMBERSHIP) { + fprintf(option_usage_fp, zLowerBits, name_ct); + fputs(zSetMemberSettings, option_usage_fp); + } else { + fprintf(option_usage_fp, zIntRange, hidden, name_ct - 1 + hidden); + } +} + +/** + * Convert a name or number into a binary number. + * "~0" and "-1" will be converted to the largest value in the enumeration. + * + * @param name the keyword name (number) to convert + * @param pOpts the program's option descriptor + * @param pOD the option descriptor for this option + * @param paz_names the list of keywords for this option + * @param name_ct the count of keywords + */ +static uintptr_t +find_name(char const * name, tOptions * pOpts, tOptDesc * pOD, + char const * const * paz_names, unsigned int name_ct) +{ + /* + * Return the matching index as a pointer sized integer. + * The result gets stashed in a char * pointer. + */ + uintptr_t res = name_ct; + size_t len = strlen((char *)name); + uintptr_t idx; + + if (IS_DEC_DIGIT_CHAR(*name)) { + char * pz = VOIDP(name); + unsigned long val = strtoul(pz, &pz, 0); + if ((*pz == NUL) && (val < name_ct)) + return (uintptr_t)val; + pz_enum_err_fmt = znum_too_large; + option_usage_fp = stderr; + enum_err(pOpts, pOD, paz_names, (int)name_ct); + return name_ct; + } + + if (IS_INVERSION_CHAR(*name) && (name[2] == NUL)) { + if ( ((name[0] == '~') && (name[1] == '0')) + || ((name[0] == '-') && (name[1] == '1'))) + return (uintptr_t)(name_ct - 1); + goto oops; + } + + /* + * Look for an exact match, but remember any partial matches. + * Multiple partial matches means we have an ambiguous match. + */ + for (idx = 0; idx < name_ct; idx++) { + if (strncmp((char *)paz_names[idx], (char *)name, len) == 0) { + if (paz_names[idx][len] == NUL) + return idx; /* full match */ + + if (res == name_ct) + res = idx; /* save partial match */ + else + res = (uintptr_t)~0; /* may yet find full match */ + } + } + + if (res < name_ct) + return res; /* partial match */ + + oops: + + pz_enum_err_fmt = (res == name_ct) ? zNoKey : zambiguous_key; + option_usage_fp = stderr; + enum_err(pOpts, pOD, paz_names, (int)name_ct); + return name_ct; +} + + +/*=export_func optionKeywordName + * what: Convert between enumeration values and strings + * private: + * + * arg: tOptDesc *, pOD, enumeration option description + * arg: unsigned int, enum_val, the enumeration value to map + * + * ret_type: char const * + * ret_desc: the enumeration name from const memory + * + * doc: This converts an enumeration value into the matching string. +=*/ +char const * +optionKeywordName(tOptDesc * pOD, unsigned int enum_val) +{ + tOptDesc od = { 0 }; + od.optArg.argEnum = enum_val; + + (*(pOD->pOptProc))(OPTPROC_RETURN_VALNAME, &od ); + return od.optArg.argString; +} + + +/*=export_func optionEnumerationVal + * what: Convert from a string to an enumeration value + * private: + * + * arg: tOptions *, pOpts, the program options descriptor + * arg: tOptDesc *, pOD, enumeration option description + * arg: char const * const *, paz_names, list of enumeration names + * arg: unsigned int, name_ct, number of names in list + * + * ret_type: uintptr_t + * ret_desc: the enumeration value + * + * doc: This converts the optArg.argString string from the option description + * into the index corresponding to an entry in the name list. + * This will match the generated enumeration value. + * Full matches are always accepted. Partial matches are accepted + * if there is only one partial match. +=*/ +uintptr_t +optionEnumerationVal(tOptions * pOpts, tOptDesc * pOD, + char const * const * paz_names, unsigned int name_ct) +{ + uintptr_t res = 0UL; + + /* + * IF the program option descriptor pointer is invalid, + * then it is some sort of special request. + */ + switch ((uintptr_t)pOpts) { + case (uintptr_t)OPTPROC_EMIT_USAGE: + /* + * print the list of enumeration names. + */ + enum_err(pOpts, pOD, paz_names, (int)name_ct); + break; + + case (uintptr_t)OPTPROC_EMIT_SHELL: + { + unsigned int ix = (unsigned int)pOD->optArg.argEnum; + /* + * print the name string. + */ + if (ix >= name_ct) + printf(INVALID_FMT, ix); + else + fputs(paz_names[ ix ], stdout); + + break; + } + + case (uintptr_t)OPTPROC_RETURN_VALNAME: + { + unsigned int ix = (unsigned int)pOD->optArg.argEnum; + /* + * Replace the enumeration value with the name string. + */ + if (ix >= name_ct) + return (uintptr_t)INVALID_STR; + + pOD->optArg.argString = paz_names[ix]; + break; + } + + default: + if ((pOD->fOptState & OPTST_RESET) != 0) + break; + + res = find_name(pOD->optArg.argString, pOpts, pOD, paz_names, name_ct); + + if (pOD->fOptState & OPTST_ALLOC_ARG) { + AGFREE(pOD->optArg.argString); + pOD->fOptState &= ~OPTST_ALLOC_ARG; + pOD->optArg.argString = NULL; + } + } + + return res; +} + +static void +set_memb_shell(tOptions * pOpts, tOptDesc * pOD, char const * const * paz_names, + unsigned int name_ct) +{ + /* + * print the name string. + */ + unsigned int ix = 0; + uintptr_t bits = (uintptr_t)pOD->optCookie; + size_t len = 0; + + (void)pOpts; + bits &= ((uintptr_t)1 << (uintptr_t)name_ct) - (uintptr_t)1; + + while (bits != 0) { + if (bits & 1) { + if (len++ > 0) fputs(OR_STR, stdout); + fputs(paz_names[ix], stdout); + } + if (++ix >= name_ct) break; + bits >>= 1; + } +} + +static void +set_memb_names(tOptions * opts, tOptDesc * od, char const * const * nm_list, + unsigned int nm_ct) +{ + char * pz; + uintptr_t mask = (1UL << (uintptr_t)nm_ct) - 1UL; + uintptr_t bits = (uintptr_t)od->optCookie & mask; + unsigned int ix = 0; + size_t len = 1; + + /* + * Replace the enumeration value with the name string. + * First, determine the needed length, then allocate and fill in. + */ + while (bits != 0) { + if (bits & 1) + len += strlen(nm_list[ix]) + PLUS_STR_LEN + 1; + if (++ix >= nm_ct) break; + bits >>= 1; + } + + od->optArg.argString = pz = AGALOC(len, "enum"); + bits = (uintptr_t)od->optCookie & mask; + if (bits == 0) { + *pz = NUL; + return; + } + + for (ix = 0; ; ix++) { + size_t nln; + int doit = bits & 1; + + bits >>= 1; + if (doit == 0) + continue; + + nln = strlen(nm_list[ix]); + memcpy(pz, nm_list[ix], nln); + pz += nln; + if (bits == 0) + break; + memcpy(pz, PLUS_STR, PLUS_STR_LEN); + pz += PLUS_STR_LEN; + } + *pz = NUL; + (void)opts; +} + +/** + * Check membership start conditions. An equal character (@samp{=}) says to + * clear the result and not carry over any residual value. A carat + * (@samp{^}), which may follow the equal character, says to invert the + * result. The scanning pointer is advanced past these characters and any + * leading white space. Invalid sequences are indicated by setting the + * scanning pointer to NULL. + * + * @param od the set membership option description + * @param argp a pointer to the string scanning pointer + * @param invert a pointer to the boolean inversion indicator + * + * @returns either zero or the original value for the optCookie. + */ +static uintptr_t +check_membership_start(tOptDesc * od, char const ** argp, bool * invert) +{ + uintptr_t res = (uintptr_t)od->optCookie; + char const * arg = SPN_WHITESPACE_CHARS(od->optArg.argString); + if ((arg == NULL) || (*arg == NUL)) + goto member_start_fail; + + *invert = false; + + switch (*arg) { + case '=': + res = 0UL; + arg = SPN_WHITESPACE_CHARS(arg + 1); + switch (*arg) { + case '=': case ',': + goto member_start_fail; + case '^': + goto inversion; + default: + break; + } + break; + + case '^': + inversion: + *invert = true; + arg = SPN_WHITESPACE_CHARS(arg + 1); + if (*arg != ',') + break; + /* FALLTHROUGH */ + + case ',': + goto member_start_fail; + + default: + break; + } + + *argp = arg; + return res; + +member_start_fail: + *argp = NULL; + return 0UL; +} + +/** + * convert a name to a bit. Look up a name string to get a bit number + * and shift the value "1" left that number of bits. + * + * @param opts program options descriptor + * @param od the set membership option description + * @param pz address of the start of the bit name + * @param nm_list the list of names for this option + * @param nm_ct the number of entries in this list + * + * @returns 0UL on error, other an unsigned long with the correct bit set. + */ +static uintptr_t +find_member_bit(tOptions * opts, tOptDesc * od, char const * pz, int len, + char const * const * nm_list, unsigned int nm_ct) +{ + char nm_buf[ AO_NAME_SIZE ]; + + memcpy(nm_buf, pz, len); + nm_buf[len] = NUL; + + { + unsigned int shift_ct = (unsigned int) + find_name(nm_buf, opts, od, nm_list, nm_ct); + if (shift_ct >= nm_ct) + return 0UL; + + return 1UL << shift_ct; + } +} + +/*=export_func optionMemberList + * what: Get the list of members of a bit mask set + * + * arg: tOptDesc *, od, the set membership option description + * + * ret_type: char * + * ret_desc: the names of the set bits + * + * doc: This converts the OPT_VALUE_name mask value to a allocated string. + * It is the caller's responsibility to free the string. +=*/ +char * +optionMemberList(tOptDesc * od) +{ + uintptr_t sv = od->optArg.argIntptr; + char * res; + (*(od->pOptProc))(OPTPROC_RETURN_VALNAME, od); + res = VOIDP(od->optArg.argString); + od->optArg.argIntptr = sv; + return res; +} + +/*=export_func optionSetMembers + * what: Convert between bit flag values and strings + * private: + * + * arg: tOptions *, opts, the program options descriptor + * arg: tOptDesc *, od, the set membership option description + * arg: char const * const *, + * nm_list, list of enumeration names + * arg: unsigned int, nm_ct, number of names in list + * + * doc: This converts the optArg.argString string from the option description + * into the index corresponding to an entry in the name list. + * This will match the generated enumeration value. + * Full matches are always accepted. Partial matches are accepted + * if there is only one partial match. +=*/ +void +optionSetMembers(tOptions * opts, tOptDesc * od, + char const * const * nm_list, unsigned int nm_ct) +{ + /* + * IF the program option descriptor pointer is invalid, + * then it is some sort of special request. + */ + switch ((uintptr_t)opts) { + case (uintptr_t)OPTPROC_EMIT_USAGE: + enum_err(OPTPROC_EMIT_USAGE, od, nm_list, nm_ct); + return; + + case (uintptr_t)OPTPROC_EMIT_SHELL: + set_memb_shell(opts, od, nm_list, nm_ct); + return; + + case (uintptr_t)OPTPROC_RETURN_VALNAME: + set_memb_names(opts, od, nm_list, nm_ct); + return; + + default: + break; + } + + if ((od->fOptState & OPTST_RESET) != 0) + return; + + { + char const * arg; + bool invert; + uintptr_t res = check_membership_start(od, &arg, &invert); + if (arg == NULL) + goto fail_return; + + while (*arg != NUL) { + bool inv_val = false; + int len; + + switch (*arg) { + case ',': + arg = SPN_WHITESPACE_CHARS(arg+1); + if ((*arg == ',') || (*arg == '|')) + goto fail_return; + continue; + + case '-': + case '!': + inv_val = true; + /* FALLTHROUGH */ + + case '+': + case '|': + arg = SPN_WHITESPACE_CHARS(arg+1); + } + + len = (int)(BRK_SET_SEPARATOR_CHARS(arg) - arg); + if (len == 0) + break; + + if ((len == 3) && (strncmp(arg, zAll, 3) == 0)) { + if (inv_val) + res = 0; + else res = ~0UL; + } + else if ((len == 4) && (strncmp(arg, zNone, 4) == 0)) { + if (! inv_val) + res = 0; + } + else do { + char * pz; + uintptr_t bit = strtoul(arg, &pz, 0); + + if (pz != arg + len) { + bit = find_member_bit(opts, od, pz, len, nm_list, nm_ct); + if (bit == 0UL) + goto fail_return; + } + if (inv_val) + res &= ~bit; + else res |= bit; + } while (false); + + arg = SPN_WHITESPACE_CHARS(arg + len); + } + + if (invert) + res ^= ~0UL; + + if (nm_ct < (8 * sizeof(uintptr_t))) + res &= (1UL << nm_ct) - 1UL; + + od->optCookie = VOIDP(res); + } + return; + +fail_return: + od->optCookie = VOIDP(0); +} + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/enum.c */ diff --git a/autoopts/env.c b/autoopts/env.c new file mode 100644 index 0000000..16f0e95 --- /dev/null +++ b/autoopts/env.c @@ -0,0 +1,261 @@ + +/** + * \file environment.c + * + * This file contains all of the routines that must be linked into + * an executable to use the generated option processing. The optional + * routines are in separately compiled modules so that they will not + * necessarily be linked in. + * + * @addtogroup autoopts + * @{ + */ +/* + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +/* + * doPrognameEnv - check for preset values from the ${PROGNAME} + * environment variable. This is accomplished by parsing the text into + * tokens, temporarily replacing the arg vector and calling + * immediate_opts and/or regular_opts. + */ +static void +doPrognameEnv(tOptions * pOpts, teEnvPresetType type) +{ + char const * env_opts = getenv(pOpts->pzPROGNAME); + token_list_t * pTL; + int sv_argc; + proc_state_mask_t sv_flag; + char ** sv_argv; + + /* + * No such beast? Then bail now. + */ + if (env_opts == NULL) + return; + + /* + * Tokenize the string. If there's nothing of interest, we'll bail + * here immediately. + */ + pTL = ao_string_tokenize(env_opts); + if (pTL == NULL) + return; + + /* + * Substitute our $PROGNAME argument list for the real one + */ + sv_argc = (int)pOpts->origArgCt; + sv_argv = pOpts->origArgVect; + sv_flag = pOpts->fOptSet; + + /* + * We add a bogus pointer to the start of the list. The program name + * has already been pulled from "argv", so it won't get dereferenced. + * The option scanning code will skip the "program name" at the start + * of this list of tokens, so we accommodate this way .... + */ + { + uintptr_t v = (uintptr_t)(pTL->tkn_list); + pOpts->origArgVect = VOIDP(v - sizeof(char *)); + } + pOpts->origArgCt = (unsigned int)pTL->tkn_ct + 1; + pOpts->fOptSet &= ~OPTPROC_ERRSTOP; + + pOpts->curOptIdx = 1; + pOpts->pzCurOpt = NULL; + + switch (type) { + case ENV_IMM: + (void)immediate_opts(pOpts); + break; + + case ENV_ALL: + (void)immediate_opts(pOpts); + pOpts->curOptIdx = 1; + pOpts->pzCurOpt = NULL; + /* FALLTHROUGH */ + + case ENV_NON_IMM: + (void)regular_opts(pOpts); + } + + /* + * Free up the temporary arg vector and restore the original program args. + */ + free(pTL); + pOpts->origArgVect = sv_argv; + pOpts->origArgCt = (unsigned int)sv_argc; + pOpts->fOptSet = sv_flag; +} + +static void +do_env_opt(tOptState * os, char * env_name, + tOptions * pOpts, teEnvPresetType type) +{ + os->pzOptArg = getenv(env_name); + if (os->pzOptArg == NULL) + return; + + os->flags = OPTST_PRESET | OPTST_ALLOC_ARG | os->pOD->fOptState; + os->optType = TOPT_UNDEFINED; + + if ( (os->pOD->pz_DisablePfx != NULL) + && (streqvcmp(os->pzOptArg, os->pOD->pz_DisablePfx) == 0)) { + os->flags |= OPTST_DISABLED; + os->pzOptArg = NULL; + handle_opt(pOpts, os); + return; + } + + switch (type) { + case ENV_IMM: + /* + * Process only immediate actions + */ + if (DO_IMMEDIATELY(os->flags)) + break; + return; + + case ENV_NON_IMM: + /* + * Process only NON immediate actions + */ + if (DO_NORMALLY(os->flags) || DO_SECOND_TIME(os->flags)) + break; + return; + + default: /* process everything */ + break; + } + + /* + * Make sure the option value string is persistent and consistent. + * + * The interpretation of the option value depends + * on the type of value argument the option takes + */ + if (OPTST_GET_ARGTYPE(os->pOD->fOptState) == OPARG_TYPE_NONE) { + /* + * Ignore any value. + */ + os->pzOptArg = NULL; + + } else if (os->pzOptArg[0] == NUL) { + /* + * If the argument is the empty string and the argument is + * optional, then treat it as if the option was not specified. + */ + if ((os->pOD->fOptState & OPTST_ARG_OPTIONAL) == 0) + return; + os->pzOptArg = NULL; + + } else { + AGDUPSTR(os->pzOptArg, os->pzOptArg, "option argument"); + os->flags |= OPTST_ALLOC_ARG; + } + + handle_opt(pOpts, os); +} + +/* + * env_presets - check for preset values from the envrionment + * This routine should process in all, immediate or normal modes.... + */ +static void +env_presets(tOptions * pOpts, teEnvPresetType type) +{ + int ct; + tOptState st; + char * pzFlagName; + size_t spaceLeft; + char zEnvName[ AO_NAME_SIZE ]; + + /* + * Finally, see if we are to look at the environment + * variables for initial values. + */ + if ((pOpts->fOptSet & OPTPROC_ENVIRON) == 0) + return; + + doPrognameEnv(pOpts, type); + + ct = pOpts->presetOptCt; + st.pOD = pOpts->pOptDesc; + + pzFlagName = zEnvName + + snprintf(zEnvName, sizeof(zEnvName), "%s_", pOpts->pzPROGNAME); + spaceLeft = AO_NAME_SIZE - (unsigned long)(pzFlagName - zEnvName) - 1; + + for (;ct-- > 0; st.pOD++) { + size_t nln; + + /* + * If presetting is disallowed, then skip this entry + */ + if ( ((st.pOD->fOptState & OPTST_NO_INIT) != 0) + || (st.pOD->optEquivIndex != NO_EQUIVALENT) ) + continue; + + /* + * IF there is no such environment variable, + * THEN skip this entry, too. + */ + nln = strlen(st.pOD->pz_NAME) + 1; + if (nln <= spaceLeft) { + /* + * Set up the option state + */ + memcpy(pzFlagName, st.pOD->pz_NAME, nln); + do_env_opt(&st, zEnvName, pOpts, type); + } + } + + /* + * Special handling for ${PROGNAME_LOAD_OPTS} + */ + if ( (pOpts->specOptIdx.save_opts != NO_EQUIVALENT) + && (pOpts->specOptIdx.save_opts != 0)) { + size_t nln; + st.pOD = pOpts->pOptDesc + pOpts->specOptIdx.save_opts + 1; + + if (st.pOD->pz_NAME == NULL) + return; + + nln = strlen(st.pOD->pz_NAME) + 1; + + if (nln > spaceLeft) + return; + + memcpy(pzFlagName, st.pOD->pz_NAME, nln); + do_env_opt(&st, zEnvName, pOpts, type); + } +} + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/environment.c */ diff --git a/autoopts/file.c b/autoopts/file.c new file mode 100644 index 0000000..14efe8f --- /dev/null +++ b/autoopts/file.c @@ -0,0 +1,201 @@ + +/** + * \file file.c + * + * Handle options that have file names for arguments. + * + * @addtogroup autoopts + * @{ + */ +/* + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +/** + * Make sure the directory containing the subject file exists and that + * the file exists or does not exist, per the option requirements. + * + * @param ftype file existence type flags + * @param pOpts program option descriptor + * @param pOD the option descriptor + */ +static void +check_existence(teOptFileType ftype, tOptions * pOpts, tOptDesc * pOD) +{ + char const * fname = pOD->optArg.argString; + struct stat sb; + + errno = 0; + + switch (ftype & FTYPE_MODE_EXIST_MASK) { + case FTYPE_MODE_MUST_NOT_EXIST: + if ((stat(fname, &sb) == 0) || (errno != ENOENT)) { + if (errno == 0) + errno = EINVAL; + fserr_exit(pOpts->pzProgName, "stat", fname); + /* NOTREACHED */ + } + /* FALLTHROUGH */ + + default: + case FTYPE_MODE_MAY_EXIST: + { + char * p = strrchr(fname, DIRCH); + size_t l; + + if (p == NULL) + /* + * The file may or may not exist and its directory is ".". + * Assume that "." exists. + */ + break; + + l = (size_t)(p - fname); + p = AGALOC(l + 1, "fname"); + memcpy(p, fname, l); + p[l] = NUL; + + if ((stat(p, &sb) != 0) || (errno = EINVAL, ! S_ISDIR(sb.st_mode))) + fserr_exit(pOpts->pzProgName, "stat", p); + /* NOTREACHED */ + + AGFREE(p); + break; + } + + case FTYPE_MODE_MUST_EXIST: + if ( (stat(fname, &sb) != 0) + || (errno = EINVAL, ! S_ISREG(sb.st_mode)) ) + fserr_exit(pOpts->pzProgName, "stat", fname); + /* NOTREACHED */ + + break; + } +} + +/** + * Open the specified file with open(2) and save the FD. + * + * @param pOpts program option descriptor + * @param pOD the option descriptor + * @param mode the open mode (uses int flags value) + */ +static void +open_file_fd(tOptions * pOpts, tOptDesc * pOD, tuFileMode mode) +{ + int fd = open(pOD->optArg.argString, mode.file_flags); + if (fd < 0) + fserr_exit(pOpts->pzProgName, "open", pOD->optArg.argString); + /* NOTREACHED */ + + if ((pOD->fOptState & OPTST_ALLOC_ARG) != 0) + pOD->optCookie = VOIDP(pOD->optArg.argString); + else + AGDUPSTR(pOD->optCookie, pOD->optArg.argString, "file name"); + + pOD->optArg.argFd = fd; + pOD->fOptState &= ~OPTST_ALLOC_ARG; +} + +/** + * Open the specified file with open(2) and save the FD. + * + * @param pOpts program option descriptor + * @param pOD the option descriptor + * @param mode the open mode (uses "char *" mode value) + */ +static void +fopen_file_fp(tOptions * pOpts, tOptDesc * pOD, tuFileMode mode) +{ + FILE * fp = fopen(pOD->optArg.argString, mode.file_mode); + if (fp == NULL) + fserr_exit(pOpts->pzProgName, "fopen", pOD->optArg.argString); + /* NOTREACHED */ + + if ((pOD->fOptState & OPTST_ALLOC_ARG) != 0) + pOD->optCookie = VOIDP(pOD->optArg.argString); + else + AGDUPSTR(pOD->optCookie, pOD->optArg.argString, "file name"); + + pOD->optArg.argFp = fp; + pOD->fOptState &= ~OPTST_ALLOC_ARG; +} + +/*=export_func optionFileCheck + * private: + * + * what: Decipher a boolean value + * arg: + tOptions * + pOpts + program options descriptor + + * arg: + tOptDesc * + pOptDesc + the descriptor for this arg + + * arg: + teOptFileType + ftype + File handling type + + * arg: + tuFileMode + mode + file open mode (if needed) + + * + * doc: + * Make sure the named file conforms with the file type mode. + * The mode specifies if the file must exist, must not exist or may + * (or may not) exist. The mode may also specify opening the + * file: don't, open just the descriptor (fd), or open as a stream + * (FILE * pointer). +=*/ +void +optionFileCheck(tOptions * pOpts, tOptDesc * pOD, + teOptFileType ftype, tuFileMode mode) +{ + if (pOpts <= OPTPROC_EMIT_LIMIT) { + if (pOpts != OPTPROC_EMIT_USAGE) + return; + + switch (ftype & FTYPE_MODE_EXIST_MASK) { + case FTYPE_MODE_MUST_NOT_EXIST: + fputs(zFileCannotExist + tab_skip_ct, option_usage_fp); + break; + + case FTYPE_MODE_MUST_EXIST: + fputs(zFileMustExist + tab_skip_ct, option_usage_fp); + break; + } + return; + } + + if ((pOD->fOptState & OPTST_RESET) != 0) { + if (pOD->optCookie != NULL) + AGFREE(pOD->optCookie); + return; + } + + check_existence(ftype, pOpts, pOD); + + switch (ftype & FTYPE_MODE_OPEN_MASK) { + default: + case FTYPE_MODE_NO_OPEN: break; + case FTYPE_MODE_OPEN_FD: open_file_fd( pOpts, pOD, mode); break; + case FTYPE_MODE_FOPEN_FP: fopen_file_fp(pOpts, pOD, mode); break; + } +} + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/file.c */ diff --git a/autoopts/find.c b/autoopts/find.c new file mode 100644 index 0000000..03ae103 --- /dev/null +++ b/autoopts/find.c @@ -0,0 +1,765 @@ +/** + * @file check.c + * + * @brief Hunt for options in the option descriptor list + * + * This file contains the routines that deal with processing quoted strings + * into an internal format. + * + * @addtogroup autoopts + * @{ + */ +/* + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +/** + * find the name and name length we are looking for + */ +static int +parse_opt(char const ** nm_pp, char ** arg_pp, char * buf, size_t bufsz) +{ + int res = 0; + char const * p = *nm_pp; + *arg_pp = NULL; + + for (;;) { + switch (*(p++)) { + case NUL: return res; + + case '=': + memcpy(buf, *nm_pp, (size_t)res); + + buf[res] = NUL; + *nm_pp = buf; + *arg_pp = (char *)p; + return res; + + default: + if (++res >= (int)bufsz) + return -1; + } + } +} + +/** + * print out the options that match the given name. + * + * @param pOpts option data + * @param opt_name name of option to look for + */ +static void +opt_ambiguities(tOptions * opts, char const * name, int nm_len) +{ + char const * const hyph = + NAMED_OPTS(opts) ? "" : LONG_OPT_MARKER; + + tOptDesc * pOD = opts->pOptDesc; + int idx = 0; + + fputs(zambig_list_msg, stderr); + do { + if (pOD->pz_Name == NULL) + continue; /* doc option */ + + if (strneqvcmp(name, pOD->pz_Name, nm_len) == 0) + fprintf(stderr, zambig_file, hyph, pOD->pz_Name); + + else if ( (pOD->pz_DisableName != NULL) + && (strneqvcmp(name, pOD->pz_DisableName, nm_len) == 0) + ) + fprintf(stderr, zambig_file, hyph, pOD->pz_DisableName); + } while (pOD++, (++idx < opts->optCt)); +} + +/** + * Determine the number of options that match the name + * + * @param pOpts option data + * @param opt_name name of option to look for + * @param nm_len length of provided name + * @param index pointer to int for option index + * @param disable pointer to bool to mark disabled option + * @return count of options that match + */ +static int +opt_match_ct(tOptions * opts, char const * name, int nm_len, + int * ixp, bool * disable) +{ + int matchCt = 0; + int idx = 0; + int idxLim = opts->optCt; + tOptDesc * pOD = opts->pOptDesc; + + do { + /* + * If option disabled or a doc option, skip to next + */ + if (pOD->pz_Name == NULL) + continue; + + if ( SKIP_OPT(pOD) + && (pOD->fOptState != (OPTST_OMITTED | OPTST_NO_INIT))) + continue; + + if (strneqvcmp(name, pOD->pz_Name, nm_len) == 0) { + /* + * IF we have a complete match + * THEN it takes priority over any already located partial + */ + if (pOD->pz_Name[ nm_len ] == NUL) { + *ixp = idx; + return 1; + } + } + + /* + * IF there is a disable name + * *AND* the option name matches the disable name + * THEN ... + */ + else if ( (pOD->pz_DisableName != NULL) + && (strneqvcmp(name, pOD->pz_DisableName, nm_len) == 0) + ) { + *disable = true; + + /* + * IF we have a complete match + * THEN it takes priority over any already located partial + */ + if (pOD->pz_DisableName[ nm_len ] == NUL) { + *ixp = idx; + return 1; + } + } + + else + continue; /* does not match any option */ + + /* + * We found a full or partial match, either regular or disabling. + * Remember the index for later. + */ + *ixp = idx; + ++matchCt; + + } while (pOD++, (++idx < idxLim)); + + return matchCt; +} + +/** + * Set the option to the indicated option number. + * + * @param opts option data + * @param arg option argument (if glued to name) + * @param idx option index + * @param disable mark disabled option + * @param st state about current option + */ +static tSuccess +opt_set(tOptions * opts, char * arg, int idx, bool disable, tOptState * st) +{ + tOptDesc * pOD = opts->pOptDesc + idx; + + if (SKIP_OPT(pOD)) { + if ((opts->fOptSet & OPTPROC_ERRSTOP) == 0) + return FAILURE; + + fprintf(stderr, zDisabledErr, opts->pzProgName, pOD->pz_Name); + if (pOD->pzText != NULL) + fprintf(stderr, SET_OFF_FMT, pOD->pzText); + fputc(NL, stderr); + (*opts->pUsageProc)(opts, EXIT_FAILURE); + /* NOTREACHED */ + _exit(EXIT_FAILURE); /* to be certain */ + } + + /* + * IF we found a disablement name, + * THEN set the bit in the callers' flag word + */ + if (disable) + st->flags |= OPTST_DISABLED; + + st->pOD = pOD; + st->pzOptArg = arg; + st->optType = TOPT_LONG; + + return SUCCESS; +} + +/** + * An option was not found. Check for default option and set it + * if there is one. Otherwise, handle the error. + * + * @param opts option data + * @param name name of option to look for + * @param arg option argument + * @param st state about current option + * + * @return success status + */ +static tSuccess +opt_unknown(tOptions * opts, char const * name, char * arg, tOptState * st) +{ + /* + * IF there is no equal sign + * *AND* we are using named arguments + * *AND* there is a default named option, + * THEN return that option. + */ + if ( (arg == NULL) + && NAMED_OPTS(opts) + && (opts->specOptIdx.default_opt != NO_EQUIVALENT)) { + + st->pOD = opts->pOptDesc + opts->specOptIdx.default_opt; + st->pzOptArg = name; + st->optType = TOPT_DEFAULT; + return SUCCESS; + } + + if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0) { + fprintf(stderr, zIllOptStr, opts->pzProgPath, name); + (*opts->pUsageProc)(opts, EXIT_FAILURE); + /* NOTREACHED */ + _exit(EXIT_FAILURE); /* to be certain */ + } + + return FAILURE; +} + +/** + * Several options match the provided name. + * + * @param opts option data + * @param name name of option to look for + * @param match_ct number of matching options + * + * @return success status (always FAILURE, if it returns) + */ +static tSuccess +opt_ambiguous(tOptions * opts, char const * name, int match_ct) +{ + if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0) { + fprintf(stderr, zambig_opt_fmt, opts->pzProgPath, name, match_ct); + if (match_ct <= 4) + opt_ambiguities(opts, name, (int)strlen(name)); + (*opts->pUsageProc)(opts, EXIT_FAILURE); + /* NOTREACHED */ + _exit(EXIT_FAILURE); /* to be certain */ + } + return FAILURE; +} + +/*=export_func optionVendorOption + * private: + * + * what: Process a vendor option + * arg: + tOptions * + pOpts + program options descriptor + + * arg: + tOptDesc * + pOptDesc + the descriptor for this arg + + * + * doc: + * For POSIX specified utilities, the options are constrained to the options, + * @xref{config attributes, Program Configuration}. AutoOpts clients should + * never specify this directly. It gets referenced when the option + * definitions contain a "vendor-opt" attribute. +=*/ +void +optionVendorOption(tOptions * pOpts, tOptDesc * pOD) +{ + tOptState opt_st = OPTSTATE_INITIALIZER(PRESET); + char const * vopt_str = pOD->optArg.argString; + + if (pOpts <= OPTPROC_EMIT_LIMIT) + return; + + if ((pOD->fOptState & OPTST_RESET) != 0) + return; + + if ((pOD->fOptState & OPTPROC_IMMEDIATE) == 0) + opt_st.flags = OPTST_DEFINED; + + if ( ((pOpts->fOptSet & OPTPROC_VENDOR_OPT) == 0) + || ! SUCCESSFUL(opt_find_long(pOpts, vopt_str, &opt_st)) + || ! SUCCESSFUL(get_opt_arg(pOpts, &opt_st)) ) + { + fprintf(stderr, zIllVendOptStr, pOpts->pzProgName, vopt_str); + (*pOpts->pUsageProc)(pOpts, EXIT_FAILURE); + /* NOTREACHED */ + _exit(EXIT_FAILURE); /* to be certain */ + } + + /* + * See if we are in immediate handling state. + */ + if (pOpts->fOptSet & OPTPROC_IMMEDIATE) { + /* + * See if the enclosed option is okay with that state. + */ + if (DO_IMMEDIATELY(opt_st.flags)) + (void)handle_opt(pOpts, &opt_st); + + } else { + /* + * non-immediate direction. + * See if the enclosed option is okay with that state. + */ + if (DO_NORMALLY(opt_st.flags) || DO_SECOND_TIME(opt_st.flags)) + (void)handle_opt(pOpts, &opt_st); + } +} + +/** + * Find the option descriptor by full name. + * + * @param opts option data + * @param opt_name name of option to look for + * @param state state about current option + * + * @return success status + */ +static tSuccess +opt_find_long(tOptions * opts, char const * opt_name, tOptState * state) +{ + char name_buf[128]; + char * opt_arg; + int nm_len = parse_opt(&opt_name, &opt_arg, name_buf, sizeof(name_buf)); + + int idx = 0; + bool disable = false; + int ct; + + if (nm_len <= 1) { + if ((opts->fOptSet & OPTPROC_ERRSTOP) == 0) + return FAILURE; + + fprintf(stderr, zInvalOptName, opts->pzProgName, opt_name); + (*opts->pUsageProc)(opts, EXIT_FAILURE); + /* NOTREACHED */ + _exit(EXIT_FAILURE); /* to be certain */ + } + + ct = opt_match_ct(opts, opt_name, nm_len, &idx, &disable); + + /* + * See if we found one match, no matches or multiple matches. + */ + switch (ct) { + case 1: return opt_set(opts, opt_arg, idx, disable, state); + case 0: return opt_unknown(opts, opt_name, opt_arg, state); + default: return opt_ambiguous(opts, opt_name, ct); + } +} + + +/** + * Find the short option descriptor for the current option + * + * @param pOpts option data + * @param optValue option flag character + * @param pOptState state about current option + */ +static tSuccess +opt_find_short(tOptions * pOpts, uint_t optValue, tOptState * pOptState) +{ + tOptDesc * pRes = pOpts->pOptDesc; + int ct = pOpts->optCt; + + /* + * Search the option list + */ + do { + if (optValue != pRes->optValue) + continue; + + if (SKIP_OPT(pRes)) { + if ( (pRes->fOptState == (OPTST_OMITTED | OPTST_NO_INIT)) + && (pRes->pz_Name != NULL)) { + if ((pOpts->fOptSet & OPTPROC_ERRSTOP) == 0) + return FAILURE; + + fprintf(stderr, zDisabledErr, pOpts->pzProgPath, pRes->pz_Name); + if (pRes->pzText != NULL) + fprintf(stderr, SET_OFF_FMT, pRes->pzText); + fputc(NL, stderr); + (*pOpts->pUsageProc)(pOpts, EXIT_FAILURE); + /* NOTREACHED */ + _exit(EXIT_FAILURE); /* to be certain */ + } + goto short_opt_error; + } + + pOptState->pOD = pRes; + pOptState->optType = TOPT_SHORT; + return SUCCESS; + + } while (pRes++, --ct > 0); + + /* + * IF the character value is a digit + * AND there is a special number option ("-n") + * THEN the result is the "option" itself and the + * option is the specially marked "number" option. + */ + if ( IS_DEC_DIGIT_CHAR(optValue) + && (pOpts->specOptIdx.number_option != NO_EQUIVALENT) ) { + pOptState->pOD = \ + pRes = pOpts->pOptDesc + pOpts->specOptIdx.number_option; + (pOpts->pzCurOpt)--; + pOptState->optType = TOPT_SHORT; + return SUCCESS; + } + + short_opt_error: + + /* + * IF we are to stop on errors (the default, actually) + * THEN call the usage procedure. + */ + if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0) { + fprintf(stderr, zIllOptChr, pOpts->pzProgPath, optValue); + (*pOpts->pUsageProc)(pOpts, EXIT_FAILURE); + /* NOTREACHED */ + _exit(EXIT_FAILURE); /* to be certain */ + } + + return FAILURE; +} + +/** + * Process option with a required argument. Long options can either have a + * separate command line argument, or an argument attached by the '=' + * character. Figure out which. + * + * @param[in,out] opts the program option descriptor + * @param[in,out] o_st the option processing state + * @returns SUCCESS or FAILURE + */ +static tSuccess +get_opt_arg_must(tOptions * opts, tOptState * o_st) +{ + switch (o_st->optType) { + case TOPT_SHORT: + /* + * See if an arg string follows the flag character + */ + if (*++(opts->pzCurOpt) == NUL) + opts->pzCurOpt = opts->origArgVect[ opts->curOptIdx++ ]; + o_st->pzOptArg = opts->pzCurOpt; + break; + + case TOPT_LONG: + /* + * See if an arg string has already been assigned (glued on + * with an `=' character) + */ + if (o_st->pzOptArg == NULL) + o_st->pzOptArg = opts->origArgVect[ opts->curOptIdx++ ]; + break; + + default: +#ifdef DEBUG + fputs("AutoOpts lib error: option type not selected\n", stderr); + option_exits(EXIT_FAILURE); +#endif + + case TOPT_DEFAULT: + /* + * The option was selected by default. The current token is + * the option argument. + */ + break; + } + + /* + * Make sure we did not overflow the argument list. + */ + if (opts->curOptIdx > opts->origArgCt) { + fprintf(stderr, zMisArg, opts->pzProgPath, o_st->pOD->pz_Name); + return FAILURE; + } + + opts->pzCurOpt = NULL; /* next time advance to next arg */ + return SUCCESS; +} + +/** + * Process an option with an optional argument. For short options, it looks + * at the character after the option character, or it consumes the next full + * argument. For long options, it looks for an '=' character attachment to + * the long option name before deciding to take the next command line + * argument. + * + * @param pOpts the option descriptor + * @param o_st a structure for managing the current processing state + * @returns SUCCESS or does not return + */ +static tSuccess +get_opt_arg_may(tOptions * pOpts, tOptState * o_st) +{ + /* + * An option argument is optional. + */ + switch (o_st->optType) { + case TOPT_SHORT: + if (*++pOpts->pzCurOpt != NUL) + o_st->pzOptArg = pOpts->pzCurOpt; + else { + char * pzLA = pOpts->origArgVect[ pOpts->curOptIdx ]; + + /* + * BECAUSE it is optional, we must make sure + * we did not find another flag and that there + * is such an argument. + */ + if ((pzLA == NULL) || (*pzLA == '-')) + o_st->pzOptArg = NULL; + else { + pOpts->curOptIdx++; /* argument found */ + o_st->pzOptArg = pzLA; + } + } + break; + + case TOPT_LONG: + /* + * Look for an argument if we don't already have one (glued on + * with a `=' character) *AND* we are not in named argument mode + */ + if ( (o_st->pzOptArg == NULL) + && (! NAMED_OPTS(pOpts))) { + char * pzLA = pOpts->origArgVect[ pOpts->curOptIdx ]; + + /* + * BECAUSE it is optional, we must make sure + * we did not find another flag and that there + * is such an argument. + */ + if ((pzLA == NULL) || (*pzLA == '-')) + o_st->pzOptArg = NULL; + else { + pOpts->curOptIdx++; /* argument found */ + o_st->pzOptArg = pzLA; + } + } + break; + + default: + case TOPT_DEFAULT: + ao_bug(zbad_default_msg); + } + + /* + * After an option with an optional argument, we will + * *always* start with the next option because if there + * were any characters following the option name/flag, + * they would be interpreted as the argument. + */ + pOpts->pzCurOpt = NULL; + return SUCCESS; +} + +/** + * Process option that does not have an argument. + * + * @param[in,out] opts the program option descriptor + * @param[in,out] o_st the option processing state + * @returns SUCCESS or FAILURE + */ +static tSuccess +get_opt_arg_none(tOptions * pOpts, tOptState * o_st) +{ + /* + * No option argument. Make sure next time around we find + * the correct option flag character for short options + */ + if (o_st->optType == TOPT_SHORT) + (pOpts->pzCurOpt)++; + + /* + * It is a long option. Make sure there was no ``=xxx'' argument + */ + else if (o_st->pzOptArg != NULL) { + fprintf(stderr, zNoArg, pOpts->pzProgPath, o_st->pOD->pz_Name); + return FAILURE; + } + + /* + * It is a long option. Advance to next command line argument. + */ + else + pOpts->pzCurOpt = NULL; + + return SUCCESS; +} + +/** + * Process option. Figure out whether or not to look for an option argument. + * + * @param[in,out] opts the program option descriptor + * @param[in,out] o_st the option processing state + * @returns SUCCESS or FAILURE + */ +static tSuccess +get_opt_arg(tOptions * opts, tOptState * o_st) +{ + o_st->flags |= (o_st->pOD->fOptState & OPTST_PERSISTENT_MASK); + + /* + * Disabled options and options specified to not have arguments + * are handled with the "none" procedure. Otherwise, check the + * optional flag and call either the "may" or "must" function. + */ + if ((o_st->flags & OPTST_DISABLED) != 0) + return get_opt_arg_none(opts, o_st); + + switch (OPTST_GET_ARGTYPE(o_st->flags)) { + case OPARG_TYPE_STATIC: + { + /* + * Propagate the static arg + */ + tSuccess res = get_opt_arg_none(opts, o_st); + o_st->pzOptArg = o_st->pOD->optArg.argString; + return res; + } + + case OPARG_TYPE_NONE: + return get_opt_arg_none(opts, o_st); + } + + if (o_st->flags & OPTST_ARG_OPTIONAL) + return get_opt_arg_may( opts, o_st); + + return get_opt_arg_must(opts, o_st); +} + +/** + * Find the option descriptor for the current option. + * + * @param[in,out] opts the program option descriptor + * @param[in,out] o_st the option processing state + * @returns SUCCESS or FAILURE + */ +static tSuccess +find_opt(tOptions * opts, tOptState * o_st) +{ + /* + * IF we are continuing a short option list (e.g. -xyz...) + * THEN continue a single flag option. + * OTHERWISE see if there is room to advance and then do so. + */ + if ((opts->pzCurOpt != NULL) && (*opts->pzCurOpt != NUL)) + return opt_find_short(opts, (uint8_t)*(opts->pzCurOpt), o_st); + + if (opts->curOptIdx >= opts->origArgCt) + return PROBLEM; /* NORMAL COMPLETION */ + + opts->pzCurOpt = opts->origArgVect[ opts->curOptIdx ]; + + /* + * IF all arguments must be named options, ... + */ + if (NAMED_OPTS(opts)) { + char * pz = opts->pzCurOpt; + int def; + tSuccess res; + uint16_t * def_opt; + + opts->curOptIdx++; + + if (*pz != '-') + return opt_find_long(opts, pz, o_st); + + /* + * The name is prefixed with one or more hyphens. Strip them off + * and disable the "default_opt" setting. Use heavy recasting to + * strip off the "const" quality of the "default_opt" field. + */ + while (*(++pz) == '-') ; + def_opt = VOIDP(&(opts->specOptIdx.default_opt)); + def = *def_opt; + *def_opt = NO_EQUIVALENT; + res = opt_find_long(opts, pz, o_st); + *def_opt = (uint16_t)def; + return res; + } + + /* + * Note the kind of flag/option marker + */ + if (*((opts->pzCurOpt)++) != '-') + return PROBLEM; /* NORMAL COMPLETION - this + rest are operands */ + + /* + * Special hack for a hyphen by itself + */ + if (*(opts->pzCurOpt) == NUL) + return PROBLEM; /* NORMAL COMPLETION - this + rest are operands */ + + /* + * The current argument is to be processed as an option argument + */ + opts->curOptIdx++; + + /* + * We have an option marker. + * Test the next character for long option indication + */ + if (opts->pzCurOpt[0] == '-') { + if (*++(opts->pzCurOpt) == NUL) + /* + * NORMAL COMPLETION - NOT this arg, but rest are operands + */ + return PROBLEM; + + /* + * We do not allow the hyphen to be used as a flag value. + * Therefore, if long options are not to be accepted, we punt. + */ + if ((opts->fOptSet & OPTPROC_LONGOPT) == 0) { + fprintf(stderr, zIllOptStr, opts->pzProgPath, opts->pzCurOpt-2); + return FAILURE; + } + + return opt_find_long(opts, opts->pzCurOpt, o_st); + } + + /* + * If short options are not allowed, then do long + * option processing. Otherwise the character must be a + * short (i.e. single character) option. + */ + if ((opts->fOptSet & OPTPROC_SHORTOPT) != 0) + return opt_find_short(opts, (uint8_t)*(opts->pzCurOpt), o_st); + + return opt_find_long(opts, opts->pzCurOpt, o_st); +} + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/find.c */ diff --git a/autoopts/funcs.def b/autoopts/funcs.def new file mode 100644 index 0000000..f820c26 --- /dev/null +++ b/autoopts/funcs.def @@ -0,0 +1,1666 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * + * DO NOT EDIT THIS FILE (funcs.def) + * + * It has been extracted by getdefs from the following files: + * + * autoopts.c + * alias.c + * boolean.c + * check.c + * configfile.c + * cook.c + * enum.c + * env.c + * file.c + * find.c + * genshell.c + * load.c + * makeshell.c + * nested.c + * numeric.c + * pgusage.c + * putshell.c + * reset.c + * restore.c + * save.c + * sort.c + * stack.c + * streqvcmp.c + * text_mmap.c + * time.c + * tokenize.c + * usage.c + * version.c + * init.c + */ +autogen definitions options_h; + +/* GLOBALDEFS */ + +#line 279 "autoopts.c" + library = 'opts'; + header = 'your-opts.h'; + lib_description = +'These are the routines that libopts users may call directly from their +code. There are several other routines that can be called by code +generated by the libopts option templates, but they are not to be +called from any other user code. The @file{options.h} header is +fairly clear about this, too.'; + + +#line 212 "cook.c" +export_func = { + name = 'ao_string_cook'; + private; + what = 'concatenate and escape-process strings'; + arg = { + arg_type = 'char *'; + arg_name = 'pzScan'; + arg_desc = 'The *MODIFIABLE* input buffer'; + }; + arg = { + arg_type = 'int *'; + arg_name = 'lnct_p'; + arg_desc = 'The (possibly NULL) pointer to a line count'; + }; + ret-type = 'char *'; + ret-desc = 'The address of the text following the processed strings. +The return value is NULL if the strings are ill-formed.'; + doc = +'A series of one or more quoted strings are concatenated together. +If they are quoted with double quotes (@code{"}), then backslash +escapes are processed per the C programming language. If they are +single quote strings, then the backslashes are honored only when they +precede another backslash or a single quote character.'; + err = '@code{NULL} is returned if the string(s) is/are mal-formed.'; + srcfile = 'cook.c'; + linenum = '212'; +}; + + +#line 32 "cook.c" +export_func = { + name = 'ao_string_cook_escape_char'; + private; + what = 'escape-process a string fragment'; + arg = { + arg_type = 'char const *'; + arg_name = 'pzScan'; + arg_desc = 'points to character after the escape'; + }; + arg = { + arg_type = 'char *'; + arg_name = 'pRes'; + arg_desc = 'Where to put the result byte'; + }; + arg = { + arg_type = 'unsigned int'; + arg_name = 'nl_ch'; + arg_desc = 'replacement char if scanned char is \n'; + }; + ret-type = 'unsigned int'; + ret-desc = 'The number of bytes consumed processing the escaped character.'; + doc = +'This function converts "t" into "\\t" and all your other favorite +escapes, including numeric ones: hex and ocatal, too. +The returned result tells the caller how far to advance the +scan pointer (passed in). The default is to just pass through the +escaped character and advance the scan by one. + +Some applications need to keep an escaped newline, others need to +suppress it. This is accomplished by supplying a \'\\n\' replacement +character that is different from \\n, if need be. For example, use +0x7F and never emit a 0x7F.'; + err = '@code{NULL} is returned if the string is mal-formed.'; + srcfile = 'cook.c'; + linenum = '32'; +}; + + +#line 152 "tokenize.c" +export_func = { + name = 'ao_string_tokenize'; + what = 'tokenize an input string'; + arg = { + arg_type = 'char const *'; + arg_name = 'string'; + arg_desc = 'string to be tokenized'; + }; + ret_type = 'token_list_t *'; + ret_desc = 'pointer to a structure that lists each token'; + doc = +'This function will convert one input string into a list of strings. +The list of strings is derived by separating the input based on +white space separation. However, if the input contains either single +or double quote characters, then the text after that character up to +a matching quote will become the string in the list. + +The returned pointer should be deallocated with @code{free(3C)} when +are done using the data. The data are placed in a single block of +allocated memory. Do not deallocate individual token/strings. + +The structure pointed to will contain at least these two fields: +@table @samp +@item tkn_ct +The number of tokens found in the input string. +@item tok_list +An array of @code{tkn_ct + 1} pointers to substring tokens, with +the last pointer set to NULL. +@end table + +There are two types of quoted strings: single quoted (@code{\'}) and +double quoted (@code{"}). Singly quoted strings are fairly raw in that +escape characters (@code{\\\\}) are simply another character, except when +preceding the following characters: +@example +@code{\\\\} double backslashes reduce to one +@code{\'} incorporates the single quote into the string +@code{\\n} suppresses both the backslash and newline character +@end example + +Double quote strings are formed according to the rules of string +constants in ANSI-C programs.'; + example = +'@example +#include +int ix; +token_list_t * ptl = ao_string_tokenize(some_string) +for (ix = 0; ix < ptl->tkn_ct; ix++) +do_something_with_tkn(ptl->tkn_list[ix]); +free(ptl); +@end example +Note that everything is freed with the one call to @code{free(3C)}.'; + err = +'NULL is returned and @code{errno} will be set to indicate the problem: +@itemize @bullet +@item +@code{EINVAL} - There was an unterminated quoted string. +@item +@code{ENOENT} - The input string was empty. +@item +@code{ENOMEM} - There is not enough memory. +@end itemize'; + srcfile = 'tokenize.c'; + linenum = '152'; +}; + + +#line 43 "configfile.c" +export_func = { + name = 'configFileLoad'; + what = 'parse a configuration file'; + arg = { + arg_type = 'char const *'; + arg_name = 'fname'; + arg_desc = 'the file to load'; + }; + ret_type = 'const tOptionValue *'; + ret_desc = 'An allocated, compound value structure'; + doc = +'This routine will load a named configuration file and parse the +text as a hierarchically valued option. The option descriptor +created from an option definition file is not used via this interface. +The returned value is "named" with the input file name and is of +type "@code{OPARG_TYPE_HIERARCHY}". It may be used in calls to +@code{optionGetValue()}, @code{optionNextValue()} and +@code{optionUnloadNested()}.'; + err = +'If the file cannot be loaded or processed, @code{NULL} is returned and +@var{errno} is set. It may be set by a call to either @code{open(2)} +@code{mmap(2)} or other file system calls, or it may be: +@itemize @bullet +@item +@code{ENOENT} - the file was not found. +@item +@code{ENOMSG} - the file was empty. +@item +@code{EINVAL} - the file contents are invalid -- not properly formed. +@item +@code{ENOMEM} - not enough memory to allocate the needed structures. +@end itemize'; + srcfile = 'configfile.c'; + linenum = '43'; +}; + + +#line 811 "makeshell.c" +export_func = { + name = 'genshelloptUsage'; + private; + what = 'The usage function for the genshellopt generated program'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'opts'; + arg_desc = 'program options descriptor'; + }; + arg = { + arg_type = 'int'; + arg_name = 'exit_cd'; + arg_desc = 'usage text type to produce'; + }; + doc = +'This function is used to create the usage strings for the option +processing shell script code. Two child processes are spawned +each emitting the usage text in either the short (error exit) +style or the long style. The generated program will capture this +and create shell script variables containing the two types of text.'; + srcfile = 'makeshell.c'; + linenum = '811'; +}; + + +#line 53 "alias.c" +export_func = { + name = 'optionAlias'; + private; + what = 'relay an option to its alias'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'opts'; + arg_desc = 'program options descriptor'; + }; + arg = { + arg_type = 'tOptDesc *'; + arg_name = 'old_od'; + arg_desc = 'the descriptor for this arg'; + }; + arg = { + arg_type = 'unsigned int'; + arg_name = 'alias'; + arg_desc = 'the aliased-to option index'; + }; + ret-type = 'int'; + doc = +'Handle one option as if it had been specified as another. Exactly. +Returns "-1" if the aliased-to option has appeared too many times.'; + srcfile = 'alias.c'; + linenum = '53'; +}; + + +#line 35 "boolean.c" +export_func = { + name = 'optionBooleanVal'; + private; + what = 'Decipher a boolean value'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'opts'; + arg_desc = 'program options descriptor'; + }; + arg = { + arg_type = 'tOptDesc *'; + arg_name = 'od'; + arg_desc = 'the descriptor for this arg'; + }; + doc = +'Decipher a true or false value for a boolean valued option argument. +The value is true, unless it starts with \'n\' or \'f\' or "#f" or +it is an empty string or it is a number that evaluates to zero.'; + srcfile = 'boolean.c'; + linenum = '35'; +}; + + +#line 240 "enum.c" +export_func = { + name = 'optionEnumerationVal'; + what = 'Convert from a string to an enumeration value'; + private; + arg = { + arg_type = 'tOptions *'; + arg_name = 'pOpts'; + arg_desc = 'the program options descriptor'; + }; + arg = { + arg_type = 'tOptDesc *'; + arg_name = 'pOD'; + arg_desc = 'enumeration option description'; + }; + arg = { + arg_type = 'char const * const *'; + arg_name = 'paz_names'; + arg_desc = 'list of enumeration names'; + }; + arg = { + arg_type = 'unsigned int'; + arg_name = 'name_ct'; + arg_desc = 'number of names in list'; + }; + ret_type = 'uintptr_t'; + ret_desc = 'the enumeration value'; + doc = 'This converts the optArg.argString string from the option description +into the index corresponding to an entry in the name list. +This will match the generated enumeration value. +Full matches are always accepted. Partial matches are accepted +if there is only one partial match.'; + srcfile = 'enum.c'; + linenum = '240'; +}; + + +#line 142 "file.c" +export_func = { + name = 'optionFileCheck'; + private; + what = 'Decipher a boolean value'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'pOpts'; + arg_desc = 'program options descriptor'; + }; + arg = { + arg_type = 'tOptDesc *'; + arg_name = 'pOptDesc'; + arg_desc = 'the descriptor for this arg'; + }; + arg = { + arg_type = 'teOptFileType'; + arg_name = 'ftype'; + arg_desc = 'File handling type'; + }; + arg = { + arg_type = 'tuFileMode'; + arg_name = 'mode'; + arg_desc = 'file open mode (if needed)'; + }; + doc = +'Make sure the named file conforms with the file type mode. +The mode specifies if the file must exist, must not exist or may +(or may not) exist. The mode may also specify opening the'; + file = 'don\'t, open just the descriptor (fd), or open as a stream +(FILE * pointer).'; + srcfile = 'file.c'; + linenum = '142'; +}; + + +#line 1051 "configfile.c" +export_func = { + name = 'optionFileLoad'; + what = 'Load the locatable config files, in order'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'opts'; + arg_desc = 'program options descriptor'; + }; + arg = { + arg_type = 'char const *'; + arg_name = 'prog'; + arg_desc = 'program name'; + }; + ret_type = 'int'; + ret_desc = '0 -> SUCCESS, -1 -> FAILURE'; + doc = +'This function looks in all the specified directories for a configuration +file ("rc" file or "ini" file) and processes any found twice. The first +time through, they are processed in reverse order (last file first). At +that time, only "immediate action" configurables are processed. For +example, if the last named file specifies not processing any more +configuration files, then no more configuration files will be processed. +Such an option in the @strong{first} named directory will have no effect. + +Once the immediate action configurables have been handled, then the +directories are handled in normal, forward order. In that way, later +config files can override the settings of earlier config files. + +See the AutoOpts documentation for a thorough discussion of the +config file format. + +Configuration files not found or not decipherable are simply ignored.'; + err = 'Returns the value, "-1" if the program options descriptor +is out of date or indecipherable. Otherwise, the value "0" will +always be returned.'; + srcfile = 'configfile.c'; + linenum = '1051'; +}; + + +#line 175 "configfile.c" +export_func = { + name = 'optionFindNextValue'; + FIXME = 'the handling of \'pzName\' and \'pzVal\' is just wrong.'; + what = 'find a hierarcicaly valued option instance'; + arg = { + arg_type = 'const tOptDesc *'; + arg_name = 'odesc'; + arg_desc = 'an option with a nested arg type'; + }; + arg = { + arg_type = 'const tOptionValue *'; + arg_name = 'pPrevVal'; + arg_desc = 'the last entry'; + }; + arg = { + arg_type = 'char const *'; + arg_name = 'name'; + arg_desc = 'name of value to find'; + }; + arg = { + arg_type = 'char const *'; + arg_name = 'value'; + arg_desc = 'the matching value'; + }; + ret_type = 'const tOptionValue *'; + ret_desc = 'a compound value structure'; + doc = +'This routine will find the next entry in a nested value option or +configurable. It will search through the list and return the next entry +that matches the criteria.'; + err = +'The returned result is NULL and errno is set: +@itemize @bullet +@item +@code{EINVAL} - the @code{pOptValue} does not point to a valid +hierarchical option value. +@item +@code{ENOENT} - no entry matched the given name. +@end itemize'; + srcfile = 'configfile.c'; + linenum = '175'; +}; + + +#line 102 "configfile.c" +export_func = { + name = 'optionFindValue'; + what = 'find a hierarcicaly valued option instance'; + arg = { + arg_type = 'const tOptDesc *'; + arg_name = 'odesc'; + arg_desc = 'an option with a nested arg type'; + }; + arg = { + arg_type = 'char const *'; + arg_name = 'name'; + arg_desc = 'name of value to find'; + }; + arg = { + arg_type = 'char const *'; + arg_name = 'val'; + arg_desc = 'the matching value'; + }; + ret_type = 'const tOptionValue *'; + ret_desc = 'a compound value structure'; + doc = +'This routine will find an entry in a nested value option or configurable. +It will search through the list and return a matching entry.'; + err = +'The returned result is NULL and errno is set: +@itemize @bullet +@item +@code{EINVAL} - the @code{pOptValue} does not point to a valid +hierarchical option value. +@item +@code{ENOENT} - no entry matched the given name. +@end itemize'; + srcfile = 'configfile.c'; + linenum = '102'; +}; + + +#line 159 "restore.c" +export_func = { + name = 'optionFree'; + what = 'free allocated option processing memory'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'pOpts'; + arg_desc = 'program options descriptor'; + }; + doc = 'AutoOpts sometimes allocates memory and puts pointers to it in the +option state structures. This routine deallocates all such memory.'; + err = 'As long as memory has not been corrupted, +this routine is always successful.'; + srcfile = 'restore.c'; + linenum = '159'; +}; + + +#line 244 "configfile.c" +export_func = { + name = 'optionGetValue'; + what = 'get a specific value from a hierarcical list'; + arg = { + arg_type = 'const tOptionValue *'; + arg_name = 'pOptValue'; + arg_desc = 'a hierarchcal value'; + }; + arg = { + arg_type = 'char const *'; + arg_name = 'valueName'; + arg_desc = 'name of value to get'; + }; + ret_type = 'const tOptionValue *'; + ret_desc = 'a compound value structure'; + doc = +'This routine will find an entry in a nested value option or configurable. +If "valueName" is NULL, then the first entry is returned. Otherwise, +the first entry with a name that exactly matches the argument will be +returned. If there is no matching value, NULL is returned and errno is +set to ENOENT. If the provided option value is not a hierarchical value, +NULL is also returned and errno is set to EINVAL.'; + err = +'The returned result is NULL and errno is set: +@itemize @bullet +@item +@code{EINVAL} - the @code{pOptValue} does not point to a valid +hierarchical option value. +@item +@code{ENOENT} - no entry matched the given name. +@end itemize'; + srcfile = 'configfile.c'; + linenum = '244'; +}; + + +#line 217 "enum.c" +export_func = { + name = 'optionKeywordName'; + what = 'Convert between enumeration values and strings'; + private; + arg = { + arg_type = 'tOptDesc *'; + arg_name = 'pOD'; + arg_desc = 'enumeration option description'; + }; + arg = { + arg_type = 'unsigned int'; + arg_name = 'enum_val'; + arg_desc = 'the enumeration value to map'; + }; + ret_type = 'char const *'; + ret_desc = 'the enumeration name from const memory'; + doc = 'This converts an enumeration value into the matching string.'; + srcfile = 'enum.c'; + linenum = '217'; +}; + + +#line 533 "load.c" +export_func = { + name = 'optionLoadLine'; + what = 'process a string for an option name and value'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'opts'; + arg_desc = 'program options descriptor'; + }; + arg = { + arg_type = 'char const *'; + arg_name = 'line'; + arg_desc = 'NUL-terminated text'; + }; + doc = +'This is a client program callable routine for setting options from, for +example, the contents of a file that they read in. Only one option may +appear in the text. It will be treated as a normal (non-preset) option. + +When passed a pointer to the option struct and a string, it will find +the option named by the first token on the string and set the option +argument to the remainder of the string. The caller must NUL terminate +the string. The caller need not skip over any introductory hyphens. +Any embedded new lines will be included in the option +argument. If the input looks like one or more quoted strings, then the +input will be "cooked". The "cooking" is identical to the string +formation used in AutoGen definition files (@pxref{basic expression}), +except that you may not use backquotes.'; + err = 'Invalid options are silently ignored. Invalid option arguments +will cause a warning to print, but the function should return.'; + srcfile = 'load.c'; + linenum = '533'; +}; + + +#line 1104 "configfile.c" +export_func = { + name = 'optionLoadOpt'; + private; + what = 'Load an option rc/ini file'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'opts'; + arg_desc = 'program options descriptor'; + }; + arg = { + arg_type = 'tOptDesc *'; + arg_name = 'odesc'; + arg_desc = 'the descriptor for this arg'; + }; + doc = +'Processes the options found in the file named with +odesc->optArg.argString.'; + srcfile = 'configfile.c'; + linenum = '1104'; +}; + + +#line 73 "load.c" +export_func = { + name = 'optionMakePath'; + private; + what = 'translate and construct a path'; + arg = { + arg_type = 'char *'; + arg_name = 'p_buf'; + arg_desc = 'The result buffer'; + }; + arg = { + arg_type = 'int'; + arg_name = 'b_sz'; + arg_desc = 'The size of this buffer'; + }; + arg = { + arg_type = 'char const *'; + arg_name = 'fname'; + arg_desc = 'The input name'; + }; + arg = { + arg_type = 'char const *'; + arg_name = 'prg_path'; + arg_desc = 'The full path of the current program'; + }; + ret-type = 'bool'; + ret-desc = 'true if the name was handled, otherwise false. +If the name does not start with ``$\'\', then it is handled +simply by copying the input name to the output buffer and +resolving the name with either +@code{canonicalize_file_name(3GLIBC)} or @code{realpath(3C)}.'; + doc = +'This routine will copy the @code{pzName} input name into the +@code{pzBuf} output buffer, not exceeding @code{bufSize} bytes. If the +first character of the input name is a @code{\'$\'} character, then there +is special handling: +@* +@code{$$} is replaced with the directory name of the @code{pzProgPath}, +searching @code{$PATH} if necessary. +@* +@code{$@} is replaced with the AutoGen package data installation directory +(aka @code{pkgdatadir}). +@* +@code{$NAME} is replaced by the contents of the @code{NAME} environment +variable. If not found, the search fails. + +Please note: both @code{$$} and @code{$NAME} must be at the start of the +@code{pzName} string and must either be the entire string or be followed +by the @code{\'/\'} (backslash on windows) character.'; + err = '@code{false} is returned if: +@* +@bullet{} The input name exceeds @code{bufSize} bytes. +@* +@bullet{} @code{$$}, @code{$@@} or @code{$NAME} is not the full string +and the next character is not \'/\'. +@* +@bullet{} libopts was built without PKGDATADIR defined and @code{$@@} +was specified. +@* +@bullet{} @code{NAME} is not a known environment variable +@* +@bullet{} @code{canonicalize_file_name} or @code{realpath} return +errors (cannot resolve the resulting path).'; + srcfile = 'load.c'; + linenum = '73'; +}; + + +#line 483 "enum.c" +export_func = { + name = 'optionMemberList'; + what = 'Get the list of members of a bit mask set'; + arg = { + arg_type = 'tOptDesc *'; + arg_name = 'od'; + arg_desc = 'the set membership option description'; + }; + ret_type = 'char *'; + ret_desc = 'the names of the set bits'; + doc = 'This converts the OPT_VALUE_name mask value to a allocated string. +It is the caller\'s responsibility to free the string.'; + srcfile = 'enum.c'; + linenum = '483'; +}; + + +#line 782 "nested.c" +export_func = { + name = 'optionNestedVal'; + private; + what = 'parse a hierarchical option argument'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'opts'; + arg_desc = 'program options descriptor'; + }; + arg = { + arg_type = 'tOptDesc *'; + arg_name = 'od'; + arg_desc = 'the descriptor for this arg'; + }; + doc = +'Nested value was found on the command line'; + srcfile = 'nested.c'; + linenum = '782'; +}; + + +#line 303 "configfile.c" +export_func = { + name = 'optionNextValue'; + what = 'get the next value from a hierarchical list'; + arg = { + arg_type = 'const tOptionValue *'; + arg_name = 'pOptValue'; + arg_desc = 'a hierarchcal list value'; + }; + arg = { + arg_type = 'const tOptionValue *'; + arg_name = 'pOldValue'; + arg_desc = 'a value from this list'; + }; + ret_type = 'const tOptionValue *'; + ret_desc = 'a compound value structure'; + doc = +'This routine will return the next entry after the entry passed in. At the +end of the list, NULL will be returned. If the entry is not found on the +list, NULL will be returned and "@var{errno}" will be set to EINVAL. +The "@var{pOldValue}" must have been gotten from a prior call to this +routine or to "@code{opitonGetValue()}".'; + err = +'The returned result is NULL and errno is set: +@itemize @bullet +@item +@code{EINVAL} - the @code{pOptValue} does not point to a valid +hierarchical option value or @code{pOldValue} does not point to a +member of that option value. +@item +@code{ENOENT} - the supplied @code{pOldValue} pointed to the last entry. +@end itemize'; + srcfile = 'configfile.c'; + linenum = '303'; +}; + + +#line 96 "numeric.c" +export_func = { + name = 'optionNumericVal'; + private; + what = 'process an option with a numeric value.'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'opts'; + arg_desc = 'program options descriptor'; + }; + arg = { + arg_type = 'tOptDesc *'; + arg_name = 'od'; + arg_desc = 'the descriptor for this arg'; + }; + doc = +'Decipher a numeric value.'; + srcfile = 'numeric.c'; + linenum = '96'; +}; + + +#line 189 "usage.c" +export_func = { + name = 'optionOnlyUsage'; + what = 'Print usage text for just the options'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'pOpts'; + arg_desc = 'program options descriptor'; + }; + arg = { + arg_type = 'int'; + arg_name = 'ex_code'; + arg_desc = 'exit code for calling exit(3)'; + }; + doc = +'This routine will print only the usage for each option. +This function may be used when the emitted usage must incorporate +information not available to AutoOpts.'; + srcfile = 'usage.c'; + linenum = '189'; +}; + + +#line 97 "pgusage.c" +export_func = { + name = 'optionPagedUsage'; + private; + what = 'emit help text and pass through a pager program.'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'opts'; + arg_desc = 'program options descriptor'; + }; + arg = { + arg_type = 'tOptDesc *'; + arg_name = 'od'; + arg_desc = 'the descriptor for this arg'; + }; + doc = +'Run the usage output through a pager. +This is very handy if it is very long. +This is disabled on platforms without a working fork() function.'; + srcfile = 'pgusage.c'; + linenum = '97'; +}; + + +#line 67 "makeshell.c" +export_func = { + name = 'optionParseShell'; + private; + what = 'Decipher a boolean value'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'pOpts'; + arg_desc = 'program options descriptor'; + }; + doc = +'Emit a shell script that will parse the command line options.'; + srcfile = 'makeshell.c'; + linenum = '67'; +}; + + +#line 391 "usage.c" +export_func = { + name = 'optionPrintParagraphs'; + private; + what = 'Print a paragraph of usage text'; + arg = { + arg_type = 'char const *'; + arg_name = 'text'; + arg_desc = 'a block of text that has bee i18n-ed'; + }; + arg = { + arg_type = 'bool'; + arg_name = 'plain'; + arg_desc = 'false -> wrap text in fputs()'; + }; + arg = { + arg_type = 'FILE *'; + arg_name = 'fp'; + arg_desc = 'the stream file pointer for output'; + }; + doc = +'This procedure is called in two contexts: when a full or short usage text +has been provided for display, and when autogen is assembling a list of +translatable texts in the optmain.tlib template. In the former case, \\a +plain is set to \\a true, otherwise \\a false. + +Anything less than 256 characters in size is printed as a single unit. +Otherwise, paragraphs are detected. A paragraph break is defined as just +before a non-empty line preceded by two newlines or a line that starts +with at least one space character but fewer than 8 space characters. +Lines indented with tabs or more than 7 spaces are considered continuation +lines. + +If \'plain\' is true, we are emitting text for a user to see. So, if it is +true and NLS is not enabled, then just write the whole thing at once.'; + srcfile = 'usage.c'; + linenum = '391'; +}; + + +#line 184 "version.c" +export_func = { + name = 'optionPrintVersion'; + what = 'Print the program version'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'opts'; + arg_desc = 'program options descriptor'; + }; + arg = { + arg_type = 'tOptDesc *'; + arg_name = 'od'; + arg_desc = 'the descriptor for this arg'; + }; + doc = +'This routine will print the version to stdout.'; + srcfile = 'version.c'; + linenum = '184'; +}; + + +#line 199 "version.c" +export_func = { + name = 'optionPrintVersionAndReturn'; + what = 'Print the program version'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'opts'; + arg_desc = 'program options descriptor'; + }; + arg = { + arg_type = 'tOptDesc *'; + arg_name = 'od'; + arg_desc = 'the descriptor for this arg'; + }; + doc = +'This routine will print the version to stdout and return +instead of exiting. Please see the source for the +@code{print_ver} funtion for details on selecting how +verbose to be after this function returns.'; + srcfile = 'version.c'; + linenum = '199'; +}; + + +#line 292 "autoopts.c" +export_func = { + name = 'optionProcess'; + what = 'this is the main option processing routine'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'opts'; + arg_desc = 'program options descriptor'; + }; + arg = { + arg_type = 'int'; + arg_name = 'a_ct'; + arg_desc = 'program arg count'; + }; + arg = { + arg_type = 'char **'; + arg_name = 'a_v'; + arg_desc = 'program arg vector'; + }; + ret_type = 'int'; + ret_desc = 'the count of the arguments processed'; + doc = +'This is the main entry point for processing options. It is intended +that this procedure be called once at the beginning of the execution of +a program. Depending on options selected earlier, it is sometimes +necessary to stop and restart option processing, or to select completely +different sets of options. This can be done easily, but you generally +do not want to do this. + +The number of arguments processed always includes the program name. +If one of the arguments is "--", then it is counted and the processing +stops. If an error was encountered and errors are to be tolerated, then +the returned value is the index of the argument causing the error. +A hyphen by itself ("-") will also cause processing to stop and will +@emph{not} be counted among the processed arguments. A hyphen by itself +is treated as an operand. Encountering an operand stops option +processing.'; + err = 'Errors will cause diagnostics to be printed. @code{exit(3)} may +or may not be called. It depends upon whether or not the options +were generated with the "allow-errors" attribute, or if the +ERRSKIP_OPTERR or ERRSTOP_OPTERR macros were invoked.'; + srcfile = 'autoopts.c'; + linenum = '292'; +}; + + +#line 347 "putshell.c" +export_func = { + name = 'optionPutShell'; + what = 'write a portable shell script to parse options'; + private; + arg = { + arg_type = 'tOptions *'; + arg_name = 'pOpts'; + arg_desc = 'the program options descriptor'; + }; + doc = 'This routine will emit portable shell script text for parsing +the options described in the option definitions.'; + srcfile = 'putshell.c'; + linenum = '347'; +}; + + +#line 88 "putshell.c" +export_func = { + name = 'optionQuoteString'; + private; + what = 'Print a string as quoted text suitable for a C compiler.'; + arg = { + arg_type = 'char const *'; + arg_name = 'text'; + arg_desc = 'a block of text to quote'; + }; + arg = { + arg_type = 'char const *'; + arg_name = 'nl'; + arg_desc = 'line splice text'; + }; + ret_type = 'char const *'; + ret_desc = 'the allocated input string as a quoted string'; + doc = +'This is for internal use by autogen and autoopts. +It takes an input string and produces text the C compiler can process +to produce an exact copy of the original string. +The caller must deallocate the result. Standard C strings and +K&R strings are distinguished by the "nl" string.'; + srcfile = 'putshell.c'; + linenum = '88'; +}; + + +#line 62 "reset.c" +export_func = { + name = 'optionResetOpt'; + private; + what = 'Reset the value of an option'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'pOpts'; + arg_desc = 'program options descriptor'; + }; + arg = { + arg_type = 'tOptDesc *'; + arg_name = 'pOptDesc'; + arg_desc = 'the descriptor for this arg'; + }; + doc = +'This code will cause another option to be reset to its initial state. +For example, --reset=foo will cause the --foo option to be reset.'; + srcfile = 'reset.c'; + linenum = '62'; +}; + + +#line 116 "restore.c" +export_func = { + name = 'optionRestore'; + what = 'restore option state from memory copy'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'pOpts'; + arg_desc = 'program options descriptor'; + }; + doc = 'Copy back the option state from saved memory. +The allocated memory is left intact, so this routine can be +called repeatedly without having to call optionSaveState again. +If you are restoring a state that was saved before the first call +to optionProcess(3AO), then you may change the contents of the +argc/argv parameters to optionProcess.'; + err = 'If you have not called @code{optionSaveState} before, a diagnostic is +printed to @code{stderr} and exit is called.'; + srcfile = 'restore.c'; + linenum = '116'; +}; + + +#line 768 "save.c" +export_func = { + name = 'optionSaveFile'; + what = 'saves the option state to a file'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'opts'; + arg_desc = 'program options descriptor'; + }; + doc = +'This routine will save the state of option processing to a file. The name +of that file can be specified with the argument to the @code{--save-opts} +option, or by appending the @code{rcfile} attribute to the last +@code{homerc} attribute. If no @code{rcfile} attribute was specified, it +will default to @code{.@i{programname}rc}. If you wish to specify another +file, you should invoke the @code{SET_OPT_SAVE_OPTS(@i{filename})} macro. + +The recommend usage is as follows: +@example +optionProcess(&progOptions, argc, argv); +if (i_want_a_non_standard_place_for_this) +SET_OPT_SAVE_OPTS("myfilename"); +optionSaveFile(&progOptions); +@end example'; + err = +'If no @code{homerc} file was specified, this routine will silently return +and do nothing. If the output file cannot be created or updated, a message +will be printed to @code{stderr} and the routine will return.'; + srcfile = 'save.c'; + linenum = '768'; +}; + + +#line 73 "restore.c" +export_func = { + name = 'optionSaveState'; + what = 'saves the option state to memory'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'pOpts'; + arg_desc = 'program options descriptor'; + }; + doc = +'This routine will allocate enough memory to save the current option +processing state. If this routine has been called before, that memory +will be reused. You may only save one copy of the option state. This +routine may be called before optionProcess(3AO). If you do call it +before the first call to optionProcess, then you may also change the +contents of argc/argv after you call optionRestore(3AO) + +In fact, more strongly put: it is safest to only use this function +before having processed any options. In particular, the saving and +restoring of stacked string arguments and hierarchical values is +disabled. The values are not saved.'; + err = 'If it fails to allocate the memory, +it will print a message to stderr and exit. +Otherwise, it will always succeed.'; + srcfile = 'restore.c'; + linenum = '73'; +}; + + +#line 505 "enum.c" +export_func = { + name = 'optionSetMembers'; + what = 'Convert between bit flag values and strings'; + private; + arg = { + arg_type = 'tOptions *'; + arg_name = 'opts'; + arg_desc = 'the program options descriptor'; + }; + arg = { + arg_type = 'tOptDesc *'; + arg_name = 'od'; + arg_desc = 'the set membership option description'; + }; + arg = { + arg_type = 'char const * const *'; + arg_name = 'nm_list'; + arg_desc = 'list of enumeration names'; + }; + arg = { + arg_type = 'unsigned int'; + arg_name = 'nm_ct'; + arg_desc = 'number of names in list'; + }; + doc = 'This converts the optArg.argString string from the option description +into the index corresponding to an entry in the name list. +This will match the generated enumeration value. +Full matches are always accepted. Partial matches are accepted +if there is only one partial match.'; + srcfile = 'enum.c'; + linenum = '505'; +}; + + +#line 32 "numeric.c" +export_func = { + name = 'optionShowRange'; + private; + what = 'Show info about range constraints'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'pOpts'; + arg_desc = 'program options descriptor'; + }; + arg = { + arg_type = 'tOptDesc *'; + arg_name = 'pOptDesc'; + arg_desc = 'the descriptor for this arg'; + }; + arg = { + arg_type = 'void *'; + arg_name = 'rng_table'; + arg_desc = 'the value range tables'; + }; + arg = { + arg_type = 'int'; + arg_name = 'rng_count'; + arg_desc = 'the number of entries'; + }; + doc = +'Show information about a numeric option with range constraints.'; + srcfile = 'numeric.c'; + linenum = '32'; +}; + + +#line 223 "stack.c" +export_func = { + name = 'optionStackArg'; + private; + what = 'put option args on a stack'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'opts'; + arg_desc = 'program options descriptor'; + }; + arg = { + arg_type = 'tOptDesc *'; + arg_name = 'od'; + arg_desc = 'the descriptor for this arg'; + }; + doc = +'Keep an entry-ordered list of option arguments.'; + srcfile = 'stack.c'; + linenum = '223'; +}; + + +#line 63 "time.c" +export_func = { + name = 'optionTimeDate'; + private; + what = 'process an option with a time and date.'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'opts'; + arg_desc = 'program options descriptor'; + }; + arg = { + arg_type = 'tOptDesc *'; + arg_name = 'od'; + arg_desc = 'the descriptor for this arg'; + }; + doc = +'Decipher a time and date value.'; + srcfile = 'time.c'; + linenum = '63'; +}; + + +#line 30 "time.c" +export_func = { + name = 'optionTimeVal'; + private; + what = 'process an option with a time duration.'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'opts'; + arg_desc = 'program options descriptor'; + }; + arg = { + arg_type = 'tOptDesc *'; + arg_name = 'od'; + arg_desc = 'the descriptor for this arg'; + }; + doc = +'Decipher a time duration value.'; + srcfile = 'time.c'; + linenum = '30'; +}; + + +#line 615 "nested.c" +export_func = { + name = 'optionUnloadNested'; + what = 'Deallocate the memory for a nested value'; + arg = { + arg_type = 'tOptionValue const *'; + arg_name = 'pOptVal'; + arg_desc = 'the hierarchical value'; + }; + doc = +'A nested value needs to be deallocated. The pointer passed in should +have been gotten from a call to @code{configFileLoad()} (See +@pxref{libopts-configFileLoad}).'; + srcfile = 'nested.c'; + linenum = '615'; +}; + + +#line 37 "stack.c" +export_func = { + name = 'optionUnstackArg'; + private; + what = 'Remove option args from a stack'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'opts'; + arg_desc = 'program options descriptor'; + }; + arg = { + arg_type = 'tOptDesc *'; + arg_name = 'od'; + arg_desc = 'the descriptor for this arg'; + }; + doc = +'Invoked for options that are equivalenced to stacked options.'; + srcfile = 'stack.c'; + linenum = '37'; +}; + + +#line 501 "usage.c" +export_func = { + name = 'optionUsage'; + private; + what = 'Print usage text'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'opts'; + arg_desc = 'program options descriptor'; + }; + arg = { + arg_type = 'int'; + arg_name = 'exitCode'; + arg_desc = 'exit code for calling exit(3)'; + }; + doc = +'This routine will print usage in both GNU-standard and AutoOpts-expanded +formats. The descriptor specifies the default, but AUTOOPTS_USAGE will +over-ride this, providing the value of it is set to either "gnu" or +"autoopts". This routine will @strong{not} return. + +If "exitCode" is "AO_EXIT_REQ_USAGE" (normally 64), then output will to +to stdout and the actual exit code will be "EXIT_SUCCESS".'; + srcfile = 'usage.c'; + linenum = '501'; +}; + + +#line 273 "find.c" +export_func = { + name = 'optionVendorOption'; + private; + what = 'Process a vendor option'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'pOpts'; + arg_desc = 'program options descriptor'; + }; + arg = { + arg_type = 'tOptDesc *'; + arg_name = 'pOptDesc'; + arg_desc = 'the descriptor for this arg'; + }; + doc = +'For POSIX specified utilities, the options are constrained to the options, +@xref{config attributes, Program Configuration}. AutoOpts clients should +never specify this directly. It gets referenced when the option +definitions contain a "vendor-opt" attribute.'; + srcfile = 'find.c'; + linenum = '273'; +}; + + +#line 32 "version.c" +export_func = { + name = 'optionVersion'; + what = 'return the compiled AutoOpts version number'; + ret_type = 'char const *'; + ret_desc = 'the version string in constant memory'; + doc = +'Returns the full version string compiled into the library. +The returned string cannot be modified.'; + srcfile = 'version.c'; + linenum = '32'; +}; + + +#line 217 "version.c" +export_func = { + name = 'optionVersionStderr'; + private; + what = 'Print the program version to stderr'; + arg = { + arg_type = 'tOptions *'; + arg_name = 'opts'; + arg_desc = 'program options descriptor'; + }; + arg = { + arg_type = 'tOptDesc *'; + arg_name = 'od'; + arg_desc = 'the descriptor for this arg'; + }; + doc = +'This routine will print the version to stderr.'; + srcfile = 'version.c'; + linenum = '217'; +}; + + +#line 225 "streqvcmp.c" +export_func = { + name = 'strequate'; + what = 'map a list of characters to the same value'; + arg = { + arg_type = 'char const *'; + arg_name = 'ch_list'; + arg_desc = 'characters to equivalence'; + }; + doc = +'Each character in the input string get mapped to the first character +in the string. +This function name is mapped to option_strequate so as to not conflict +with the POSIX name space.'; + err = 'none.'; + srcfile = 'streqvcmp.c'; + linenum = '225'; +}; + + +#line 128 "streqvcmp.c" +export_func = { + name = 'streqvcmp'; + what = 'compare two strings with an equivalence mapping'; + arg = { + arg_type = 'char const *'; + arg_name = 'str1'; + arg_desc = 'first string'; + }; + arg = { + arg_type = 'char const *'; + arg_name = 'str2'; + arg_desc = 'second string'; + }; + ret_type = 'int'; + ret_desc = 'the difference between two differing characters'; + doc = +'Using a character mapping, two strings are compared for "equivalence". +Each input character is mapped to a comparison character and the +mapped-to characters are compared for the two NUL terminated input strings. +This function name is mapped to option_streqvcmp so as to not conflict +with the POSIX name space.'; + err = 'none checked. Caller responsible for seg faults.'; + srcfile = 'streqvcmp.c'; + linenum = '128'; +}; + + +#line 172 "streqvcmp.c" +export_func = { + name = 'streqvmap'; + what = 'Set the character mappings for the streqv functions'; + arg = { + arg_type = 'char'; + arg_name = 'from'; + arg_desc = 'Input character'; + }; + arg = { + arg_type = 'char'; + arg_name = 'to'; + arg_desc = 'Mapped-to character'; + }; + arg = { + arg_type = 'int'; + arg_name = 'ct'; + arg_desc = 'compare length'; + }; + doc = +'Set the character mapping. If the count (@code{ct}) is set to zero, then +the map is cleared by setting all entries in the map to their index +value. Otherwise, the "@code{From}" character is mapped to the "@code{To}" +character. If @code{ct} is greater than 1, then @code{From} and @code{To} +are incremented and the process repeated until @code{ct} entries have been +set. For example, +@example +streqvmap(\'a\', \'A\', 26); +@end example +@noindent +will alter the mapping so that all English lower case letters +will map to upper case. + +This function name is mapped to option_streqvmap so as to not conflict +with the POSIX name space.'; + err = 'none.'; + srcfile = 'streqvcmp.c'; + linenum = '172'; +}; + + +#line 80 "streqvcmp.c" +export_func = { + name = 'strneqvcmp'; + what = 'compare two strings with an equivalence mapping'; + arg = { + arg_type = 'char const *'; + arg_name = 'str1'; + arg_desc = 'first string'; + }; + arg = { + arg_type = 'char const *'; + arg_name = 'str2'; + arg_desc = 'second string'; + }; + arg = { + arg_type = 'int'; + arg_name = 'ct'; + arg_desc = 'compare length'; + }; + ret_type = 'int'; + ret_desc = 'the difference between two differing characters'; + doc = +'Using a character mapping, two strings are compared for "equivalence". +Each input character is mapped to a comparison character and the +mapped-to characters are compared for the two NUL terminated input strings. +The comparison is limited to @code{ct} bytes. +This function name is mapped to option_strneqvcmp so as to not conflict +with the POSIX name space.'; + err = 'none checked. Caller responsible for seg faults.'; + srcfile = 'streqvcmp.c'; + linenum = '80'; +}; + + +#line 251 "streqvcmp.c" +export_func = { + name = 'strtransform'; + what = 'convert a string into its mapped-to value'; + arg = { + arg_type = 'char *'; + arg_name = 'dest'; + arg_desc = 'output string'; + }; + arg = { + arg_type = 'char const *'; + arg_name = 'src'; + arg_desc = 'input string'; + }; + doc = +'Each character in the input string is mapped and the mapped-to +character is put into the output. +This function name is mapped to option_strtransform so as to not conflict +with the POSIX name space. + +The source and destination may be the same.'; + err = 'none.'; + srcfile = 'streqvcmp.c'; + linenum = '251'; +}; + + +#line 256 "text_mmap.c" +export_func = { + name = 'text_mmap'; + private; + what = 'map a text file with terminating NUL'; + arg = { + arg_type = 'char const *'; + arg_name = 'pzFile'; + arg_desc = 'name of the file to map'; + }; + arg = { + arg_type = 'int'; + arg_name = 'prot'; + arg_desc = 'mmap protections (see mmap(2))'; + }; + arg = { + arg_type = 'int'; + arg_name = 'flags'; + arg_desc = 'mmap flags (see mmap(2))'; + }; + arg = { + arg_type = 'tmap_info_t *'; + arg_name = 'mapinfo'; + arg_desc = 'returned info about the mapping'; + }; + ret-type = 'void *'; + ret-desc = 'The mmaped data address'; + doc = +'This routine will mmap a file into memory ensuring that there is at least +one @file{NUL} character following the file data. It will return the +address where the file contents have been mapped into memory. If there is a +problem, then it will return @code{MAP_FAILED} and set @code{errno} +appropriately. + +The named file does not exist, @code{stat(2)} will set @code{errno} as it +will. If the file is not a regular file, @code{errno} will be +@code{EINVAL}. At that point, @code{open(2)} is attempted with the access +bits set appropriately for the requested @code{mmap(2)} protections and flag +bits. On failure, @code{errno} will be set according to the documentation +for @code{open(2)}. If @code{mmap(2)} fails, @code{errno} will be set as +that routine sets it. If @code{text_mmap} works to this point, a valid +address will be returned, but there may still be ``issues\'\'. + +If the file size is not an even multiple of the system page size, then +@code{text_map} will return at this point and @code{errno} will be zero. +Otherwise, an anonymous map is attempted. If not available, then an attempt +is made to @code{mmap(2)} @file{/dev/zero}. If any of these fail, the +address of the file\'s data is returned, bug @code{no} @file{NUL} characters +are mapped after the end of the data.'; + see = 'mmap(2), open(2), stat(2)'; + err = 'Any error code issued by mmap(2), open(2), stat(2) is possible. +Additionally, if the specified file is not a regular file, then +errno will be set to @code{EINVAL}.'; + example = +'#include +tmap_info_t mi; +int no_nul; +void * data = text_mmap("file", PROT_WRITE, MAP_PRIVATE, &mi); +if (data == MAP_FAILED) return; +no_nul = (mi.txt_size == mi.txt_full_size); +<< use the data >> +text_munmap(&mi);'; + srcfile = 'text_mmap.c'; + linenum = '256'; +}; + + +#line 329 "text_mmap.c" +export_func = { + name = 'text_munmap'; + private; + what = 'unmap the data mapped in by text_mmap'; + arg = { + arg_type = 'tmap_info_t *'; + arg_name = 'mapinfo'; + arg_desc = 'info about the mapping'; + }; + ret-type = 'int'; + ret-desc = '-1 or 0. @code{errno} will have the error code.'; + doc = +'This routine will unmap the data mapped in with @code{text_mmap} and close +the associated file descriptors opened by that function.'; + see = 'munmap(2), close(2)'; + err = 'Any error code issued by munmap(2) or close(2) is possible.'; + srcfile = 'text_mmap.c'; + linenum = '329'; +}; +vers-curr = "172033"; +vers-min = "102400"; +vers-min-str = "25:0:0"; +vers-sovers = "42:1:17"; +display-ver = "42.1"; +library = opts; + +/* + * THIS FILE IS DISTRIBUTED + * + * This file is used to construct options.h + doc files. Because it is + * such a nuisance to get the build ordering correct, we distribute + * this. It should be constructed after all binaries are built. + */ diff --git a/autoopts/genshell.c b/autoopts/genshell.c new file mode 100644 index 0000000..05182a6 --- /dev/null +++ b/autoopts/genshell.c @@ -0,0 +1,848 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * DO NOT EDIT THIS FILE (genshell.c) + * + * It has been AutoGen-ed + * From the definitions genshell.def + * and the template file options + * + * Generated from AutoOpts 42:1:17 templates. + * + * AutoOpts is a copyrighted work. This source file is not encumbered + * by AutoOpts licensing, but is provided under the licensing terms chosen + * by the genshellopt author or copyright holder. AutoOpts is + * licensed under the terms of the LGPL. The redistributable library + * (``libopts'') is licensed under the terms of either the LGPL or, at the + * users discretion, the BSD license. See the AutoOpts and/or libopts sources + * for details. + * + * The genshellopt program is copyrighted and licensed + * under the following terms: + * + * Copyright (C) 1999-2018 Bruce Korb, all rights reserved. + * This is free software. It is licensed for use, modification and + * redistribution under the terms of the GNU Lesser General Public License, + * version 2 or later + * + * The genshellopt 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, see + * + */ + +#ifndef __doxygen__ +#define OPTION_CODE_COMPILE 1 +#include "genshell.h" +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif +extern FILE * option_usage_fp; +#define zCopyright (genshellopt_opt_strs+0) +#define zLicenseDescrip (genshellopt_opt_strs+285) + +extern tUsageProc genshelloptUsage; + +#ifndef NULL +# define NULL 0 +#endif + +/** + * static const strings for genshellopt options + */ +static char const genshellopt_opt_strs[1769] = +/* 0 */ "genshellopt 1\n" + "Copyright (C) 1999-2018 Bruce Korb, all rights reserved.\n" + "This is free software. It is licensed for use, modification and\n" + "redistribution under the terms of the GNU Lesser General Public License,\n" + "version 2 or later \n\0" +/* 285 */ "The genshellopt library is free software; you can redistribute it and/or\n" + "modify it under the terms of the GNU Library General Public License as\n" + "published by the Free Software Foundation; either version 2 of the License,\n" + "or (at your option) any later version.\n\n" + "This library is distributed in the hope that it will be useful, but WITHOUT\n" + "ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n" + "FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public\n" + "License for more details.\n\n" + "You should have received a copy of the GNU Library General Public License\n" + "along with this library; if not, see\n" + "\n\0" +/* 957 */ "Output Script File\0" +/* 976 */ "SCRIPT\0" +/* 983 */ "script\0" +/* 990 */ "Shell name (follows \"#!\" magic)\0" +/* 1022 */ "SHELL\0" +/* 1028 */ "no-shell\0" +/* 1037 */ "no\0" +/* 1040 */ "display extended usage information and exit\0" +/* 1084 */ "help\0" +/* 1089 */ "extended usage information passed thru pager\0" +/* 1134 */ "more-help\0" +/* 1144 */ "output version information and exit\0" +/* 1180 */ "version\0" +/* 1188 */ "GENSHELLOPT\0" +/* 1200 */ "genshellopt - Generate Shell Option Processing Script - Ver. 1\n" + "Usage: %s [ - [] | --[{=| }] ]...\n\0" +/* 1321 */ "autogen-users@lists.sourceforge.net\0" +/* 1357 */ "Note that 'shell' is only useful if the output file does not already exist.\n" + "If it does, then the shell name and optional first argument will be\n" + "extracted from the script file.\n\0" +/* 1534 */ "If the script file already exists and contains Automated Option Processing\n" + "text, the second line of the file through the ending tag will be replaced\n" + "by the newly generated text. The first '#!' line will be regenerated.\n\0" +/* 1755 */ "genshellopt 1"; + +/** + * script option description: + */ +/** Descriptive text for the script option */ +#define SCRIPT_DESC (genshellopt_opt_strs+957) +/** Upper-cased name for the script option */ +#define SCRIPT_NAME (genshellopt_opt_strs+976) +/** Name string for the script option */ +#define SCRIPT_name (genshellopt_opt_strs+983) +/** Compiled in flag settings for the script option */ +#define SCRIPT_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/** + * shell option description: + */ +/** Descriptive text for the shell option */ +#define SHELL_DESC (genshellopt_opt_strs+990) +/** Upper-cased name for the shell option */ +#define SHELL_NAME (genshellopt_opt_strs+1022) +/** disablement name for the shell option */ +#define NOT_SHELL_name (genshellopt_opt_strs+1028) +/** disablement prefix for the shell option */ +#define NOT_SHELL_PFX (genshellopt_opt_strs+1037) +/** Name string for the shell option */ +#define SHELL_name (NOT_SHELL_name + 3) +/** Compiled in flag settings for the shell option */ +#define SHELL_FLAGS (OPTST_INITENABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/* + * Help/More_Help/Version option descriptions: + */ +#define HELP_DESC (genshellopt_opt_strs+1040) +#define HELP_name (genshellopt_opt_strs+1084) +#ifdef HAVE_WORKING_FORK +#define MORE_HELP_DESC (genshellopt_opt_strs+1089) +#define MORE_HELP_name (genshellopt_opt_strs+1134) +#define MORE_HELP_FLAGS (OPTST_IMM | OPTST_NO_INIT) +#else +#define MORE_HELP_DESC HELP_DESC +#define MORE_HELP_name HELP_name +#define MORE_HELP_FLAGS (OPTST_OMITTED | OPTST_NO_INIT) +#endif +#ifdef NO_OPTIONAL_OPT_ARGS +# define VER_FLAGS (OPTST_IMM | OPTST_NO_INIT) +#else +# define VER_FLAGS (OPTST_SET_ARGTYPE(OPARG_TYPE_STRING) | \ + OPTST_ARG_OPTIONAL | OPTST_IMM | OPTST_NO_INIT) +#endif +#define VER_DESC (genshellopt_opt_strs+1144) +#define VER_name (genshellopt_opt_strs+1180) +/** + * Declare option callback procedures + */ +extern tOptProc + optionBooleanVal, optionNestedVal, optionNumericVal, + optionPagedUsage, optionPrintVersion, optionResetOpt, + optionStackArg, optionTimeDate, optionTimeVal, + optionUnstackArg, optionVendorOption; +static tOptProc + doUsageOpt; +#define VER_PROC optionPrintVersion + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Define the genshellopt Option Descriptions. + * This is an array of GENSHELL_OPTION_CT entries, one for each + * option that the genshellopt program responds to. + */ +static tOptDesc optDesc[GENSHELL_OPTION_CT] = { + { /* entry idx, value */ 0, VALUE_GENSHELL_OPT_SCRIPT, + /* equiv idx, value */ 0, VALUE_GENSHELL_OPT_SCRIPT, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ SCRIPT_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --script */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ SCRIPT_DESC, SCRIPT_NAME, SCRIPT_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 1, VALUE_GENSHELL_OPT_SHELL, + /* equiv idx, value */ 1, VALUE_GENSHELL_OPT_SHELL, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ SHELL_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --shell */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ SHELL_DESC, SHELL_NAME, SHELL_name, + /* disablement strs */ NOT_SHELL_name, NOT_SHELL_PFX }, + + { /* entry idx, value */ INDEX_GENSHELL_OPT_VERSION, VALUE_GENSHELL_OPT_VERSION, + /* equiv idx value */ NO_EQUIVALENT, VALUE_GENSHELL_OPT_VERSION, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ VER_FLAGS, AOUSE_VERSION, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ VER_PROC, + /* desc, NAME, name */ VER_DESC, NULL, VER_name, + /* disablement strs */ NULL, NULL }, + + + + { /* entry idx, value */ INDEX_GENSHELL_OPT_HELP, VALUE_GENSHELL_OPT_HELP, + /* equiv idx value */ NO_EQUIVALENT, VALUE_GENSHELL_OPT_HELP, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ OPTST_IMM | OPTST_NO_INIT, AOUSE_HELP, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ doUsageOpt, + /* desc, NAME, name */ HELP_DESC, NULL, HELP_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ INDEX_GENSHELL_OPT_MORE_HELP, VALUE_GENSHELL_OPT_MORE_HELP, + /* equiv idx value */ NO_EQUIVALENT, VALUE_GENSHELL_OPT_MORE_HELP, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ MORE_HELP_FLAGS, AOUSE_MORE_HELP, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ optionPagedUsage, + /* desc, NAME, name */ MORE_HELP_DESC, NULL, MORE_HELP_name, + /* disablement strs */ NULL, NULL } +}; + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** Reference to the upper cased version of genshellopt. */ +#define zPROGNAME (genshellopt_opt_strs+1188) +/** Reference to the title line for genshellopt usage. */ +#define zUsageTitle (genshellopt_opt_strs+1200) +/** There is no genshellopt configuration file. */ +#define zRcName NULL +/** There are no directories to search for genshellopt config files. */ +#define apzHomeList NULL +/** The genshellopt program bug email address. */ +#define zBugsAddr (genshellopt_opt_strs+1321) +/** Clarification/explanation of what genshellopt does. */ +#define zExplain (genshellopt_opt_strs+1357) +/** Extra detail explaining what genshellopt does. */ +#define zDetail (genshellopt_opt_strs+1534) +/** The full version string for genshellopt. */ +#define zFullVersion (genshellopt_opt_strs+1755) +/* extracted from optcode.tlib near line 342 */ + +#if defined(ENABLE_NLS) +# define OPTPROC_BASE OPTPROC_TRANSLATE + static tOptionXlateProc translate_option_strings; +#else +# define OPTPROC_BASE OPTPROC_NONE +# define translate_option_strings NULL +#endif /* ENABLE_NLS */ + +#define genshellopt_full_usage (NULL) +#define genshellopt_short_usage (NULL) + +#endif /* not defined __doxygen__ */ + +/* + * Create the static procedure(s) declared above. + */ +/** + * The callout function that invokes the genshelloptUsage function. + * + * @param[in] opts the AutoOpts option description structure + * @param[in] od the descriptor for the "help" (usage) option. + * @noreturn + */ +static void +doUsageOpt(tOptions * opts, tOptDesc * od) +{ + int ex_code; + ex_code = GENSHELLOPT_EXIT_SUCCESS; + genshelloptUsage(&genshelloptOptions, ex_code); + /* NOTREACHED */ + exit(GENSHELLOPT_EXIT_FAILURE); + (void)opts; + (void)od; +} +/* extracted from optmain.tlib near line 1250 */ + +/** + * The directory containing the data associated with genshellopt. + */ +#ifndef PKGDATADIR +# define PKGDATADIR "" +#endif + +/** + * Information about the person or institution that packaged genshellopt + * for the current distribution. + */ +#ifndef WITH_PACKAGER +# define genshellopt_packager_info NULL +#else +/** Packager information for genshellopt. */ +static char const genshellopt_packager_info[] = + "Packaged by " WITH_PACKAGER + +# ifdef WITH_PACKAGER_VERSION + " ("WITH_PACKAGER_VERSION")" +# endif + +# ifdef WITH_PACKAGER_BUG_REPORTS + "\nReport genshellopt bugs to " WITH_PACKAGER_BUG_REPORTS +# endif + "\n"; +#endif +#ifndef __doxygen__ + +#endif /* __doxygen__ */ +/** + * The option definitions for genshellopt. The one structure that + * binds them all. + */ +tOptions genshelloptOptions = { + OPTIONS_STRUCT_VERSION, + 0, NULL, /* original argc + argv */ + ( OPTPROC_BASE + + OPTPROC_ERRSTOP + + OPTPROC_SHORTOPT + + OPTPROC_LONGOPT + + OPTPROC_NO_REQ_OPT + + OPTPROC_NEGATIONS + + OPTPROC_NO_ARGS ), + 0, NULL, /* current option index, current option */ + NULL, NULL, zPROGNAME, + zRcName, zCopyright, zLicenseDescrip, + zFullVersion, apzHomeList, zUsageTitle, + zExplain, zDetail, optDesc, + zBugsAddr, /* address to send bugs to */ + NULL, NULL, /* extensions/saved state */ + genshelloptUsage, /* usage procedure */ + translate_option_strings, /* translation procedure */ + /* + * Indexes to special options + */ + { INDEX_GENSHELL_OPT_MORE_HELP, /* more-help option index */ + NO_EQUIVALENT, /* save option index */ + NO_EQUIVALENT, /* '-#' option index */ + NO_EQUIVALENT /* index of default opt */ + }, + 5 /* full option count */, 2 /* user option count */, + genshellopt_full_usage, genshellopt_short_usage, + NULL, NULL, + PKGDATADIR, genshellopt_packager_info +}; + +#if ENABLE_NLS +/** + * This code is designed to translate translatable option text for the + * genshellopt program. These translations happen upon entry + * to optionProcess(). + */ +#include +#include +#include +#include +#ifdef HAVE_DCGETTEXT +# include +#endif +#include + +static char * AO_gettext(char const * pz); +static void coerce_it(void ** s); + +/** + * AutoGen specific wrapper function for gettext. It relies on the macro _() + * to convert from English to the target language, then strdup-duplicates the + * result string. It tries the "libopts" domain first, then whatever has been + * set via the \a textdomain(3) call. + * + * @param[in] pz the input text used as a lookup key. + * @returns the translated text (if there is one), + * or the original text (if not). + */ +static char * +AO_gettext(char const * pz) +{ + char * res; + if (pz == NULL) + return NULL; +#ifdef HAVE_DCGETTEXT + /* + * While processing the option_xlateable_txt data, try to use the + * "libopts" domain. Once we switch to the option descriptor data, + * do *not* use that domain. + */ + if (option_xlateable_txt.field_ct != 0) { + res = dgettext("libopts", pz); + if (res == pz) + res = (char *)VOIDP(_(pz)); + } else + res = (char *)VOIDP(_(pz)); +#else + res = (char *)VOIDP(_(pz)); +#endif + if (res == pz) + return res; + res = strdup(res); + if (res == NULL) { + fputs(_("No memory for duping translated strings\n"), stderr); + exit(GENSHELLOPT_EXIT_FAILURE); + } + return res; +} + +/** + * All the pointers we use are marked "* const", but they are stored in + * writable memory. Coerce the mutability and set the pointer. + */ +static void coerce_it(void ** s) { *s = AO_gettext(*s); +} + +/** + * Translate all the translatable strings in the genshelloptOptions + * structure defined above. This is done only once. + */ +static void +translate_option_strings(void) +{ + tOptions * const opts = &genshelloptOptions; + + /* + * Guard against re-translation. It won't work. The strings will have + * been changed by the first pass through this code. One shot only. + */ + if (option_xlateable_txt.field_ct != 0) { + /* + * Do the translations. The first pointer follows the field count + * field. The field count field is the size of a pointer. + */ + char ** ppz = (char**)VOIDP(&(option_xlateable_txt)); + int ix = option_xlateable_txt.field_ct; + + do { + ppz++; /* skip over field_ct */ + *ppz = AO_gettext(*ppz); + } while (--ix > 0); + /* prevent re-translation and disable "libopts" domain lookup */ + option_xlateable_txt.field_ct = 0; + + coerce_it(VOIDP(&(opts->pzCopyright))); + coerce_it(VOIDP(&(opts->pzCopyNotice))); + coerce_it(VOIDP(&(opts->pzFullVersion))); + coerce_it(VOIDP(&(opts->pzUsageTitle))); + coerce_it(VOIDP(&(opts->pzExplain))); + coerce_it(VOIDP(&(opts->pzDetail))); + { + tOptDesc * od = opts->pOptDesc; + for (ix = opts->optCt; ix > 0; ix--, od++) + coerce_it(VOIDP(&(od->pzText))); + } + } +} +#endif /* ENABLE_NLS */ + +#ifdef DO_NOT_COMPILE_THIS_CODE_IT_IS_FOR_GETTEXT +/** I18N function strictly for xgettext. Do not compile. */ +static void bogus_function(void) { + /* TRANSLATORS: + + The following dummy function was crated solely so that xgettext can + extract the correct strings. These strings are actually referenced + by a field name in the genshelloptOptions structure noted in the + comments below. The literal text is defined in genshellopt_opt_strs. + + NOTE: the strings below are segmented with respect to the source string + genshellopt_opt_strs. The strings above are handed off for translation + at run time a paragraph at a time. Consequently, they are presented here + for translation a paragraph at a time. + + ALSO: often the description for an option will reference another option + by name. These are set off with apostrophe quotes (I hope). Do not + translate option names. + */ + /* referenced via genshelloptOptions.pzCopyright */ + puts(_("genshellopt 1\n\ +Copyright (C) 1999-2018 Bruce Korb, all rights reserved.\n\ +This is free software. It is licensed for use, modification and\n\ +redistribution under the terms of the GNU Lesser General Public License,\n\ +version 2 or later \n")); + + /* referenced via genshelloptOptions.pzCopyNotice */ + puts(_("The genshellopt library is free software; you can redistribute it and/or\n\ +modify it under the terms of the GNU Library General Public License as\n\ +published by the Free Software Foundation; either version 2 of the License,\n\ +or (at your option) any later version.\n\n")); + puts(_("This library is distributed in the hope that it will be useful, but WITHOUT\n\ +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n\ +FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public\n\ +License for more details.\n\n")); + puts(_("You should have received a copy of the GNU Library General Public License\n\ +along with this library; if not, see\n\ +\n")); + + /* referenced via genshelloptOptions.pOptDesc->pzText */ + puts(_("Output Script File")); + + /* referenced via genshelloptOptions.pOptDesc->pzText */ + puts(_("Shell name (follows \"#!\" magic)")); + + /* referenced via genshelloptOptions.pOptDesc->pzText */ + puts(_("display extended usage information and exit")); + + /* referenced via genshelloptOptions.pOptDesc->pzText */ + puts(_("extended usage information passed thru pager")); + + /* referenced via genshelloptOptions.pOptDesc->pzText */ + puts(_("output version information and exit")); + + /* referenced via genshelloptOptions.pzUsageTitle */ + puts(_("genshellopt - Generate Shell Option Processing Script - Ver. 1\n\ +Usage: %s [ - [] | --[{=| }] ]...\n")); + + /* referenced via genshelloptOptions.pzExplain */ + puts(_("Note that 'shell' is only useful if the output file does not already exist.\n\ +If it does, then the shell name and optional first argument will be\n\ +extracted from the script file.\n")); + + /* referenced via genshelloptOptions.pzDetail */ + puts(_("If the script file already exists and contains Automated Option Processing\n\ +text, the second line of the file through the ending tag will be replaced\n\ +by the newly generated text. The first '#!' line will be regenerated.\n")); + + /* referenced via genshelloptOptions.pzFullVersion */ + puts(_("genshellopt 1")); + + /* referenced via genshelloptOptions.pzFullUsage */ + puts(_("<<>>")); + + /* referenced via genshelloptOptions.pzShortUsage */ + puts(_("<<>>")); + /* LIBOPTS-MESSAGES: */ +#line 67 "../autoopts.c" + puts(_("allocation of %d bytes failed\n")); +#line 89 "../autoopts.c" + puts(_("allocation of %d bytes failed\n")); +#line 48 "../init.c" + puts(_("AutoOpts function called without option descriptor\n")); +#line 81 "../init.c" + puts(_("\tThis exceeds the compiled library version: ")); +#line 79 "../init.c" + puts(_("Automated Options Processing Error!\n" + "\t%s called AutoOpts function with structure version %d:%d:%d.\n")); +#line 78 "../autoopts.c" + puts(_("realloc of %d bytes at 0x%p failed\n")); +#line 83 "../init.c" + puts(_("\tThis is less than the minimum library version: ")); +#line 121 "../version.c" + puts(_("Automated Options version %s\n" + "\tCopyright (C) 1999-2017 by Bruce Korb - all rights reserved\n")); +#line 49 "../makeshell.c" + puts(_("(AutoOpts bug): %s.\n")); +#line 90 "../reset.c" + puts(_("optionResetOpt() called, but reset-option not configured")); +#line 241 "../usage.c" + puts(_("could not locate the 'help' option")); +#line 330 "../autoopts.c" + puts(_("optionProcess() was called with invalid data")); +#line 697 "../usage.c" + puts(_("invalid argument type specified")); +#line 568 "../find.c" + puts(_("defaulted to option with optional arg")); +#line 76 "../alias.c" + puts(_("aliasing option is out of range.")); +#line 210 "../enum.c" + puts(_("%s error: the keyword '%s' is ambiguous for %s\n")); +#line 78 "../find.c" + puts(_(" The following options match:\n")); +#line 263 "../find.c" + puts(_("%s: ambiguous option name: %s (matches %d options)\n")); +#line 161 "../check.c" + puts(_("%s: Command line arguments required\n")); +#line 43 "../alias.c" + puts(_("%d %s%s options allowed\n")); +#line 56 "../makeshell.c" + puts(_("%s error %d (%s) calling %s for '%s'\n")); +#line 268 "../makeshell.c" + puts(_("interprocess pipe")); +#line 171 "../version.c" + puts(_("error: version option argument '%c' invalid. Use:\n" + "\t'v' - version only\n" + "\t'c' - version and copyright\n" + "\t'n' - version and full copyright notice\n")); +#line 58 "../check.c" + puts(_("%s error: the '%s' and '%s' options conflict\n")); +#line 187 "../find.c" + puts(_("%s: The '%s' option has been disabled.")); +#line 400 "../find.c" + puts(_("%s: The '%s' option has been disabled.")); +#line 38 "../alias.c" + puts(_("-equivalence")); +#line 439 "../find.c" + puts(_("%s: illegal option -- %c\n")); +#line 110 "../reset.c" + puts(_("%s: illegal option -- %c\n")); +#line 241 "../find.c" + puts(_("%s: illegal option -- %s\n")); +#line 740 "../find.c" + puts(_("%s: illegal option -- %s\n")); +#line 118 "../reset.c" + puts(_("%s: illegal option -- %s\n")); +#line 305 "../find.c" + puts(_("%s: unknown vendor extension option -- %s\n")); +#line 135 "../enum.c" + puts(_(" or an integer from %d through %d\n")); +#line 145 "../enum.c" + puts(_(" or an integer from %d through %d\n")); +#line 696 "../usage.c" + puts(_("%s error: invalid option descriptor for %s\n")); +#line 1030 "../usage.c" + puts(_("%s error: invalid option descriptor for %s\n")); +#line 355 "../find.c" + puts(_("%s: invalid option name: %s\n")); +#line 497 "../find.c" + puts(_("%s: The '%s' option requires an argument.\n")); +#line 150 "../autoopts.c" + puts(_("(AutoOpts bug): Equivalenced option '%s' was equivalenced to both\n" + "\t'%s' and '%s'.")); +#line 94 "../check.c" + puts(_("%s error: The %s option is required\n")); +#line 602 "../find.c" + puts(_("%s: The '%s' option cannot have an argument.\n")); +#line 151 "../check.c" + puts(_("%s: Command line arguments are not allowed.\n")); +#line 568 "../save.c" + puts(_("error %d (%s) creating %s\n")); +#line 210 "../enum.c" + puts(_("%s error: '%s' does not match any %s keywords.\n")); +#line 93 "../reset.c" + puts(_("%s error: The '%s' option requires an argument.\n")); +#line 122 "../save.c" + puts(_("error %d (%s) stat-ing %s\n")); +#line 175 "../save.c" + puts(_("error %d (%s) stat-ing %s\n")); +#line 143 "../restore.c" + puts(_("%s error: no saved option state\n")); +#line 225 "../autoopts.c" + puts(_("'%s' is not a command line option.\n")); +#line 113 "../time.c" + puts(_("%s error: '%s' is not a recognizable date/time.\n")); +#line 50 "../time.c" + puts(_("%s error: '%s' is not a recognizable time duration.\n")); +#line 92 "../check.c" + puts(_("%s error: The %s option must appear %d times.\n")); +#line 165 "../numeric.c" + puts(_("%s error: '%s' is not a recognizable number.\n")); +#line 176 "../enum.c" + puts(_("%s error: %s exceeds %s keyword count\n")); +#line 279 "../usage.c" + puts(_("Try '%s %s' for more information.\n")); +#line 45 "../alias.c" + puts(_("one %s%s option allowed\n")); +#line 170 "../makeshell.c" + puts(_("standard output")); +#line 905 "../makeshell.c" + puts(_("standard output")); +#line 223 "../usage.c" + puts(_("standard output")); +#line 364 "../usage.c" + puts(_("standard output")); +#line 574 "../usage.c" + puts(_("standard output")); +#line 178 "../version.c" + puts(_("standard output")); +#line 223 "../usage.c" + puts(_("standard error")); +#line 364 "../usage.c" + puts(_("standard error")); +#line 574 "../usage.c" + puts(_("standard error")); +#line 178 "../version.c" + puts(_("standard error")); +#line 170 "../makeshell.c" + puts(_("write")); +#line 905 "../makeshell.c" + puts(_("write")); +#line 222 "../usage.c" + puts(_("write")); +#line 363 "../usage.c" + puts(_("write")); +#line 573 "../usage.c" + puts(_("write")); +#line 177 "../version.c" + puts(_("write")); +#line 60 "../numeric.c" + puts(_("%s error: %s option value %ld is out of range.\n")); +#line 44 "../check.c" + puts(_("%s error: %s option requires the %s option\n")); +#line 121 "../save.c" + puts(_("%s warning: cannot save options - %s not regular file\n")); +#line 174 "../save.c" + puts(_("%s warning: cannot save options - %s not regular file\n")); +#line 193 "../save.c" + puts(_("%s warning: cannot save options - %s not regular file\n")); +#line 567 "../save.c" + puts(_("%s warning: cannot save options - %s not regular file\n")); + /* END-LIBOPTS-MESSAGES */ + + /* USAGE-TEXT: */ +#line 822 "../usage.c" + puts(_("\t\t\t\t- an alternate for '%s'\n")); +#line 1097 "../usage.c" + puts(_("Version, usage and configuration options:")); +#line 873 "../usage.c" + puts(_("\t\t\t\t- default option for unnamed options\n")); +#line 786 "../usage.c" + puts(_("\t\t\t\t- disabled as '--%s'\n")); +#line 1066 "../usage.c" + puts(_(" --- %-14s %s\n")); +#line 1064 "../usage.c" + puts(_("This option has been disabled")); +#line 813 "../usage.c" + puts(_("\t\t\t\t- enabled by default\n")); +#line 40 "../alias.c" + puts(_("%s error: only ")); +#line 1143 "../usage.c" + puts(_(" - examining environment variables named %s_*\n")); +#line 168 "../file.c" + puts(_("\t\t\t\t- file must not pre-exist\n")); +#line 172 "../file.c" + puts(_("\t\t\t\t- file must pre-exist\n")); +#line 329 "../usage.c" + puts(_("Options are specified by doubled hyphens and their name or by a single\n" + "hyphen and the flag character.\n")); +#line 882 "../makeshell.c" + puts(_("\n" + "= = = = = = = =\n\n" + "This incarnation of genshell will produce\n" + "a shell script to parse the options for %s:\n\n")); +#line 142 "../enum.c" + puts(_(" or an integer mask with any of the lower %d bits set\n")); +#line 846 "../usage.c" + puts(_("\t\t\t\t- is a set membership option\n")); +#line 867 "../usage.c" + puts(_("\t\t\t\t- must appear between %d and %d times\n")); +#line 331 "../usage.c" + puts(_("Options are specified by single or double hyphens and their name.\n")); +#line 853 "../usage.c" + puts(_("\t\t\t\t- may appear multiple times\n")); +#line 840 "../usage.c" + puts(_("\t\t\t\t- may not be preset\n")); +#line 1258 "../usage.c" + puts(_(" Arg Option-Name Description\n")); +#line 1194 "../usage.c" + puts(_(" Flg Arg Option-Name Description\n")); +#line 1252 "../usage.c" + puts(_(" Flg Arg Option-Name Description\n")); +#line 1253 "../usage.c" + puts(_(" %3s %s")); +#line 1259 "../usage.c" + puts(_(" %3s %s")); +#line 336 "../usage.c" + puts(_("The '-#' option may omit the hash char\n")); +#line 332 "../usage.c" + puts(_("All arguments are named options.\n")); +#line 920 "../usage.c" + puts(_(" - reading file %s")); +#line 358 "../usage.c" + puts(_("\n" + "Please send bug reports to: <%s>\n")); +#line 100 "../version.c" + puts(_("\n" + "Please send bug reports to: <%s>\n")); +#line 129 "../version.c" + puts(_("\n" + "Please send bug reports to: <%s>\n")); +#line 852 "../usage.c" + puts(_("\t\t\t\t- may NOT appear - preset only\n")); +#line 893 "../usage.c" + puts(_("\n" + "The following option preset mechanisms are supported:\n")); +#line 1141 "../usage.c" + puts(_("\n" + "The following option preset mechanisms are supported:\n")); +#line 631 "../usage.c" + puts(_("prohibits these options:\n")); +#line 626 "../usage.c" + puts(_("prohibits the option '%s'\n")); +#line 81 "../numeric.c" + puts(_("%s%ld to %ld")); +#line 79 "../numeric.c" + puts(_("%sgreater than or equal to %ld")); +#line 75 "../numeric.c" + puts(_("%s%ld exactly")); +#line 68 "../numeric.c" + puts(_("%sit must lie in one of the ranges:\n")); +#line 68 "../numeric.c" + puts(_("%sit must be in the range:\n")); +#line 88 "../numeric.c" + puts(_(", or\n")); +#line 66 "../numeric.c" + puts(_("%sis scalable with a suffix: k/K/m/M/g/G/t/T\n")); +#line 77 "../numeric.c" + puts(_("%sless than or equal to %ld")); +#line 339 "../usage.c" + puts(_("Operands and options may be intermixed. They will be reordered.\n")); +#line 601 "../usage.c" + puts(_("requires the option '%s'\n")); +#line 604 "../usage.c" + puts(_("requires these options:\n")); +#line 1270 "../usage.c" + puts(_(" Arg Option-Name Req? Description\n")); +#line 1264 "../usage.c" + puts(_(" Flg Arg Option-Name Req? Description\n")); +#line 143 "../enum.c" + puts(_("or you may use a numeric representation. Preceding these with a '!'\n" + "will clear the bits, specifying 'none' will clear all bits, and 'all'\n" + "will set them all. Multiple entries may be passed as an option\n" + "argument list.\n")); +#line 859 "../usage.c" + puts(_("\t\t\t\t- may appear up to %d times\n")); +#line 52 "../enum.c" + puts(_("The valid \"%s\" option keywords are:\n")); +#line 1101 "../usage.c" + puts(_("The next option supports vendor supported extra options:")); +#line 722 "../usage.c" + puts(_("These additional options are:")); + /* END-USAGE-TEXT */ +} +#endif /* uncompilable code */ +#ifdef __cplusplus +} +#endif +/* genshell.c ends here */ diff --git a/autoopts/genshell.def b/autoopts/genshell.def new file mode 100644 index 0000000..8a4e2f0 --- /dev/null +++ b/autoopts/genshell.def @@ -0,0 +1,83 @@ + +autogen definitions options; + +/** + * \file genshell.def + * + * This module generates shell scripts with AutoOpts supported command line + * option processing. This program is licensed separately from the AutoOpts + * library and is _only_ available under the terms of the GNU General + * Public License. + * + * Genshell Copyright (C) 1999-2018 by Bruce Korb - all rights reserved + * Genshell is free software. + * This file is part of AutoGen. + * + * AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoGen is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AutoGen is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +copyright = { + date = "1999-2018"; + owner = "Bruce Korb"; + eaddr = "autogen-users@lists.sourceforge.net"; + type = lgplv2; +}; + +owner = "Bruce Korb"; +prog-name = "genshellopt"; +prog-title = "Generate Shell Option Processing Script"; +long-opts; +usage = genshelloptUsage; +prefix = genshell; + +version = 1; + +flag = { + name = script; + value = o; + arg-type = string; + descrip = "Output Script File"; +}; + +flag = { + name = shell; + disable = no; + enabled; + value = s; + arg-type = string; + descrip = 'Shell name (follows "#!" magic)'; +}; + +option-doc-format = texi; + +explain =<<- _EOF_ + Note that @code{shell} is only useful if the output file does not + already exist. If it does, then the shell name and optional first + argument will be extracted from the script file. + _EOF_; + +detail =<<- _EOF_ + If the script file already exists and contains Automated Option + Processing text, the second line of the file through the ending tag + will be replaced by the newly generated text. The first @code{#!} + line will be regenerated. + _EOF_; + +export = <<- EndOfText + #define ch_t unsigned char + #define cc_t const unsigned char + #define cch_t char const + EndOfText; diff --git a/autoopts/genshell.h b/autoopts/genshell.h new file mode 100644 index 0000000..994af16 --- /dev/null +++ b/autoopts/genshell.h @@ -0,0 +1,224 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * DO NOT EDIT THIS FILE (genshell.h) + * + * It has been AutoGen-ed + * From the definitions genshell.def + * and the template file options + * + * Generated from AutoOpts 42:1:17 templates. + * + * AutoOpts is a copyrighted work. This header file is not encumbered + * by AutoOpts licensing, but is provided under the licensing terms chosen + * by the genshellopt author or copyright holder. AutoOpts is + * licensed under the terms of the LGPL. The redistributable library + * (``libopts'') is licensed under the terms of either the LGPL or, at the + * users discretion, the BSD license. See the AutoOpts and/or libopts sources + * for details. + * + * The genshellopt program is copyrighted and licensed + * under the following terms: + * + * Copyright (C) 1999-2018 Bruce Korb, all rights reserved. + * This is free software. It is licensed for use, modification and + * redistribution under the terms of the GNU Lesser General Public License, + * version 2 or later + * + * The genshellopt 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, see + * + */ +/** + * This file contains the programmatic interface to the Automated + * Options generated for the genshellopt program. + * These macros are documented in the AutoGen info file in the + * "AutoOpts" chapter. Please refer to that doc for usage help. + */ +#ifndef AUTOOPTS_GENSHELL_H_GUARD +#define AUTOOPTS_GENSHELL_H_GUARD 1 +#include +#include +#include + +/** + * Ensure that the library used for compiling this generated header is at + * least as new as the version current when the header template was released + * (not counting patch version increments). Also ensure that the oldest + * tolerable version is at least as old as what was current when the header + * template was released. + */ +#define AO_TEMPLATE_VERSION 172033 +#if (AO_TEMPLATE_VERSION < OPTIONS_MINIMUM_VERSION) \ + || (AO_TEMPLATE_VERSION > OPTIONS_STRUCT_VERSION) +# error option template version mismatches autoopts/options.h header + Choke Me. +#endif + +#if GCC_VERSION > 40400 +#define NOT_REACHED __builtin_unreachable(); +#else +#define NOT_REACHED +#endif + +/** + * Enumeration of each option type for genshellopt + */ +typedef enum { + INDEX_GENSHELL_OPT_SCRIPT = 0, + INDEX_GENSHELL_OPT_SHELL = 1, + INDEX_GENSHELL_OPT_VERSION = 2, + INDEX_GENSHELL_OPT_HELP = 3, + INDEX_GENSHELL_OPT_MORE_HELP = 4 +} teGenshell_OptIndex; +/** count of all options for genshellopt */ +#define GENSHELL_OPTION_CT 5 +/** genshellopt version */ +#define GENSHELLOPT_VERSION "1" +/** Full genshellopt version text */ +#define GENSHELLOPT_FULL_VERSION "genshellopt 1" + +/** + * Interface defines for all options. Replace "n" with the UPPER_CASED + * option name (as in the teGenshell_OptIndex enumeration above). + * e.g. HAVE_GENSHELL_OPT(SCRIPT) + */ +#define GENSHELL_DESC(n) (genshelloptOptions.pOptDesc[INDEX_GENSHELL_OPT_## n]) +/** 'true' if an option has been specified in any way */ +#define HAVE_GENSHELL_OPT(n) (! UNUSED_OPT(& GENSHELL_DESC(n))) +/** The string argument to an option. The argument type must be \"string\". */ +#define GENSHELL_OPT_ARG(n) (GENSHELL_DESC(n).optArg.argString) +/** Mask the option state revealing how an option was specified. + * It will be one and only one of \a OPTST_SET, \a OPTST_PRESET, + * \a OPTST_DEFINED, \a OPTST_RESET or zero. + */ +#define STATE_GENSHELL_OPT(n) (GENSHELL_DESC(n).fOptState & OPTST_SET_MASK) +/** Count of option's occurrances *on the command line*. */ +#define COUNT_GENSHELL_OPT(n) (GENSHELL_DESC(n).optOccCt) +/** mask of \a OPTST_SET and \a OPTST_DEFINED. */ +#define ISSEL_GENSHELL_OPT(n) (SELECTED_OPT(&GENSHELL_DESC(n))) +/** 'true' if \a HAVE_OPT would yield 'false'. */ +#define ISUNUSED_GENSHELL_OPT(n) (UNUSED_OPT(& GENSHELL_DESC(n))) +/** 'true' if OPTST_DISABLED bit not set. */ +#define ENABLED_GENSHELL_OPT(n) (! DISABLED_OPT(& GENSHELL_DESC(n))) +/** number of stacked option arguments. + * Valid only for stacked option arguments. */ +#define STACKCT_GENSHELL_OPT(n) (((tArgList*)(GENSHELL_DESC(n).optCookie))->useCt) +/** stacked argument vector. + * Valid only for stacked option arguments. */ +#define STACKLST_GENSHELL_OPT(n) (((tArgList*)(GENSHELL_DESC(n).optCookie))->apzArgs) +/** Reset an option. */ +#define CLEAR_GENSHELL_OPT(n) STMTS( \ + GENSHELL_DESC(n).fOptState &= OPTST_PERSISTENT_MASK; \ + if ((GENSHELL_DESC(n).fOptState & OPTST_INITENABLED) == 0) \ + GENSHELL_DESC(n).fOptState |= OPTST_DISABLED; \ + GENSHELL_DESC(n).optCookie = NULL ) +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Enumeration of genshellopt exit codes + */ +typedef enum { + GENSHELLOPT_EXIT_SUCCESS = 0, + GENSHELLOPT_EXIT_FAILURE = 1, + GENSHELLOPT_EXIT_USAGE_ERROR = 64, + GENSHELLOPT_EXIT_LIBOPTS_FAILURE = 70 +} genshellopt_exit_code_t; +/** + * Interface defines for specific options. + * @{ + */ +#define VALUE_GENSHELL_OPT_SCRIPT 'o' +#define VALUE_GENSHELL_OPT_SHELL 's' +/** option flag (value) for help-value option */ +#define VALUE_GENSHELL_OPT_HELP '?' +/** option flag (value) for more-help-value option */ +#define VALUE_GENSHELL_OPT_MORE_HELP '!' +/** option flag (value) for version-value option */ +#define VALUE_GENSHELL_OPT_VERSION 'v' +/* + * Interface defines not associated with particular options + */ +#define ERRSKIP_GENSHELL_OPTERR STMTS(genshelloptOptions.fOptSet &= ~OPTPROC_ERRSTOP) +#define ERRSTOP_GENSHELL_OPTERR STMTS(genshelloptOptions.fOptSet |= OPTPROC_ERRSTOP) +#define RESTART_GENSHELL_OPT(n) STMTS( \ + genshelloptOptions.curOptIdx = (n); \ + genshelloptOptions.pzCurOpt = NULL ) +#define START_GENSHELL_OPT RESTART_GENSHELL_OPT(1) +#define GENSHELL_USAGE(c) (*genshelloptOptions.pUsageProc)(&genshelloptOptions, c) + +#ifdef __cplusplus +extern "C" { +#endif +/* + * global exported definitions + */ +#define ch_t unsigned char +#define cc_t const unsigned char +#define cch_t char const + + +/* * * * * * + * + * Declare the genshellopt option descriptor. + */ +extern tOptions genshelloptOptions; + +#if defined(ENABLE_NLS) +# ifndef _ +# include +# ifndef HAVE_GETTEXT + extern char * gettext(char const *); +# else +# include +# endif + +# ifndef ATTRIBUTE_FORMAT_ARG +# define ATTRIBUTE_FORMAT_ARG(_a) +# endif + +static inline char* aoGetsText(char const* pz) ATTRIBUTE_FORMAT_ARG(1); +static inline char* aoGetsText(char const* pz) { + if (pz == NULL) return NULL; + return (char*)gettext(pz); +} +# define _(s) aoGetsText(s) +# endif /* _() */ + +# define OPT_NO_XLAT_CFG_NAMES STMTS(genshelloptOptions.fOptSet |= \ + OPTPROC_NXLAT_OPT_CFG;) +# define OPT_NO_XLAT_OPT_NAMES STMTS(genshelloptOptions.fOptSet |= \ + OPTPROC_NXLAT_OPT|OPTPROC_NXLAT_OPT_CFG;) + +# define OPT_XLAT_CFG_NAMES STMTS(genshelloptOptions.fOptSet &= \ + ~(OPTPROC_NXLAT_OPT|OPTPROC_NXLAT_OPT_CFG);) +# define OPT_XLAT_OPT_NAMES STMTS(genshelloptOptions.fOptSet &= \ + ~OPTPROC_NXLAT_OPT;) + +#else /* ENABLE_NLS */ +# define OPT_NO_XLAT_CFG_NAMES +# define OPT_NO_XLAT_OPT_NAMES + +# define OPT_XLAT_CFG_NAMES +# define OPT_XLAT_OPT_NAMES + +# ifndef _ +# define _(_s) _s +# endif +#endif /* ENABLE_NLS */ + + +#ifdef __cplusplus +} +#endif +#endif /* AUTOOPTS_GENSHELL_H_GUARD */ + +/* genshell.h ends here */ diff --git a/autoopts/gettext.h b/autoopts/gettext.h new file mode 100644 index 0000000..87ec819 --- /dev/null +++ b/autoopts/gettext.h @@ -0,0 +1,294 @@ +/* Convenience header for conditional use of GNU . + Copyright (C) 1995-1998, 2000-2002, 2004-2006, 2009-2018 Free Software + Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1, 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License along + with this program; if not, see . */ + +#ifndef _LIBGETTEXT_H +#define _LIBGETTEXT_H 1 + +/* NLS can be disabled through the configure --disable-nls option + or through "#define ENABLE NLS 0" before including this file. */ +#if defined ENABLE_NLS && ENABLE_NLS + +/* Get declarations of GNU message catalog functions. */ +# include + +/* You can set the DEFAULT_TEXT_DOMAIN macro to specify the domain used by + the gettext() and ngettext() macros. This is an alternative to calling + textdomain(), and is useful for libraries. */ +# ifdef DEFAULT_TEXT_DOMAIN +# undef gettext +# define gettext(Msgid) \ + dgettext (DEFAULT_TEXT_DOMAIN, Msgid) +# undef ngettext +# define ngettext(Msgid1, Msgid2, N) \ + dngettext (DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N) +# endif + +#else + +/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which + chokes if dcgettext is defined as a macro. So include it now, to make + later inclusions of a NOP. We don't include + as well because people using "gettext.h" will not include , + and also including would fail on SunOS 4, whereas + is OK. */ +#if defined(__sun) +# include +#endif + +/* Many header files from the libstdc++ coming with g++ 3.3 or newer include + , which chokes if dcgettext is defined as a macro. So include + it now, to make later inclusions of a NOP. */ +#if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3) +# include +# if (__GLIBC__ >= 2 && !defined __UCLIBC__) || _GLIBCXX_HAVE_LIBINTL_H +# include +# endif +#endif + +/* Disabled NLS. + The casts to 'const char *' serve the purpose of producing warnings + for invalid uses of the value returned from these functions. + On pre-ANSI systems without 'const', the config.h file is supposed to + contain "#define const". */ +# undef gettext +# define gettext(Msgid) ((const char *) (Msgid)) +# undef dgettext +# define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid)) +# undef dcgettext +# define dcgettext(Domainname, Msgid, Category) \ + ((void) (Category), dgettext (Domainname, Msgid)) +# undef ngettext +# define ngettext(Msgid1, Msgid2, N) \ + ((N) == 1 \ + ? ((void) (Msgid2), (const char *) (Msgid1)) \ + : ((void) (Msgid1), (const char *) (Msgid2))) +# undef dngettext +# define dngettext(Domainname, Msgid1, Msgid2, N) \ + ((void) (Domainname), ngettext (Msgid1, Msgid2, N)) +# undef dcngettext +# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \ + ((void) (Category), dngettext (Domainname, Msgid1, Msgid2, N)) +# undef textdomain +# define textdomain(Domainname) ((const char *) (Domainname)) +# undef bindtextdomain +# define bindtextdomain(Domainname, Dirname) \ + ((void) (Domainname), (const char *) (Dirname)) +# undef bind_textdomain_codeset +# define bind_textdomain_codeset(Domainname, Codeset) \ + ((void) (Domainname), (const char *) (Codeset)) + +#endif + +/* Prefer gnulib's setlocale override over libintl's setlocale override. */ +#ifdef GNULIB_defined_setlocale +# undef setlocale +# define setlocale rpl_setlocale +#endif + +/* A pseudo function call that serves as a marker for the automated + extraction of messages, but does not call gettext(). The run-time + translation is done at a different place in the code. + The argument, String, should be a literal string. Concatenated strings + and other string expressions won't work. + The macro's expansion is not parenthesized, so that it is suitable as + initializer for static 'char[]' or 'const char[]' variables. */ +#define gettext_noop(String) String + +/* The separator between msgctxt and msgid in a .mo file. */ +#define GETTEXT_CONTEXT_GLUE "\004" + +/* Pseudo function calls, taking a MSGCTXT and a MSGID instead of just a + MSGID. MSGCTXT and MSGID must be string literals. MSGCTXT should be + short and rarely need to change. + The letter 'p' stands for 'particular' or 'special'. */ +#ifdef DEFAULT_TEXT_DOMAIN +# define pgettext(Msgctxt, Msgid) \ + pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) +#else +# define pgettext(Msgctxt, Msgid) \ + pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) +#endif +#define dpgettext(Domainname, Msgctxt, Msgid) \ + pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES) +#define dcpgettext(Domainname, Msgctxt, Msgid, Category) \ + pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category) +#ifdef DEFAULT_TEXT_DOMAIN +# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \ + npgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) +#else +# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \ + npgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) +#endif +#define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \ + npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES) +#define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \ + npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category) + +#ifdef __GNUC__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static const char * +pgettext_aux (const char *domain, + const char *msg_ctxt_id, const char *msgid, + int category) +{ + const char *translation = dcgettext (domain, msg_ctxt_id, category); + if (translation == msg_ctxt_id) + return msgid; + else + return translation; +} + +#ifdef __GNUC__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static const char * +npgettext_aux (const char *domain, + const char *msg_ctxt_id, const char *msgid, + const char *msgid_plural, unsigned long int n, + int category) +{ + const char *translation = + dcngettext (domain, msg_ctxt_id, msgid_plural, n, category); + if (translation == msg_ctxt_id || translation == msgid_plural) + return (n == 1 ? msgid : msgid_plural); + else + return translation; +} + +/* The same thing extended for non-constant arguments. Here MSGCTXT and MSGID + can be arbitrary expressions. But for string literals these macros are + less efficient than those above. */ + +#include + +#if (((__GNUC__ >= 3 || __GNUG__ >= 2) && !defined __STRICT_ANSI__) \ + /* || __STDC_VERSION__ == 199901L + || (__STDC_VERSION__ >= 201112L && !defined __STDC_NO_VLA__) */ ) +# define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 1 +#else +# define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 0 +#endif + +#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS +#include +#endif + +#define pgettext_expr(Msgctxt, Msgid) \ + dcpgettext_expr (NULL, Msgctxt, Msgid, LC_MESSAGES) +#define dpgettext_expr(Domainname, Msgctxt, Msgid) \ + dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES) + +#ifdef __GNUC__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static const char * +dcpgettext_expr (const char *domain, + const char *msgctxt, const char *msgid, + int category) +{ + size_t msgctxt_len = strlen (msgctxt) + 1; + size_t msgid_len = strlen (msgid) + 1; + const char *translation; +#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS + char msg_ctxt_id[msgctxt_len + msgid_len]; +#else + char buf[1024]; + char *msg_ctxt_id = + (msgctxt_len + msgid_len <= sizeof (buf) + ? buf + : (char *) malloc (msgctxt_len + msgid_len)); + if (msg_ctxt_id != NULL) +#endif + { + int found_translation; + memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1); + msg_ctxt_id[msgctxt_len - 1] = '\004'; + memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len); + translation = dcgettext (domain, msg_ctxt_id, category); + found_translation = (translation != msg_ctxt_id); +#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS + if (msg_ctxt_id != buf) + free (msg_ctxt_id); +#endif + if (found_translation) + return translation; + } + return msgid; +} + +#define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \ + dcnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES) +#define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \ + dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES) + +#ifdef __GNUC__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static const char * +dcnpgettext_expr (const char *domain, + const char *msgctxt, const char *msgid, + const char *msgid_plural, unsigned long int n, + int category) +{ + size_t msgctxt_len = strlen (msgctxt) + 1; + size_t msgid_len = strlen (msgid) + 1; + const char *translation; +#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS + char msg_ctxt_id[msgctxt_len + msgid_len]; +#else + char buf[1024]; + char *msg_ctxt_id = + (msgctxt_len + msgid_len <= sizeof (buf) + ? buf + : (char *) malloc (msgctxt_len + msgid_len)); + if (msg_ctxt_id != NULL) +#endif + { + int found_translation; + memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1); + msg_ctxt_id[msgctxt_len - 1] = '\004'; + memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len); + translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category); + found_translation = !(translation == msg_ctxt_id || translation == msgid_plural); +#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS + if (msg_ctxt_id != buf) + free (msg_ctxt_id); +#endif + if (found_translation) + return translation; + } + return (n == 1 ? msgid : msgid_plural); +} + +#endif /* _LIBGETTEXT_H */ diff --git a/autoopts/init.c b/autoopts/init.c new file mode 100644 index 0000000..b65e593 --- /dev/null +++ b/autoopts/init.c @@ -0,0 +1,289 @@ +/** + * \file initialize.c + * + * initialize the libopts data structures. + * + * @addtogroup autoopts + * @{ + */ +/* + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +/** + * Make sure the option descriptor is there and that we understand it. + * This should be called from any user entry point where one needs to + * worry about validity. (Some entry points are free to assume that + * the call is not the first to the library and, thus, that this has + * already been called.) + * + * Upon successful completion, pzProgName and pzProgPath are set. + * + * @param[in,out] opts program options descriptor + * @param[in] pname name of program, from argv[] + * @returns SUCCESS or FAILURE + */ +static tSuccess +validate_struct(tOptions * opts, char const * pname) +{ + if (opts == NULL) { + fputs(zno_opt_arg, stderr); + return FAILURE; + } + print_exit = ((opts->fOptSet & OPTPROC_SHELL_OUTPUT) != 0); + + /* + * IF the client has enabled translation and the translation procedure + * is available, then go do it. + */ + if ( ((opts->fOptSet & OPTPROC_TRANSLATE) != 0) + && (opts->pTransProc != NULL) + && (option_xlateable_txt.field_ct != 0) ) { + /* + * If option names are not to be translated at all, then do not do + * it for configuration parsing either. (That is the bit that really + * gets tested anyway.) + */ + if ((opts->fOptSet & OPTPROC_NO_XLAT_MASK) == OPTPROC_NXLAT_OPT) + opts->fOptSet |= OPTPROC_NXLAT_OPT_CFG; + opts->pTransProc(); + } + + /* + * IF the struct version is not the current, and also + * either too large (?!) or too small, + * THEN emit error message and fail-exit + */ + if ( ( opts->structVersion != OPTIONS_STRUCT_VERSION ) + && ( (opts->structVersion > OPTIONS_STRUCT_VERSION ) + || (opts->structVersion < OPTIONS_MINIMUM_VERSION ) + ) ) { + fprintf(stderr, zwrong_ver, pname, NUM_TO_VER(opts->structVersion)); + if (opts->structVersion > OPTIONS_STRUCT_VERSION ) + fputs(ztoo_new, stderr); + else + fputs(ztoo_old, stderr); + + fwrite(ao_ver_string, sizeof(ao_ver_string) - 1, 1, stderr); + return FAILURE; + } + + /* + * If the program name hasn't been set, then set the name and the path + * and the set of equivalent characters. + */ + if (opts->pzProgName == NULL) { + char const * pz = strrchr(pname, DIRCH); + char const ** pp = + (char const **)(void **)&(opts->pzProgName); + + if (pz != NULL) + *pp = pz+1; + else + *pp = pname; + + pz = pathfind(getenv("PATH"), (char *)pname, "rx"); + if (pz != NULL) + pname = VOIDP(pz); + + pp = (char const **)VOIDP(&(opts->pzProgPath)); + *pp = pname; + + /* + * when comparing long names, these are equivalent + */ + strequate(zSepChars); + } + + return SUCCESS; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * DO PRESETS + * + * The next several routines do the immediate action pass on the command + * line options, then the environment variables, then the config files in + * reverse order. Once done with that, the order is reversed and all + * the config files and environment variables are processed again, this + * time only processing the non-immediate action options. do_presets() + * will then return for optionProcess() to do the final pass on the command + * line arguments. + */ + +/** + * scan the command line for immediate action options. + * This is only called the first time through. + * While this procedure is active, the OPTPROC_IMMEDIATE is true. + * + * @param pOpts program options descriptor + * @returns SUCCESS or FAILURE + */ +static tSuccess +immediate_opts(tOptions * opts) +{ + tSuccess res; + + opts->fOptSet |= OPTPROC_IMMEDIATE; + opts->curOptIdx = 1; /* start by skipping program name */ + opts->pzCurOpt = NULL; + + /* + * Examine all the options from the start. We process any options that + * are marked for immediate processing. + */ + for (;;) { + tOptState opt_st = OPTSTATE_INITIALIZER(PRESET); + + res = next_opt(opts, &opt_st); + switch (res) { + case FAILURE: goto failed_option; + case PROBLEM: res = SUCCESS; goto leave; + case SUCCESS: break; + } + + /* + * IF this is an immediate-attribute option, then do it. + */ + if (! DO_IMMEDIATELY(opt_st.flags)) + continue; + + if (! SUCCESSFUL(handle_opt(opts, &opt_st))) + break; + } failed_option:; + + if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0) + (*opts->pUsageProc)(opts, EXIT_FAILURE); + + leave: + + opts->fOptSet &= ~OPTPROC_IMMEDIATE; + return res; +} + +/** + * check for preset values from a config files or envrionment variables + * + * @param[in,out] opts the structure with the option names to check + */ +static tSuccess +do_presets(tOptions * opts) +{ + tOptDesc * od = NULL; + + if (! SUCCESSFUL(immediate_opts(opts))) + return FAILURE; + + /* + * IF this option set has a --save-opts option, then it also + * has a --load-opts option. See if a command line option has disabled + * option presetting. + */ + if ( (opts->specOptIdx.save_opts != NO_EQUIVALENT) + && (opts->specOptIdx.save_opts != 0)) { + od = opts->pOptDesc + opts->specOptIdx.save_opts + 1; + if (DISABLED_OPT(od)) + return SUCCESS; + } + + /* + * Until we return from this procedure, disable non-presettable opts + */ + opts->fOptSet |= OPTPROC_PRESETTING; + /* + * IF there are no config files, + * THEN do any environment presets and leave. + */ + if (opts->papzHomeList == NULL) { + env_presets(opts, ENV_ALL); + } + else { + env_presets(opts, ENV_IMM); + + /* + * Check to see if environment variables have disabled presetting. + */ + if ((od != NULL) && ! DISABLED_OPT(od)) + intern_file_load(opts); + + /* + * ${PROGRAM_LOAD_OPTS} value of "no" cannot disable other environment + * variable options. Only the loading of .rc files. + */ + env_presets(opts, ENV_NON_IMM); + } + opts->fOptSet &= ~OPTPROC_PRESETTING; + + return SUCCESS; +} + +/** + * AutoOpts initialization + * + * @param[in,out] opts the structure to initialize + * @param[in] a_ct program argument count + * @param[in] a_v program argument vector + */ +static bool +ao_initialize(tOptions * opts, int a_ct, char ** a_v) +{ + if ((opts->fOptSet & OPTPROC_INITDONE) != 0) + return true; + + opts->origArgCt = (unsigned int)a_ct; + opts->origArgVect = a_v; + opts->fOptSet |= OPTPROC_INITDONE; + + if (HAS_pzPkgDataDir(opts)) + program_pkgdatadir = opts->pzPkgDataDir; + + if (! SUCCESSFUL(do_presets(opts))) + return false; + + /* + * IF option name conversion was suppressed but it is not suppressed + * for the command line, then it's time to translate option names. + * Usage text will not get retranslated. + */ + if ( ((opts->fOptSet & OPTPROC_TRANSLATE) != 0) + && (opts->pTransProc != NULL) + && ((opts->fOptSet & OPTPROC_NO_XLAT_MASK) == OPTPROC_NXLAT_OPT_CFG) + ) { + opts->fOptSet &= ~OPTPROC_NXLAT_OPT_CFG; + (*opts->pTransProc)(); + } + + if ((opts->fOptSet & OPTPROC_REORDER) != 0) + optionSort(opts); + + opts->curOptIdx = 1; + opts->pzCurOpt = NULL; + return true; +} + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/initialize.c */ diff --git a/autoopts/install-hook.sh b/autoopts/install-hook.sh new file mode 100644 index 0000000..5aee2d9 --- /dev/null +++ b/autoopts/install-hook.sh @@ -0,0 +1,137 @@ +#! /bin/sh + +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under either of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +egrep '#undef +AUTOOPTS_ENABLED' ${top_builddir}/config.h >/dev/null && \ + exit 0 + +srcdir=`dirname $0` +srcdir=`cd ${srcdir} ; pwd` + +. ${top_builddir}/config/shdefs + +rm -f ${DESTdestdir}/options.h ${DESTdestdir}/usage-txt.h +opthdrsrc=${srcdir}/autoopts/options.h +usehdrsrc=${srcdir}/autoopts/usage-txt.h +cfgf=${top_builddir}/config.h + +emit_options_h() { + sed '/^#include /dev/null + then echo '#include ' + else echo '#include ' ; fi + + if ${EGREP} 'define +HAVE_LIMITS_H' ${cfgf} >/dev/null + then echo '#include ' + else echo '#include ' ; fi + + if ${EGREP} 'define +HAVE_STDBOOL_H' ${cfgf} >/dev/null + then echo '#include ' + else cat <<- _EOF_ + typedef enum { false = 0, true = 1 } _Bool; + #define bool _Bool + #define true 1 + #define false 0 + _EOF_ + fi + + ${EGREP} 'define +NO_OPTIONAL_OPT_ARGS' ${cfgf} + + if ${EGREP} 'define +HAVE_INTPTR_T' ${cfgf} >/dev/null + then : + else + sizeof_charp=`${EGREP} 'define +SIZEOF_CHARP ' ${cfgf} | \ + sed 's/.*SIZEOF_CHARP *//'` + sizeof_long=` ${EGREP} 'define +SIZEOF_LONG ' ${cfgf} | \ + sed 's/.*SIZEOF_LONG *//'` + if test "X${sizeof_charp}" = "X${sizeof_long}" + then ptrtype=long + else ptrtype=int + fi + cat <<- _EOF_ + #ifndef HAVE_UINTPTR_T + #define HAVE_UINTPTR_T 1 + #define HAVE_INTPTR_T 1 + typedef $ptrtype intptr_t; + typedef unsigned $ptrtype uintptr_t; + #endif /* HAVE_UINTPTR_T */ + _EOF_ + fi + + sedcmd='1,/END-CONFIGURED-HEADERS/d' + + if ${EGREP} 'define +HAVE_PATHFIND' ${cfgf} >/dev/null + then nopathfind='/From:.*pathfind\.c/,/#endif.*HAVE_PATHFIND/d' + else nopathfind='/HAVE_PATHFIND/d' ; fi + + sed "${sedcmd};${nopathfind}" ${opthdrsrc} +} +emit_options_h > ${DESTdestdir}/options.h + +sed '/#if.*AUTOOPTS_INTERNAL/,/#endif.*AUTOOPTS_INTERNAL/d' \ + ${usehdrsrc} > ${DESTdestdir}/usage-txt.h + +test -d "${DESTpkgdatadir}" && { + rmbuild='/# *START-BUILDTREE-ISMS/,/# *END-BUILDTREE-ISMS/d + /# *END-INSTALL-ONLY-CODE/d + /^##/d' + + cd ${DESTpkgdatadir} + for f in * + do case "$f" in + agtexi-cmd.tpl | cmd-doc.tlib | def2pot.tpl | \ + getopt.tpl | options.tpl | str2init.tlib | usage.tlib) + sed "${rmbuild}" $f > $f.tmp + mv -f $f.tmp $f + ;; + + tpl-config.tlib ) + sed '/define top-[a-z]*-dir/d' $f > $f.tmp + mv -f $f.tmp $f + test -n "${DESTlibdatadir}" && { + test -d ${DESTlibdatadir} || \ + mkdir -p ${DESTlibdatadir} || \ + continue + + cp $f ${DESTlibdatadir}/. + } + ;; + + *.* ) : ;; + * ) + chmod a+x $f + ;; + esac + done +} + +## Local Variables: +## Mode: shell-script +## indent-tabs-mode: nil +## sh-basic-offset: 4 +## sh-indent-after-do: 4 +## sh-indentation: 4 +## sh-indent-for-case-label: 0 +## sh-indent-for-case-alt: 4 +## End: + +# end of install-hook.sh diff --git a/autoopts/intprops.h b/autoopts/intprops.h new file mode 100644 index 0000000..af456ff --- /dev/null +++ b/autoopts/intprops.h @@ -0,0 +1,453 @@ +/* intprops.h -- properties of integer types + + Copyright (C) 2001-2018 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* Written by Paul Eggert. */ + +#ifndef _GL_INTPROPS_H +#define _GL_INTPROPS_H + +#include + +/* Return a value with the common real type of E and V and the value of V. */ +#define _GL_INT_CONVERT(e, v) (0 * (e) + (v)) + +/* Act like _GL_INT_CONVERT (E, -V) but work around a bug in IRIX 6.5 cc; see + . */ +#define _GL_INT_NEGATE_CONVERT(e, v) (0 * (e) - (v)) + +/* The extra casts in the following macros work around compiler bugs, + e.g., in Cray C 5.0.3.0. */ + +/* True if the arithmetic type T is an integer type. bool counts as + an integer. */ +#define TYPE_IS_INTEGER(t) ((t) 1.5 == 1) + +/* True if the real type T is signed. */ +#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) + +/* Return 1 if the real expression E, after promotion, has a + signed or floating type. */ +#define EXPR_SIGNED(e) (_GL_INT_NEGATE_CONVERT (e, 1) < 0) + + +/* Minimum and maximum values for integer types and expressions. */ + +/* The width in bits of the integer type or expression T. + Padding bits are not supported; this is checked at compile-time below. */ +#define TYPE_WIDTH(t) (sizeof (t) * CHAR_BIT) + +/* The maximum and minimum values for the integer type T. */ +#define TYPE_MINIMUM(t) ((t) ~ TYPE_MAXIMUM (t)) +#define TYPE_MAXIMUM(t) \ + ((t) (! TYPE_SIGNED (t) \ + ? (t) -1 \ + : ((((t) 1 << (TYPE_WIDTH (t) - 2)) - 1) * 2 + 1))) + +/* The maximum and minimum values for the type of the expression E, + after integer promotion. E should not have side effects. */ +#define _GL_INT_MINIMUM(e) \ + (EXPR_SIGNED (e) \ + ? ~ _GL_SIGNED_INT_MAXIMUM (e) \ + : _GL_INT_CONVERT (e, 0)) +#define _GL_INT_MAXIMUM(e) \ + (EXPR_SIGNED (e) \ + ? _GL_SIGNED_INT_MAXIMUM (e) \ + : _GL_INT_NEGATE_CONVERT (e, 1)) +#define _GL_SIGNED_INT_MAXIMUM(e) \ + (((_GL_INT_CONVERT (e, 1) << (TYPE_WIDTH ((e) + 0) - 2)) - 1) * 2 + 1) + +/* Work around OpenVMS incompatibility with C99. */ +#if !defined LLONG_MAX && defined __INT64_MAX +# define LLONG_MAX __INT64_MAX +# define LLONG_MIN __INT64_MIN +#endif + +/* This include file assumes that signed types are two's complement without + padding bits; the above macros have undefined behavior otherwise. + If this is a problem for you, please let us know how to fix it for your host. + This assumption is tested by the intprops-tests module. */ + +/* Does the __typeof__ keyword work? This could be done by + 'configure', but for now it's easier to do it by hand. */ +#if (2 <= __GNUC__ \ + || (1210 <= __IBMC__ && defined __IBM__TYPEOF__) \ + || (0x5110 <= __SUNPRO_C && !__STDC__)) +# define _GL_HAVE___TYPEOF__ 1 +#else +# define _GL_HAVE___TYPEOF__ 0 +#endif + +/* Return 1 if the integer type or expression T might be signed. Return 0 + if it is definitely unsigned. This macro does not evaluate its argument, + and expands to an integer constant expression. */ +#if _GL_HAVE___TYPEOF__ +# define _GL_SIGNED_TYPE_OR_EXPR(t) TYPE_SIGNED (__typeof__ (t)) +#else +# define _GL_SIGNED_TYPE_OR_EXPR(t) 1 +#endif + +/* Bound on length of the string representing an unsigned integer + value representable in B bits. log10 (2.0) < 146/485. The + smallest value of B where this bound is not tight is 2621. */ +#define INT_BITS_STRLEN_BOUND(b) (((b) * 146 + 484) / 485) + +/* Bound on length of the string representing an integer type or expression T. + Subtract 1 for the sign bit if T is signed, and then add 1 more for + a minus sign if needed. + + Because _GL_SIGNED_TYPE_OR_EXPR sometimes returns 0 when its argument is + signed, this macro may overestimate the true bound by one byte when + applied to unsigned types of size 2, 4, 16, ... bytes. */ +#define INT_STRLEN_BOUND(t) \ + (INT_BITS_STRLEN_BOUND (TYPE_WIDTH (t) - _GL_SIGNED_TYPE_OR_EXPR (t)) \ + + _GL_SIGNED_TYPE_OR_EXPR (t)) + +/* Bound on buffer size needed to represent an integer type or expression T, + including the terminating null. */ +#define INT_BUFSIZE_BOUND(t) (INT_STRLEN_BOUND (t) + 1) + + +/* Range overflow checks. + + The INT__RANGE_OVERFLOW macros return 1 if the corresponding C + operators might not yield numerically correct answers due to + arithmetic overflow. They do not rely on undefined or + implementation-defined behavior. Their implementations are simple + and straightforward, but they are a bit harder to use than the + INT__OVERFLOW macros described below. + + Example usage: + + long int i = ...; + long int j = ...; + if (INT_MULTIPLY_RANGE_OVERFLOW (i, j, LONG_MIN, LONG_MAX)) + printf ("multiply would overflow"); + else + printf ("product is %ld", i * j); + + Restrictions on *_RANGE_OVERFLOW macros: + + These macros do not check for all possible numerical problems or + undefined or unspecified behavior: they do not check for division + by zero, for bad shift counts, or for shifting negative numbers. + + These macros may evaluate their arguments zero or multiple times, + so the arguments should not have side effects. The arithmetic + arguments (including the MIN and MAX arguments) must be of the same + integer type after the usual arithmetic conversions, and the type + must have minimum value MIN and maximum MAX. Unsigned types should + use a zero MIN of the proper type. + + These macros are tuned for constant MIN and MAX. For commutative + operations such as A + B, they are also tuned for constant B. */ + +/* Return 1 if A + B would overflow in [MIN,MAX] arithmetic. + See above for restrictions. */ +#define INT_ADD_RANGE_OVERFLOW(a, b, min, max) \ + ((b) < 0 \ + ? (a) < (min) - (b) \ + : (max) - (b) < (a)) + +/* Return 1 if A - B would overflow in [MIN,MAX] arithmetic. + See above for restrictions. */ +#define INT_SUBTRACT_RANGE_OVERFLOW(a, b, min, max) \ + ((b) < 0 \ + ? (max) + (b) < (a) \ + : (a) < (min) + (b)) + +/* Return 1 if - A would overflow in [MIN,MAX] arithmetic. + See above for restrictions. */ +#define INT_NEGATE_RANGE_OVERFLOW(a, min, max) \ + ((min) < 0 \ + ? (a) < - (max) \ + : 0 < (a)) + +/* Return 1 if A * B would overflow in [MIN,MAX] arithmetic. + See above for restrictions. Avoid && and || as they tickle + bugs in Sun C 5.11 2010/08/13 and other compilers; see + . */ +#define INT_MULTIPLY_RANGE_OVERFLOW(a, b, min, max) \ + ((b) < 0 \ + ? ((a) < 0 \ + ? (a) < (max) / (b) \ + : (b) == -1 \ + ? 0 \ + : (min) / (b) < (a)) \ + : (b) == 0 \ + ? 0 \ + : ((a) < 0 \ + ? (a) < (min) / (b) \ + : (max) / (b) < (a))) + +/* Return 1 if A / B would overflow in [MIN,MAX] arithmetic. + See above for restrictions. Do not check for division by zero. */ +#define INT_DIVIDE_RANGE_OVERFLOW(a, b, min, max) \ + ((min) < 0 && (b) == -1 && (a) < - (max)) + +/* Return 1 if A % B would overflow in [MIN,MAX] arithmetic. + See above for restrictions. Do not check for division by zero. + Mathematically, % should never overflow, but on x86-like hosts + INT_MIN % -1 traps, and the C standard permits this, so treat this + as an overflow too. */ +#define INT_REMAINDER_RANGE_OVERFLOW(a, b, min, max) \ + INT_DIVIDE_RANGE_OVERFLOW (a, b, min, max) + +/* Return 1 if A << B would overflow in [MIN,MAX] arithmetic. + See above for restrictions. Here, MIN and MAX are for A only, and B need + not be of the same type as the other arguments. The C standard says that + behavior is undefined for shifts unless 0 <= B < wordwidth, and that when + A is negative then A << B has undefined behavior and A >> B has + implementation-defined behavior, but do not check these other + restrictions. */ +#define INT_LEFT_SHIFT_RANGE_OVERFLOW(a, b, min, max) \ + ((a) < 0 \ + ? (a) < (min) >> (b) \ + : (max) >> (b) < (a)) + +/* True if __builtin_add_overflow (A, B, P) works when P is non-null. */ +#if 5 <= __GNUC__ && !defined __ICC +# define _GL_HAS_BUILTIN_OVERFLOW 1 +#else +# define _GL_HAS_BUILTIN_OVERFLOW 0 +#endif + +/* True if __builtin_add_overflow_p (A, B, C) works. */ +#define _GL_HAS_BUILTIN_OVERFLOW_P (7 <= __GNUC__) + +/* The _GL*_OVERFLOW macros have the same restrictions as the + *_RANGE_OVERFLOW macros, except that they do not assume that operands + (e.g., A and B) have the same type as MIN and MAX. Instead, they assume + that the result (e.g., A + B) has that type. */ +#if _GL_HAS_BUILTIN_OVERFLOW_P +# define _GL_ADD_OVERFLOW(a, b, min, max) \ + __builtin_add_overflow_p (a, b, (__typeof__ ((a) + (b))) 0) +# define _GL_SUBTRACT_OVERFLOW(a, b, min, max) \ + __builtin_sub_overflow_p (a, b, (__typeof__ ((a) - (b))) 0) +# define _GL_MULTIPLY_OVERFLOW(a, b, min, max) \ + __builtin_mul_overflow_p (a, b, (__typeof__ ((a) * (b))) 0) +#else +# define _GL_ADD_OVERFLOW(a, b, min, max) \ + ((min) < 0 ? INT_ADD_RANGE_OVERFLOW (a, b, min, max) \ + : (a) < 0 ? (b) <= (a) + (b) \ + : (b) < 0 ? (a) <= (a) + (b) \ + : (a) + (b) < (b)) +# define _GL_SUBTRACT_OVERFLOW(a, b, min, max) \ + ((min) < 0 ? INT_SUBTRACT_RANGE_OVERFLOW (a, b, min, max) \ + : (a) < 0 ? 1 \ + : (b) < 0 ? (a) - (b) <= (a) \ + : (a) < (b)) +# define _GL_MULTIPLY_OVERFLOW(a, b, min, max) \ + (((min) == 0 && (((a) < 0 && 0 < (b)) || ((b) < 0 && 0 < (a)))) \ + || INT_MULTIPLY_RANGE_OVERFLOW (a, b, min, max)) +#endif +#define _GL_DIVIDE_OVERFLOW(a, b, min, max) \ + ((min) < 0 ? (b) == _GL_INT_NEGATE_CONVERT (min, 1) && (a) < - (max) \ + : (a) < 0 ? (b) <= (a) + (b) - 1 \ + : (b) < 0 && (a) + (b) <= (a)) +#define _GL_REMAINDER_OVERFLOW(a, b, min, max) \ + ((min) < 0 ? (b) == _GL_INT_NEGATE_CONVERT (min, 1) && (a) < - (max) \ + : (a) < 0 ? (a) % (b) != ((max) - (b) + 1) % (b) \ + : (b) < 0 && ! _GL_UNSIGNED_NEG_MULTIPLE (a, b, max)) + +/* Return a nonzero value if A is a mathematical multiple of B, where + A is unsigned, B is negative, and MAX is the maximum value of A's + type. A's type must be the same as (A % B)'s type. Normally (A % + -B == 0) suffices, but things get tricky if -B would overflow. */ +#define _GL_UNSIGNED_NEG_MULTIPLE(a, b, max) \ + (((b) < -_GL_SIGNED_INT_MAXIMUM (b) \ + ? (_GL_SIGNED_INT_MAXIMUM (b) == (max) \ + ? (a) \ + : (a) % (_GL_INT_CONVERT (a, _GL_SIGNED_INT_MAXIMUM (b)) + 1)) \ + : (a) % - (b)) \ + == 0) + +/* Check for integer overflow, and report low order bits of answer. + + The INT__OVERFLOW macros return 1 if the corresponding C operators + might not yield numerically correct answers due to arithmetic overflow. + The INT__WRAPV macros also store the low-order bits of the answer. + These macros work correctly on all known practical hosts, and do not rely + on undefined behavior due to signed arithmetic overflow. + + Example usage, assuming A and B are long int: + + if (INT_MULTIPLY_OVERFLOW (a, b)) + printf ("result would overflow\n"); + else + printf ("result is %ld (no overflow)\n", a * b); + + Example usage with WRAPV flavor: + + long int result; + bool overflow = INT_MULTIPLY_WRAPV (a, b, &result); + printf ("result is %ld (%s)\n", result, + overflow ? "after overflow" : "no overflow"); + + Restrictions on these macros: + + These macros do not check for all possible numerical problems or + undefined or unspecified behavior: they do not check for division + by zero, for bad shift counts, or for shifting negative numbers. + + These macros may evaluate their arguments zero or multiple times, so the + arguments should not have side effects. + + The WRAPV macros are not constant expressions. They support only + +, binary -, and *. The result type must be signed. + + These macros are tuned for their last argument being a constant. + + Return 1 if the integer expressions A * B, A - B, -A, A * B, A / B, + A % B, and A << B would overflow, respectively. */ + +#define INT_ADD_OVERFLOW(a, b) \ + _GL_BINARY_OP_OVERFLOW (a, b, _GL_ADD_OVERFLOW) +#define INT_SUBTRACT_OVERFLOW(a, b) \ + _GL_BINARY_OP_OVERFLOW (a, b, _GL_SUBTRACT_OVERFLOW) +#if _GL_HAS_BUILTIN_OVERFLOW_P +# define INT_NEGATE_OVERFLOW(a) INT_SUBTRACT_OVERFLOW (0, a) +#else +# define INT_NEGATE_OVERFLOW(a) \ + INT_NEGATE_RANGE_OVERFLOW (a, _GL_INT_MINIMUM (a), _GL_INT_MAXIMUM (a)) +#endif +#define INT_MULTIPLY_OVERFLOW(a, b) \ + _GL_BINARY_OP_OVERFLOW (a, b, _GL_MULTIPLY_OVERFLOW) +#define INT_DIVIDE_OVERFLOW(a, b) \ + _GL_BINARY_OP_OVERFLOW (a, b, _GL_DIVIDE_OVERFLOW) +#define INT_REMAINDER_OVERFLOW(a, b) \ + _GL_BINARY_OP_OVERFLOW (a, b, _GL_REMAINDER_OVERFLOW) +#define INT_LEFT_SHIFT_OVERFLOW(a, b) \ + INT_LEFT_SHIFT_RANGE_OVERFLOW (a, b, \ + _GL_INT_MINIMUM (a), _GL_INT_MAXIMUM (a)) + +/* Return 1 if the expression A B would overflow, + where OP_RESULT_OVERFLOW (A, B, MIN, MAX) does the actual test, + assuming MIN and MAX are the minimum and maximum for the result type. + Arguments should be free of side effects. */ +#define _GL_BINARY_OP_OVERFLOW(a, b, op_result_overflow) \ + op_result_overflow (a, b, \ + _GL_INT_MINIMUM (0 * (b) + (a)), \ + _GL_INT_MAXIMUM (0 * (b) + (a))) + +/* Store the low-order bits of A + B, A - B, A * B, respectively, into *R. + Return 1 if the result overflows. See above for restrictions. */ +#define INT_ADD_WRAPV(a, b, r) \ + _GL_INT_OP_WRAPV (a, b, r, +, __builtin_add_overflow, INT_ADD_OVERFLOW) +#define INT_SUBTRACT_WRAPV(a, b, r) \ + _GL_INT_OP_WRAPV (a, b, r, -, __builtin_sub_overflow, INT_SUBTRACT_OVERFLOW) +#define INT_MULTIPLY_WRAPV(a, b, r) \ + _GL_INT_OP_WRAPV (a, b, r, *, __builtin_mul_overflow, INT_MULTIPLY_OVERFLOW) + +/* Nonzero if this compiler has GCC bug 68193 or Clang bug 25390. See: + https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68193 + https://llvm.org/bugs/show_bug.cgi?id=25390 + For now, assume all versions of GCC-like compilers generate bogus + warnings for _Generic. This matters only for older compilers that + lack __builtin_add_overflow. */ +#if __GNUC__ +# define _GL__GENERIC_BOGUS 1 +#else +# define _GL__GENERIC_BOGUS 0 +#endif + +/* Store the low-order bits of A B into *R, where OP specifies + the operation. BUILTIN is the builtin operation, and OVERFLOW the + overflow predicate. Return 1 if the result overflows. See above + for restrictions. */ +#if _GL_HAS_BUILTIN_OVERFLOW +# define _GL_INT_OP_WRAPV(a, b, r, op, builtin, overflow) builtin (a, b, r) +#elif 201112 <= __STDC_VERSION__ && !_GL__GENERIC_BOGUS +# define _GL_INT_OP_WRAPV(a, b, r, op, builtin, overflow) \ + (_Generic \ + (*(r), \ + signed char: \ + _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \ + signed char, SCHAR_MIN, SCHAR_MAX), \ + short int: \ + _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \ + short int, SHRT_MIN, SHRT_MAX), \ + int: \ + _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \ + int, INT_MIN, INT_MAX), \ + long int: \ + _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \ + long int, LONG_MIN, LONG_MAX), \ + long long int: \ + _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long long int, \ + long long int, LLONG_MIN, LLONG_MAX))) +#else +# define _GL_INT_OP_WRAPV(a, b, r, op, builtin, overflow) \ + (sizeof *(r) == sizeof (signed char) \ + ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \ + signed char, SCHAR_MIN, SCHAR_MAX) \ + : sizeof *(r) == sizeof (short int) \ + ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \ + short int, SHRT_MIN, SHRT_MAX) \ + : sizeof *(r) == sizeof (int) \ + ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \ + int, INT_MIN, INT_MAX) \ + : _GL_INT_OP_WRAPV_LONGISH(a, b, r, op, overflow)) +# ifdef LLONG_MAX +# define _GL_INT_OP_WRAPV_LONGISH(a, b, r, op, overflow) \ + (sizeof *(r) == sizeof (long int) \ + ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \ + long int, LONG_MIN, LONG_MAX) \ + : _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long long int, \ + long long int, LLONG_MIN, LLONG_MAX)) +# else +# define _GL_INT_OP_WRAPV_LONGISH(a, b, r, op, overflow) \ + _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \ + long int, LONG_MIN, LONG_MAX) +# endif +#endif + +/* Store the low-order bits of A B into *R, where the operation + is given by OP. Use the unsigned type UT for calculation to avoid + overflow problems. *R's type is T, with extrema TMIN and TMAX. + T must be a signed integer type. Return 1 if the result overflows. */ +#define _GL_INT_OP_CALC(a, b, r, op, overflow, ut, t, tmin, tmax) \ + (sizeof ((a) op (b)) < sizeof (t) \ + ? _GL_INT_OP_CALC1 ((t) (a), (t) (b), r, op, overflow, ut, t, tmin, tmax) \ + : _GL_INT_OP_CALC1 (a, b, r, op, overflow, ut, t, tmin, tmax)) +#define _GL_INT_OP_CALC1(a, b, r, op, overflow, ut, t, tmin, tmax) \ + ((overflow (a, b) \ + || (EXPR_SIGNED ((a) op (b)) && ((a) op (b)) < (tmin)) \ + || (tmax) < ((a) op (b))) \ + ? (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, ut, t), 1) \ + : (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, ut, t), 0)) + +/* Return the low-order bits of A B, where the operation is given + by OP. Use the unsigned type UT for calculation to avoid undefined + behavior on signed integer overflow, and convert the result to type T. + UT is at least as wide as T and is no narrower than unsigned int, + T is two's complement, and there is no padding or trap representations. + Assume that converting UT to T yields the low-order bits, as is + done in all known two's-complement C compilers. E.g., see: + https://gcc.gnu.org/onlinedocs/gcc/Integers-implementation.html + + According to the C standard, converting UT to T yields an + implementation-defined result or signal for values outside T's + range. However, code that works around this theoretical problem + runs afoul of a compiler bug in Oracle Studio 12.3 x86. See: + https://lists.gnu.org/r/bug-gnulib/2017-04/msg00049.html + As the compiler bug is real, don't try to work around the + theoretical problem. */ + +#define _GL_INT_OP_WRAPV_VIA_UNSIGNED(a, b, op, ut, t) \ + ((t) ((ut) (a) op (ut) (b))) + +#endif /* _GL_INTPROPS_H */ diff --git a/autoopts/load.c b/autoopts/load.c new file mode 100644 index 0000000..59d124e --- /dev/null +++ b/autoopts/load.c @@ -0,0 +1,578 @@ + +/** + * \file load.c + * + * This file contains the routines that deal with processing text strings + * for options, either from a NUL-terminated string passed in or from an + * rc/ini file. + * + * @addtogroup autoopts + * @{ + */ +/* + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +static bool +get_realpath(char * buf, size_t b_sz) +{ +#if defined(HAVE_CANONICALIZE_FILE_NAME) + { + size_t name_len; + + char * pz = canonicalize_file_name(buf); + if (pz == NULL) + return false; + + name_len = strlen(pz); + if (name_len >= (size_t)b_sz) { + free(pz); + return false; + } + + memcpy(buf, pz, name_len + 1); + free(pz); + } + +#elif defined(HAVE_REALPATH) + { + size_t name_len; + char z[PATH_MAX+1]; + + if (realpath(buf, z) == NULL) + return false; + + name_len = strlen(z); + if (name_len >= b_sz) + return false; + + memcpy(buf, z, name_len + 1); + } +#endif + return true; +} + +/*=export_func optionMakePath + * private: + * + * what: translate and construct a path + * arg: + char * + p_buf + The result buffer + + * arg: + int + b_sz + The size of this buffer + + * arg: + char const * + fname + The input name + + * arg: + char const * + prg_path + The full path of the current program + + * + * ret-type: bool + * ret-desc: true if the name was handled, otherwise false. + * If the name does not start with ``$'', then it is handled + * simply by copying the input name to the output buffer and + * resolving the name with either + * @code{canonicalize_file_name(3GLIBC)} or @code{realpath(3C)}. + * + * doc: + * + * This routine will copy the @code{pzName} input name into the + * @code{pzBuf} output buffer, not exceeding @code{bufSize} bytes. If the + * first character of the input name is a @code{'$'} character, then there + * is special handling: + * @* + * @code{$$} is replaced with the directory name of the @code{pzProgPath}, + * searching @code{$PATH} if necessary. + * @* + * @code{$@} is replaced with the AutoGen package data installation directory + * (aka @code{pkgdatadir}). + * @* + * @code{$NAME} is replaced by the contents of the @code{NAME} environment + * variable. If not found, the search fails. + * + * Please note: both @code{$$} and @code{$NAME} must be at the start of the + * @code{pzName} string and must either be the entire string or be followed + * by the @code{'/'} (backslash on windows) character. + * + * err: @code{false} is returned if: + * @* + * @bullet{} The input name exceeds @code{bufSize} bytes. + * @* + * @bullet{} @code{$$}, @code{$@@} or @code{$NAME} is not the full string + * and the next character is not '/'. + * @* + * @bullet{} libopts was built without PKGDATADIR defined and @code{$@@} + * was specified. + * @* + * @bullet{} @code{NAME} is not a known environment variable + * @* + * @bullet{} @code{canonicalize_file_name} or @code{realpath} return + * errors (cannot resolve the resulting path). +=*/ +bool +optionMakePath(char * p_buf, int b_sz, char const * fname, char const * prg_path) +{ + { + size_t len = strlen(fname); + + if (((size_t)b_sz <= len) || (len == 0)) + return false; + } + + /* + * IF not an environment variable, just copy the data + */ + if (*fname != '$') { + char const * src = fname; + char * dst = p_buf; + int ct = b_sz; + + for (;;) { + if ( (*(dst++) = *(src++)) == NUL) + break; + if (--ct <= 0) + return false; + } + } + + /* + * IF the name starts with "$$", then it must be "$$" or + * it must start with "$$/". In either event, replace the "$$" + * with the path to the executable and append a "/" character. + */ + else switch (fname[1]) { + case NUL: + return false; + + case '$': + if (! add_prog_path(p_buf, b_sz, fname, prg_path)) + return false; + break; + + case '@': + if (program_pkgdatadir[0] == NUL) + return false; + + if (snprintf(p_buf, (size_t)b_sz, "%s%s", + program_pkgdatadir, fname + 2) >= b_sz) + return false; + break; + + default: + if (! add_env_val(p_buf, b_sz, fname)) + return false; + } + + return get_realpath(p_buf, b_sz); +} + +/** + * convert a leading "$$" into a path to the executable. + */ +static bool +add_prog_path(char * buf, int b_sz, char const * fname, char const * prg_path) +{ + char const * path; + char const * pz; + int skip = 2; + size_t fname_len; + size_t dir_len; //!< length of the directory portion of the path to the exe + + switch (fname[2]) { + case DIRCH: + skip = 3; + case NUL: + break; + default: + return false; + } + + /* + * See if the path is included in the program name. + * If it is, we're done. Otherwise, we have to hunt + * for the program using "pathfind". + */ + if (strchr(prg_path, DIRCH) != NULL) + path = prg_path; + else { + path = pathfind(getenv("PATH"), (char *)prg_path, "rx"); + + if (path == NULL) + return false; + } + + pz = strrchr(path, DIRCH); + + /* + * IF we cannot find a directory name separator, + * THEN we do not have a path name to our executable file. + */ + if (pz == NULL) + return false; + + fname += skip; + fname_len = strlen(fname) + 1; // + NUL byte + dir_len = (pz - path) + 1; // + dir sep character + + /* + * Concatenate the file name to the end of the executable path. + * The result may be either a file or a directory. + */ + if (dir_len + fname_len > (unsigned)b_sz) + return false; + + memcpy(buf, path, dir_len); + memcpy(buf + dir_len, fname, fname_len); + + /* + * If the "path" path was gotten from "pathfind()", then it was + * allocated and we need to deallocate it. + */ + if (path != prg_path) + AGFREE(path); + return true; +} + +/** + * Add an environment variable value. + */ +static bool +add_env_val(char * buf, int buf_sz, char const * name) +{ + char * dir_part = buf; + + for (;;) { + int ch = (int)*++name; + if (! IS_VALUE_NAME_CHAR(ch)) + break; + *(dir_part++) = (char)ch; + } + + if (dir_part == buf) + return false; + + *dir_part = NUL; + + dir_part = getenv(buf); + + /* + * Environment value not found -- skip the home list entry + */ + if (dir_part == NULL) + return false; + + { + size_t dir_len = strlen(dir_part); + size_t nm_len = strlen(name) + 1; + + if (dir_len + nm_len >= (unsigned)buf_sz) + return false; + memcpy(buf, dir_part, dir_len); + memcpy(buf + dir_len, name, nm_len); + } + + return true; +} + +/** + * Trim leading and trailing white space. + * If we are cooking the text and the text is quoted, then "cook" + * the string. To cook, the string must be quoted. + * + * @param[in,out] txt the input and output string + * @param[in] mode the handling mode (cooking method) + */ +static void +munge_str(char * txt, tOptionLoadMode mode) +{ + char * end; + + if (mode == OPTION_LOAD_KEEP) + return; + + if (IS_WHITESPACE_CHAR(*txt)) { + char * src = SPN_WHITESPACE_CHARS(txt+1); + size_t l = strlen(src) + 1; + memmove(txt, src, l); + end = txt + l - 1; + + } else + end = txt + strlen(txt); + + end = SPN_WHITESPACE_BACK(txt, end); + *end = NUL; + + if (mode == OPTION_LOAD_UNCOOKED) + return; + + switch (*txt) { + default: return; + case '"': + case '\'': break; + } + + switch (end[-1]) { + default: return; + case '"': + case '\'': break; + } + + (void)ao_string_cook(txt, NULL); +} + +static char * +assemble_arg_val(char * txt, tOptionLoadMode mode) +{ + char * end = strpbrk(txt, ARG_BREAK_STR); + int space_break; + + /* + * Not having an argument to a configurable name is okay. + */ + if (end == NULL) + return txt + strlen(txt); + + /* + * If we are keeping all whitespace, then the modevalue starts with the + * character that follows the end of the configurable name, regardless + * of which character caused it. + */ + if (mode == OPTION_LOAD_KEEP) { + *(end++) = NUL; + return end; + } + + /* + * If the name ended on a white space character, remember that + * because we'll have to skip over an immediately following ':' or '=' + * (and the white space following *that*). + */ + space_break = IS_WHITESPACE_CHAR(*end); + *(end++) = NUL; + + end = SPN_WHITESPACE_CHARS(end); + if (space_break && ((*end == ':') || (*end == '='))) + end = SPN_WHITESPACE_CHARS(end+1); + + return end; +} + +static char * +trim_quotes(char * arg) +{ + switch (*arg) { + case '"': + case '\'': + ao_string_cook(arg, NULL); + } + return arg; +} + +/** + * See if the option is to be processed in the current scan direction + * (-1 or +1). + */ +static bool +direction_ok(opt_state_mask_t f, int dir) +{ + if (dir == 0) + return true; + + switch (f & (OPTST_IMM|OPTST_DISABLE_IMM)) { + case 0: + /* + * The selected option has no immediate action. + * THEREFORE, if the direction is PRESETTING + * THEN we skip this option. + */ + if (PRESETTING(dir)) + return false; + break; + + case OPTST_IMM: + if (PRESETTING(dir)) { + /* + * We are in the presetting direction with an option we handle + * immediately for enablement, but normally for disablement. + * Therefore, skip if disabled. + */ + if ((f & OPTST_DISABLED) == 0) + return false; + } else { + /* + * We are in the processing direction with an option we handle + * immediately for enablement, but normally for disablement. + * Therefore, skip if NOT disabled. + */ + if ((f & OPTST_DISABLED) != 0) + return false; + } + break; + + case OPTST_DISABLE_IMM: + if (PRESETTING(dir)) { + /* + * We are in the presetting direction with an option we handle + * immediately for disablement, but normally for handling. + * Therefore, skip if NOT disabled. + */ + if ((f & OPTST_DISABLED) != 0) + return false; + } else { + /* + * We are in the processing direction with an option we handle + * immediately for disablement, but normally for handling. + * Therefore, skip if disabled. + */ + if ((f & OPTST_DISABLED) == 0) + return false; + } + break; + + case OPTST_IMM|OPTST_DISABLE_IMM: + /* + * The selected option is always for immediate action. + * THEREFORE, if the direction is PROCESSING + * THEN we skip this option. + */ + if (PROCESSING(dir)) + return false; + break; + } + return true; +} + +/** + * Load an option from a block of text. The text must start with the + * configurable/option name and be followed by its associated value. + * That value may be processed in any of several ways. See "tOptionLoadMode" + * in autoopts.h. + * + * @param[in,out] opts program options descriptor + * @param[in,out] opt_state option processing state + * @param[in,out] line source line with long option name in it + * @param[in] direction current processing direction (preset or not) + * @param[in] load_mode option loading mode (OPTION_LOAD_*) + */ +static void +load_opt_line(tOptions * opts, tOptState * opt_state, char * line, + tDirection direction, tOptionLoadMode load_mode ) +{ + /* + * When parsing a stored line, we only look at the characters after + * a hyphen. Long names must always be at least two characters and + * short options are always exactly one character long. + */ + line = SPN_LOAD_LINE_SKIP_CHARS(line); + + { + char * arg = assemble_arg_val(line, load_mode); + + if (IS_OPTION_NAME_CHAR(line[1])) { + + if (! SUCCESSFUL(opt_find_long(opts, line, opt_state))) + return; + + } else if (! SUCCESSFUL(opt_find_short(opts, *line, opt_state))) + return; + + if ((! CALLED(direction)) && (opt_state->flags & OPTST_NO_INIT)) + return; + + opt_state->pzOptArg = trim_quotes(arg); + } + + if (! direction_ok(opt_state->flags, direction)) + return; + + /* + * Fix up the args. + */ + if (OPTST_GET_ARGTYPE(opt_state->pOD->fOptState) == OPARG_TYPE_NONE) { + if (*opt_state->pzOptArg != NUL) + return; + opt_state->pzOptArg = NULL; + + } else if (opt_state->pOD->fOptState & OPTST_ARG_OPTIONAL) { + if (*opt_state->pzOptArg == NUL) + opt_state->pzOptArg = NULL; + else { + AGDUPSTR(opt_state->pzOptArg, opt_state->pzOptArg, "opt arg"); + opt_state->flags |= OPTST_ALLOC_ARG; + } + + } else { + if (*opt_state->pzOptArg == NUL) + opt_state->pzOptArg = zNil; + else { + AGDUPSTR(opt_state->pzOptArg, opt_state->pzOptArg, "opt arg"); + opt_state->flags |= OPTST_ALLOC_ARG; + } + } + + { + tOptionLoadMode sv = option_load_mode; + option_load_mode = load_mode; + handle_opt(opts, opt_state); + option_load_mode = sv; + } +} + +/*=export_func optionLoadLine + * + * what: process a string for an option name and value + * + * arg: tOptions *, opts, program options descriptor + * arg: char const *, line, NUL-terminated text + * + * doc: + * + * This is a client program callable routine for setting options from, for + * example, the contents of a file that they read in. Only one option may + * appear in the text. It will be treated as a normal (non-preset) option. + * + * When passed a pointer to the option struct and a string, it will find + * the option named by the first token on the string and set the option + * argument to the remainder of the string. The caller must NUL terminate + * the string. The caller need not skip over any introductory hyphens. + * Any embedded new lines will be included in the option + * argument. If the input looks like one or more quoted strings, then the + * input will be "cooked". The "cooking" is identical to the string + * formation used in AutoGen definition files (@pxref{basic expression}), + * except that you may not use backquotes. + * + * err: Invalid options are silently ignored. Invalid option arguments + * will cause a warning to print, but the function should return. +=*/ +void +optionLoadLine(tOptions * opts, char const * line) +{ + tOptState st = OPTSTATE_INITIALIZER(SET); + char * pz; + proc_state_mask_t sv_flags = opts->fOptSet; + opts->fOptSet &= ~OPTPROC_ERRSTOP; + AGDUPSTR(pz, line, "opt line"); + load_opt_line(opts, &st, pz, DIRECTION_CALLED, OPTION_LOAD_COOKED); + AGFREE(pz); + opts->fOptSet = sv_flags; +} +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/load.c */ diff --git a/autoopts/makeshell.c b/autoopts/makeshell.c new file mode 100644 index 0000000..10ed120 --- /dev/null +++ b/autoopts/makeshell.c @@ -0,0 +1,918 @@ + +/** + * \file makeshell.c + * + * This module will interpret the options set in the tOptions + * structure and create a Bourne shell script capable of parsing them. + * + * @addtogroup autoopts + * @{ + */ +/* + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + + static inline unsigned char to_uchar (char ch) { return ch; } + +#define UPPER(_c) (toupper(to_uchar(_c))) +#define LOWER(_c) (tolower(to_uchar(_c))) + +noreturn static void +option_exits(int exit_code) +{ + if (print_exit) + printf("\nexit %d\n", exit_code); + exit(exit_code); +} + +noreturn static void +ao_bug(char const * msg) +{ + fprintf(stderr, zao_bug_msg, msg); + option_exits(EX_SOFTWARE); +} + +static void +fserr_warn(char const * prog, char const * op, char const * fname) +{ + fprintf(stderr, zfserr_fmt, prog, errno, strerror(errno), + op, fname); +} + +noreturn static void +fserr_exit(char const * prog, char const * op, char const * fname) +{ + fserr_warn(prog, op, fname); + option_exits(EXIT_FAILURE); +} + +/*=export_func optionParseShell + * private: + * + * what: Decipher a boolean value + * arg: + tOptions * + pOpts + program options descriptor + + * + * doc: + * Emit a shell script that will parse the command line options. +=*/ +void +optionParseShell(tOptions * opts) +{ + /* + * Check for our SHELL option now. + * IF the output file contains the "#!" magic marker, + * it will override anything we do here. + */ + if (HAVE_GENSHELL_OPT(SHELL)) + shell_prog = GENSHELL_OPT_ARG(SHELL); + + else if (! ENABLED_GENSHELL_OPT(SHELL)) + shell_prog = NULL; + + else if ((shell_prog = getenv("SHELL")), + shell_prog == NULL) + + shell_prog = POSIX_SHELL; + + /* + * Check for a specified output file + */ + if (HAVE_GENSHELL_OPT(SCRIPT)) + open_out(GENSHELL_OPT_ARG(SCRIPT), opts->pzProgName); + + emit_usage(opts); + emit_setup(opts); + + /* + * There are four modes of option processing. + */ + switch (opts->fOptSet & (OPTPROC_LONGOPT|OPTPROC_SHORTOPT)) { + case OPTPROC_LONGOPT: + fputs(LOOP_STR, stdout); + + fputs(LONG_OPT_MARK, stdout); + fputs(INIT_LOPT_STR, stdout); + emit_long(opts); + printf(LOPT_ARG_FMT, opts->pzPROGNAME); + fputs(END_OPT_SEL_STR, stdout); + + fputs(NOT_FOUND_STR, stdout); + break; + + case 0: + fputs(ONLY_OPTS_LOOP, stdout); + fputs(INIT_LOPT_STR, stdout); + emit_long(opts); + printf(LOPT_ARG_FMT, opts->pzPROGNAME); + break; + + case OPTPROC_SHORTOPT: + fputs(LOOP_STR, stdout); + + fputs(FLAG_OPT_MARK, stdout); + fputs(INIT_OPT_STR, stdout); + emit_flag(opts); + printf(OPT_ARG_FMT, opts->pzPROGNAME); + fputs(END_OPT_SEL_STR, stdout); + + fputs(NOT_FOUND_STR, stdout); + break; + + case OPTPROC_LONGOPT|OPTPROC_SHORTOPT: + fputs(LOOP_STR, stdout); + + fputs(LONG_OPT_MARK, stdout); + fputs(INIT_LOPT_STR, stdout); + emit_long(opts); + printf(LOPT_ARG_FMT, opts->pzPROGNAME); + fputs(END_OPT_SEL_STR, stdout); + + fputs(FLAG_OPT_MARK, stdout); + fputs(INIT_OPT_STR, stdout); + emit_flag(opts); + printf(OPT_ARG_FMT, opts->pzPROGNAME); + fputs(END_OPT_SEL_STR, stdout); + + fputs(NOT_FOUND_STR, stdout); + break; + } + + emit_wrapup(opts); + if ((script_trailer != NULL) && (*script_trailer != NUL)) + fputs(script_trailer, stdout); + else if (ENABLED_GENSHELL_OPT(SHELL)) + printf(SHOW_PROG_ENV, opts->pzPROGNAME); + +#ifdef HAVE_FCHMOD + fchmod(STDOUT_FILENO, 0755); +#endif + fclose(stdout); + + if (ferror(stdout)) + fserr_exit(opts->pzProgName, zwriting, zstdout_name); + + AGFREE(script_text); + script_leader = NULL; + script_trailer = NULL; + script_text = NULL; +} + +#ifdef HAVE_WORKING_FORK +/** + * Print the value of "var" to a file descriptor. + * The "fdin" is the read end of a pipe to a forked process that + * is writing usage text to it. We read that text in and re-emit + * to standard out, formatting it so that it is assigned to a + * shell variable. + * + * @param[in] prog The capitalized, c-variable-formatted program name + * @param[in] var a similarly formatted type name + * (LONGUSAGE, USAGE or VERSION) + * @param[in] fdin the input end of a pipe + */ +static void +emit_var_text(char const * prog, char const * var, int fdin) +{ + FILE * fp = fdopen(fdin, "r" FOPEN_BINARY_FLAG); + int nlct = 0; /* defer newlines and skip trailing ones */ + + printf(SET_TEXT_FMT, prog, var); + if (fp == NULL) + goto skip_text; + + for (;;) { + int ch = fgetc(fp); + switch (ch) { + + case NL: + nlct++; + break; + + case '\'': + while (nlct > 0) { + fputc(NL, stdout); + nlct--; + } + fputs(apostrophe, stdout); + break; + + case EOF: + goto done; + + default: + while (nlct > 0) { + fputc(NL, stdout); + nlct--; + } + fputc(ch, stdout); + break; + } + } done:; + + fclose(fp); + + skip_text: + + fputs(END_SET_TEXT, stdout); +} +#endif + +/** + * The purpose of this function is to assign "long usage", short usage + * and version information to a shell variable. Rather than wind our + * way through all the logic necessary to emit the text directly, we + * fork(), have our child process emit the text the normal way and + * capture the output in the parent process. + * + * @param[in] opts the program options + * @param[in] which what to print: long usage, usage or version + * @param[in] od for TT_VERSION, it is the version option + */ +static void +text_to_var(tOptions * opts, teTextTo which, tOptDesc * od) +{ +# define _TT_(n) static char const z ## n [] = #n; + TEXTTO_TABLE +# undef _TT_ +# define _TT_(n) z ## n , + static char const * ttnames[] = { TEXTTO_TABLE }; +# undef _TT_ + +#if ! defined(HAVE_WORKING_FORK) + printf(SET_NO_TEXT_FMT, opts->pzPROGNAME, ttnames[which]); +#else + int fdpair[2]; + + fflush(stdout); + fflush(stderr); + + if (pipe(fdpair) != 0) + fserr_exit(opts->pzProgName, "pipe", zinter_proc_pipe); + + switch (fork()) { + case -1: + fserr_exit(opts->pzProgName, "fork", opts->pzProgName); + /* NOTREACHED */ + + case 0: + /* + * Send both stderr and stdout to the pipe. No matter which + * descriptor is used, we capture the output on the read end. + */ + dup2(fdpair[1], STDERR_FILENO); + dup2(fdpair[1], STDOUT_FILENO); + close(fdpair[0]); + + switch (which) { + case TT_LONGUSAGE: + (*(opts->pUsageProc))(opts, EXIT_SUCCESS); + /* FALLTHROUGH */ /* NOTREACHED */ + + case TT_USAGE: + (*(opts->pUsageProc))(opts, EXIT_FAILURE); + /* FALLTHROUGH */ /* NOTREACHED */ + + case TT_VERSION: + if (od->fOptState & OPTST_ALLOC_ARG) { + AGFREE(od->optArg.argString); + od->fOptState &= ~OPTST_ALLOC_ARG; + } + od->optArg.argString = "c"; + optionPrintVersion(opts, od); + /* FALLTHROUGH */ /* NOTREACHED */ + + default: + option_exits(EXIT_FAILURE); + /* FALLTHROUGH */ /* NOTREACHED */ + } + /* FALLTHROUGH */ /* NOTREACHED */ + + default: + close(fdpair[1]); + } + + emit_var_text(opts->pzPROGNAME, ttnames[which], fdpair[0]); +#endif +} + +/** + * capture usage text in shell variables. + * + */ +static void +emit_usage(tOptions * opts) +{ + char tm_nm_buf[AO_NAME_SIZE]; + + /* + * First, switch stdout to the output file name. + * Then, change the program name to the one defined + * by the definitions (rather than the current + * executable name). Down case the upper cased name. + */ + if (script_leader != NULL) + fputs(script_leader, stdout); + + { + char const * out_nm; + + { + time_t c_tim = time(NULL); + struct tm * ptm = localtime(&c_tim); + strftime(tm_nm_buf, AO_NAME_SIZE, TIME_FMT, ptm ); + } + + if (HAVE_GENSHELL_OPT(SCRIPT)) + out_nm = GENSHELL_OPT_ARG(SCRIPT); + else out_nm = STDOUT; + + if ((script_leader == NULL) && (shell_prog != NULL)) + printf(SHELL_MAGIC, shell_prog); + + printf(PREAMBLE_FMT, START_MARK, out_nm, tm_nm_buf); + } + + printf(END_PRE_FMT, opts->pzPROGNAME); + + /* + * Get a copy of the original program name in lower case and + * fill in an approximation of the program name from it. + */ + { + char * pzPN = tm_nm_buf; + char const * pz = opts->pzPROGNAME; + char ** pp; + + /* Copy the program name into the time/name buffer */ + for (;;) { + if ((*pzPN++ = (char)tolower(*pz++)) == NUL) + break; + } + + pp = VOIDP(&(opts->pzProgPath)); + *pp = tm_nm_buf; + pp = VOIDP(&(opts->pzProgName)); + *pp = tm_nm_buf; + } + + text_to_var(opts, TT_LONGUSAGE, NULL); + text_to_var(opts, TT_USAGE, NULL); + + { + tOptDesc * pOptDesc = opts->pOptDesc; + int optionCt = opts->optCt; + + for (;;) { + if (pOptDesc->pOptProc == optionPrintVersion) { + text_to_var(opts, TT_VERSION, pOptDesc); + break; + } + + if (--optionCt <= 0) + break; + pOptDesc++; + } + } +} + +static void +emit_wrapup(tOptions * opts) +{ + tOptDesc * od = opts->pOptDesc; + int opt_ct = opts->presetOptCt; + char const * fmt; + + printf(FINISH_LOOP, opts->pzPROGNAME); + for (;opt_ct > 0; od++, --opt_ct) { + /* + * Options that are either usage documentation or are compiled out + * are not to be processed. + */ + if (SKIP_OPT(od) || (od->pz_NAME == NULL)) + continue; + + /* + * do not presence check if there is no minimum/must-set + */ + if ((od->optMinCt == 0) && ((od->fOptState & OPTST_MUST_SET) == 0)) + continue; + + if (od->optMaxCt > 1) + fmt = CHK_MIN_COUNT; + else fmt = CHK_ONE_REQUIRED; + + { + int min = (od->optMinCt == 0) ? 1 : od->optMinCt; + printf(fmt, opts->pzPROGNAME, od->pz_NAME, min); + } + } + fputs(END_MARK, stdout); +} + +static void +emit_setup(tOptions * opts) +{ + tOptDesc * od = opts->pOptDesc; + int opt_ct = opts->presetOptCt; + char const * fmt; + char const * def_val; + + for (;opt_ct > 0; od++, --opt_ct) { + char int_val_buf[32]; + + /* + * Options that are either usage documentation or are compiled out + * are not to be processed. + */ + if (SKIP_OPT(od) || (od->pz_NAME == NULL)) + continue; + + if (od->optMaxCt > 1) + fmt = MULTI_DEF_FMT; + else fmt = SGL_DEF_FMT; + + /* + * IF this is an enumeration/bitmask option, then convert the value + * to a string before printing the default value. + */ + switch (OPTST_GET_ARGTYPE(od->fOptState)) { + case OPARG_TYPE_ENUMERATION: + (*(od->pOptProc))(OPTPROC_EMIT_SHELL, od ); + def_val = od->optArg.argString; + break; + + /* + * Numeric and membership bit options are just printed as a number. + */ + case OPARG_TYPE_NUMERIC: + snprintf(int_val_buf, sizeof(int_val_buf), "%d", + (int)od->optArg.argInt); + def_val = int_val_buf; + break; + + case OPARG_TYPE_MEMBERSHIP: + snprintf(int_val_buf, sizeof(int_val_buf), "%lu", + (unsigned long)od->optArg.argIntptr); + def_val = int_val_buf; + break; + + case OPARG_TYPE_BOOLEAN: + def_val = (od->optArg.argBool) ? TRUE_STR : FALSE_STR; + break; + + default: + if (od->optArg.argString == NULL) { + if (fmt == SGL_DEF_FMT) + fmt = SGL_NO_DEF_FMT; + def_val = NULL; + } + else + def_val = od->optArg.argString; + } + + printf(fmt, opts->pzPROGNAME, od->pz_NAME, def_val); + } +} + +static void +emit_action(tOptions * opts, tOptDesc * od) +{ + if (od->pOptProc == optionPrintVersion) + printf(ECHO_N_EXIT, opts->pzPROGNAME, VER_STR); + + else if (od->pOptProc == optionPagedUsage) + printf(PAGE_USAGE_TEXT, opts->pzPROGNAME); + + else if (od->pOptProc == optionLoadOpt) { + printf(LVL3_CMD, NO_LOAD_WARN); + printf(LVL3_CMD, YES_NEED_OPT_ARG); + + } else if (od->pz_NAME == NULL) { + + if (od->pOptProc == NULL) { + printf(LVL3_CMD, NO_SAVE_OPTS); + printf(LVL3_CMD, OK_NEED_OPT_ARG); + } else + printf(ECHO_N_EXIT, opts->pzPROGNAME, LONG_USE_STR); + + } else { + if (od->optMaxCt == 1) + printf(SGL_ARG_FMT, opts->pzPROGNAME, od->pz_NAME); + else { + if ((unsigned)od->optMaxCt < NOLIMIT) + printf(CHK_MAX_COUNT, opts->pzPROGNAME, + od->pz_NAME, od->optMaxCt); + + printf(MULTI_ARG_FMT, opts->pzPROGNAME, od->pz_NAME); + } + + /* + * Fix up the args. + */ + if (OPTST_GET_ARGTYPE(od->fOptState) == OPARG_TYPE_NONE) { + printf(SET_MULTI_ARG, opts->pzPROGNAME, od->pz_NAME); + printf(LVL3_CMD, NO_ARG_NEEDED); + + } else if (od->fOptState & OPTST_ARG_OPTIONAL) { + printf(SET_MULTI_ARG, opts->pzPROGNAME, od->pz_NAME); + printf(LVL3_CMD, OK_NEED_OPT_ARG); + + } else { + printf(LVL3_CMD, YES_NEED_OPT_ARG); + } + } + fputs(zOptionEndSelect, stdout); +} + +static void +emit_inaction(tOptions * opts, tOptDesc * od) +{ + if (od->pOptProc == optionLoadOpt) { + printf(LVL3_CMD, NO_SUPPRESS_LOAD); + + } else if (od->optMaxCt == 1) + printf(NO_SGL_ARG_FMT, opts->pzPROGNAME, + od->pz_NAME, od->pz_DisablePfx); + else + printf(NO_MULTI_ARG_FMT, opts->pzPROGNAME, + od->pz_NAME, od->pz_DisablePfx); + + printf(LVL3_CMD, NO_ARG_NEEDED); + fputs(zOptionEndSelect, stdout); +} + +/** + * recognize flag options. These go at the end. + * At the end, emit code to handle options we don't recognize. + * + * @param[in] opts the program options + */ +static void +emit_flag(tOptions * opts) +{ + tOptDesc * od = opts->pOptDesc; + int opt_ct = opts->optCt; + + fputs(zOptionCase, stdout); + + for (;opt_ct > 0; od++, --opt_ct) { + + if (SKIP_OPT(od) || ! IS_GRAPHIC_CHAR(od->optValue)) + continue; + + printf(zOptionFlag, od->optValue); + emit_action(opts, od); + } + printf(UNK_OPT_FMT, FLAG_STR, opts->pzPROGNAME); +} + +/** + * Emit the match text for a long option. The passed in \a name may be + * either the enablement name or the disablement name. + * + * @param[in] name The current name to check. + * @param[in] cod current option descriptor + * @param[in] opts the program options + */ +static void +emit_match_expr(char const * name, tOptDesc * cod, tOptions * opts) +{ + char name_bf[32]; + unsigned int min_match_ct = 2; + unsigned int max_match_ct = strlen(name) - 1; + + if (max_match_ct >= sizeof(name_bf) - 1) + goto leave; + + { + tOptDesc * od = opts->pOptDesc; + int ct = opts->optCt; + + for (; ct-- > 0; od++) { + unsigned int match_ct = 0; + + /* + * Omit the current option, Doc opts and compiled out opts. + */ + if ((od == cod) || SKIP_OPT(od)) + continue; + + /* + * Check each character of the name case insensitively. + * They must not be the same. They cannot be, because it would + * not compile correctly if they were. + */ + while (UPPER(od->pz_Name[match_ct]) == UPPER(name[match_ct])) + match_ct++; + + if (match_ct > min_match_ct) + min_match_ct = match_ct; + + /* + * Check the disablement name, too. + */ + if (od->pz_DisableName == NULL) + continue; + + match_ct = 0; + while ( toupper(od->pz_DisableName[match_ct]) + == toupper(name[match_ct])) + match_ct++; + if (match_ct > min_match_ct) + min_match_ct = match_ct; + } + } + + /* + * Don't bother emitting partial matches if there is only one possible + * partial match. + */ + if (min_match_ct < max_match_ct) { + char * pz = name_bf + min_match_ct; + int nm_ix = min_match_ct; + + memcpy(name_bf, name, min_match_ct); + + for (;;) { + *pz = NUL; + printf(zOptionPartName, name_bf); + *pz++ = name[nm_ix++]; + if (name[nm_ix] == NUL) { + *pz = NUL; + break; + } + } + } + +leave: + printf(zOptionFullName, name); +} + +/** + * Emit GNU-standard long option handling code. + * + * @param[in] opts the program options + */ +static void +emit_long(tOptions * opts) +{ + tOptDesc * od = opts->pOptDesc; + int ct = opts->optCt; + + fputs(zOptionCase, stdout); + + /* + * do each option, ... + */ + do { + /* + * Documentation & compiled-out options + */ + if (SKIP_OPT(od)) + continue; + + emit_match_expr(od->pz_Name, od, opts); + emit_action(opts, od); + + /* + * Now, do the same thing for the disablement version of the option. + */ + if (od->pz_DisableName != NULL) { + emit_match_expr(od->pz_DisableName, od, opts); + emit_inaction(opts, od); + } + } while (od++, --ct > 0); + + printf(UNK_OPT_FMT, OPTION_STR, opts->pzPROGNAME); +} + +/** + * Load the previous shell script output file. We need to preserve any + * hand-edited additions outside of the START_MARK and END_MARKs. + * + * @param[in] fname the output file name + */ +static char * +load_old_output(char const * fname, char const * pname) +{ + /* + * IF we cannot stat the file, + * THEN assume we are creating a new file. + * Skip the loading of the old data. + */ + FILE * fp = fopen(fname, "r" FOPEN_BINARY_FLAG); + struct stat stbf; + char * text; + char * scan; + + if (fp == NULL) + return NULL; + + /* + * If we opened it, we should be able to stat it and it needs + * to be a regular file + */ + if ((fstat(fileno(fp), &stbf) != 0) || (! S_ISREG(stbf.st_mode))) + fserr_exit(pname, "fstat", fname); + + scan = text = AGALOC(stbf.st_size + 1, "f data"); + + /* + * Read in all the data as fast as our OS will let us. + */ + for (;;) { + size_t inct = fread(VOIDP(scan), 1, (size_t)stbf.st_size, fp); + if (inct == 0) + break; + + stbf.st_size -= (ssize_t)inct; + + if (stbf.st_size == 0) + break; + + scan += inct; + } + + *scan = NUL; + fclose(fp); + + return text; +} + +/** + * Open the specified output file. If it already exists, load its + * contents and save the non-generated (hand edited) portions. + * If a "start mark" is found, everything before it is preserved leader. + * If not, the entire thing is a trailer. Assuming the start is found, + * then everything after the end marker is the trailer. If the end + * mark is not found, the file is actually corrupt, but we take the + * remainder to be the trailer. + * + * @param[in] fname the output file name + */ +static void +open_out(char const * fname, char const * pname) +{ + + do { + char * txt = script_text = load_old_output(fname, pname); + char * scn; + + if (txt == NULL) + break; + + scn = strstr(txt, START_MARK); + if (scn == NULL) { + script_trailer = txt; + break; + } + + *(scn++) = NUL; + scn = strstr(scn, END_MARK); + if (scn == NULL) { + /* + * The file is corrupt. Set the trailer to be everything + * after the start mark. The user will need to fix it up. + */ + script_trailer = txt + strlen(txt) + START_MARK_LEN + 1; + break; + } + + /* + * Check to see if the data contains our marker. + * If it does, then we will skip over it + */ + script_trailer = scn + END_MARK_LEN; + script_leader = txt; + } while (false); + + if (freopen(fname, "w" FOPEN_BINARY_FLAG, stdout) != stdout) + fserr_exit(pname, "freopen", fname); +} + +/*=export_func genshelloptUsage + * private: + * what: The usage function for the genshellopt generated program + * + * arg: + tOptions * + opts + program options descriptor + + * arg: + int + exit_cd + usage text type to produce + + * + * doc: + * This function is used to create the usage strings for the option + * processing shell script code. Two child processes are spawned + * each emitting the usage text in either the short (error exit) + * style or the long style. The generated program will capture this + * and create shell script variables containing the two types of text. +=*/ +void +genshelloptUsage(tOptions * opts, int exit_cd) +{ +#if ! defined(HAVE_WORKING_FORK) + optionUsage(opts, exit_cd); +#else + /* + * IF not EXIT_SUCCESS, + * THEN emit the short form of usage. + */ + if (exit_cd != EXIT_SUCCESS) + optionUsage(opts, exit_cd); + fflush(stderr); + fflush(stdout); + if (ferror(stdout) || ferror(stderr)) + option_exits(EXIT_FAILURE); + + option_usage_fp = stdout; + + /* + * First, print our usage + */ + switch (fork()) { + case -1: + optionUsage(opts, EXIT_FAILURE); + /* FALLTHROUGH */ /* NOTREACHED */ + + case 0: + pagerState = PAGER_STATE_CHILD; + optionUsage(opts, EXIT_SUCCESS); + /* FALLTHROUGH */ /* NOTREACHED */ + + default: + { + int sts; + wait(&sts); + } + } + + /* + * Generate the pzProgName, since optionProcess() normally + * gets it from the command line + */ + { + char * pz; + char ** pp = VOIDP(&(optionParseShellOptions->pzProgName)); + AGDUPSTR(pz, optionParseShellOptions->pzPROGNAME, "prog name"); + *pp = pz; + while (*pz != NUL) { + *pz = (char)LOWER(*pz); + pz++; + } + } + + /* + * Separate the makeshell usage from the client usage + */ + fprintf(option_usage_fp, zGenshell, optionParseShellOptions->pzProgName); + fflush(option_usage_fp); + + /* + * Now, print the client usage. + */ + switch (fork()) { + case 0: + pagerState = PAGER_STATE_CHILD; + /*FALLTHROUGH*/ + case -1: + optionUsage(optionParseShellOptions, EXIT_FAILURE); + /* FALLTHROUGH */ /* NOTREACHED */ + + default: + { + int sts; + wait(&sts); + } + } + + fflush(stdout); + if (ferror(stdout)) + fserr_exit(opts->pzProgName, zwriting, zstdout_name); + + option_exits(EXIT_SUCCESS); +#endif +} + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/makeshell.c */ diff --git a/autoopts/mk-autoopts-pc.in b/autoopts/mk-autoopts-pc.in new file mode 100644 index 0000000..2038cfc --- /dev/null +++ b/autoopts/mk-autoopts-pc.in @@ -0,0 +1,77 @@ +#! @CONFIG_SHELL@ +## --------------------------------------------------------------------- +## mk-autoopts-pc.in -- Describe AutoOpts configuration +## +## Autoopts Copyright (C) 1992-2018 by Bruce Korb +## +## DO NOT EDIT THIS FILE (mk-autoopts-pc.in) +## +## It has been AutoGen-ed +## From the definitions aoconf.def +## and the template file aoconf.tpl +## + prefix="@prefix@" + datarootdir="@datarootdir@" + datadir="@datadir@" + package="@PACKAGE@" + includedir="@includedir@" + exec_prefix="@exec_prefix@" + bindir="@bindir@" + libdir="@libdir@" + ldopts="@AG_LDFLAGS@" + exeext="@EXEEXT@" + version="@AO_CURRENT@:@AO_REVISION@:@AO_AGE@" + dotver="@AO_CURRENT@.@AO_REVISION@.@AO_AGE@" + pkgdatadir="${datadir}/${package}" + autogen="${bindir}/autogen${exeext}" + ldflags="-L${libdir} -lopts" + libs="${ldflags}" + libsrc="${pkgdatadir}/libopts-${dotver}.tar.gz" + static_libs="${libdir}/libopts.a" + cflags="-I${includedir}" +test 'X@ENABLE_STATIC@' = Xno && static_libs='' +case "${libdir}" in +/lib | /lib64 | /usr/lib | /usr/lib64 | /usr/lib/* ) + ldopts='' + ldflags=-lopts + ;; + +* ) + ldflags="${ldopts} ${ldflags}" + ;; +esac +libs=${ldflags} +test "${includedir}" = "/usr/include" && cflags="" +PS4='+aoc=${FUNCNAME:-=}-$LINENO> ' +dirname=`dirname ${1}` +test -d ${dirname} || mkdir -p ${dirname} || exit 1 + +cat > ${1} <<- _EOF_ + # pkg-config information for AutoOpts ${dotver} + # + prefix="${prefix}" + datarootdir="${datarootdir}" + datadir="${datadir}" + package="${package}" + includedir="${includedir}" + exec_prefix="${exec_prefix}" + bindir="${bindir}" + libdir="${libdir}" + ldopts="${ldopts}" + exeext="${exeext}" + version="${version}" + dotver="${dotver}" + pkgdatadir="${pkgdatadir}" + autogen="${autogen}" + libs="${libs}" + libsrc="${libsrc}" + static_libs="${static_libs}" + + Name: AutoOpts + Description: A semi-automated generated/library option parser + URL: http://www.gnu.org/software/autogen + Version: ${dotver} + Libs: ${ldflags} + Cflags: ${cflags} + _EOF_ +## end of mk-autoopts-pc.in diff --git a/autoopts/mk-tpl-config.sh b/autoopts/mk-tpl-config.sh new file mode 100755 index 0000000..71f7de4 --- /dev/null +++ b/autoopts/mk-tpl-config.sh @@ -0,0 +1,256 @@ +#! /bin/sh + +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +prog=`basename $0 .sh` + +die() { + echo "$prog failure: $*" + kill -TERM $progpid + sleep 1 + exit 1 +} + +init() { + PS4='+tpc-${FUNCNAME:-=}-$LINENO> ' + progpid=$$ + prog=`basename $0` + progdir=`\cd \`dirname $0\` >/dev/null ; pwd` + readonly progpid progdir prog + + for d in top_srcdir srcdir top_builddir builddir + do + eval v=\${$d} + test -d "$v" || die "$d does not reference a directory" + v=`cd $v >/dev/null && pwd` + eval ${d}=${v} + done + . ${top_builddir}/config/shdefs +} + +collect_src() { + exec 8>&1 1>&2 + cd ${builddir} + sentinel_file=${1} ; shift + cat 1>&8 <<- _EOF_ + #define AUTOOPTS_INTERNAL 1 + #include "autoopts/project.h" + + #include "ao-strs.h" + static char const ao_ver_string[] = + "${AO_CURRENT}:${AO_REVISION}:${AO_AGE}\n"; + _EOF_ + + for f in "$@" + do test "X$f" = "Xproject.h" || \ + printf '#include "%s"\n' $f + done 1>&8 +} + +extension_defines() { + cd ${builddir}/tpl + + test -f tpl-config.tlib || die "tpl-config.tlib not configured" + test -f ${top_builddir}/config.h || die "config.h missing" + ${GREP:-grep} 'extension-defines' tpl-config.tlib >/dev/null && return + + txt=`sed -n '/POSIX.*SOURCE/,/does not conform to ANSI C/{ + /^#/p + } + /does not conform to ANSI C/q' ${top_builddir}/config.h` + + { + sed '/define *top-build-dir/d;/^;;;/d' tpl-config.tlib + cat <<- _EOF_ + (define top-build-dir "`cd ${top_builddir} >/dev/null + pwd`") + (define top-src-dir "`cd ${top_srcdir} >/dev/null + pwd`") + (define extension-defines + "${txt}") \\=] + _EOF_ + } > tpl-config.$$ + mv -f tpl-config.$$ tpl-config.tlib +} + +fix_scripts() { + for f in ${srcdir}/tpl/*.sh ${srcdir}/tpl/*.pl + do + d=`basename $f | sed 's/\.[sp][hl]$//'` + st=`sed 1q $f` + + case "$st" in + *perl ) echo '#!' `which perl` + sed 1d $f + ;; + + */sh ) echo '#!' ${POSIX_SHELL} + sed 1d $f + ;; + + * ) die "Invalid script type: $st" + ;; + esac > $d + chmod 755 $d + done + + for f in ${srcdir}/tpl/*.pm + do + test -f ${f##*/} && continue + cp $f ${f##*/} + chmod 644 ${f##*/} + done +} + +find_shell_prog() { + case `uname -s` in + SunOS ) + while : ; do + POSIX_SHELL=`which bash` + test -x "${POSIX_SHELL}" && break + POSIX_SHELL=/usr/xpg4/bin/sh + test -x "${POSIX_SHELL}" && break + die "You are hosed. You are on Solaris and have no usable shell." + done + ;; + esac +} + +find_cat_prog() { + while : + do + \unalias -a + unset -f command cat which + POSIX_CAT=`which cat` + test -x "$POSIX_CAT" && break + POSIX_CAT=` + PATH=\`command -p getconf CS_PATH\` + command -v cat ` + test -x "${POSIX_CAT}" && break + die "cannot locate 'cat' command" + done + + formats='man mdoc texi' + for f in $formats + do + for g in $formats + do + test -f ${f}2${g} || { + printf "#! ${POSIX_SHELL}\nexec ${POSIX_CAT} "'${1+"$@"}\n' \ + > ${f}2${g} + chmod 755 ${f}2${g} + } + done + done +} + +scan_cflags() { + libguiledir= + while test $# -gt 0 + do + case "$1" in + -I ) + test -f "$2/libguile/__scm.h" && { + libguiledir=$2 + return 0 + } + ;; + -I* ) + f=${1#-I} + test -f "$f/libguile/__scm.h" && { + libguiledir=$f + return 0 + } + ;; + esac + shift + done + + libguiledir=/usr/include + test -f $libguiledir/libguile/__scm.h && return 0 + die "The Guile header __scm.h cannot be found" +} + +find_libguiledir() { + guile_scm_h= + libguiledir=`exec 2>/dev/null ; guile-config info includedir` + + if test -d "${libguiledir}" + then + test -f ${libguiledir}/libguile.h || { + set -- ${libguiledir}/*guile*/. + if test -d "${2}" + then libguiledir=${2%/.} + elif test -d "$1" + then libguiledir=${1%/.} + fi + } + + v=`guile-config --version 2>&1 | sed 's/.* version //'` + test -d ${libguiledir}/${v%.*} && v=${v%.*} + test -d ${libguiledir}/${v} && libguiledir=${libguiledir}/$v + + else + scan_cflags $* + fi + guile_scm_h=`find ${libguiledir} -type f -name __scm.h` +} + +fix_guile() { + cd ${builddir} + find_libguiledir ${LGCFLAGS} + + list=`exec 2>/dev/null + find ${libguiledir}/libguile* -type f | \ + xargs grep -l -E '\'` + + test -z "$list" && exit 0 + + test -d libguile || mkdir libguile || { + echo "cannot make libguile directory" + exit 1 + } 1>&2 + + noret='\([^a-zA-Z0-9_]\)noreturn\([^a-zA-Z0-9_]\)' + nores='\1__noreturn__\2' + sedex="s@${noret}@${nores}@" + + echo "Patching files to remove bare 'noreturn' keyword in" \ + $list >&2 + + for f in $list + do + g=libguile${f##*/libguile} + sed "${sedex}" $f > $g + diff -u $f $g >&2 || : + done + + test -f libguile.h || cp ${libguiledir}/libguile.h . +} + +init +collect_src "$@" > ${builddir}/libopts.c +extension_defines +fix_scripts +find_shell_prog +find_cat_prog +fix_guile +touch ${sentinel_file} diff --git a/autoopts/nested.c b/autoopts/nested.c new file mode 100644 index 0000000..e760450 --- /dev/null +++ b/autoopts/nested.c @@ -0,0 +1,905 @@ + +/** + * \file nested.c + * + * Handle options with arguments that contain nested values. + * + * @addtogroup autoopts + * @{ + */ +/* + * Automated Options Nested Values module. + * + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +typedef struct { + int xml_ch; + int xml_len; + char xml_txt[8]; +} xml_xlate_t; + + static xml_xlate_t const xml_xlate[] = { + { '&', 4, "amp;" }, + { '<', 3, "lt;" }, + { '>', 3, "gt;" }, + { '"', 5, "quot;" }, + { '\'',5, "apos;" } +}; + +#ifndef ENOMSG +#define ENOMSG ENOENT +#endif + +/** + * Backslashes are used for line continuations. We keep the newline + * characters, but trim out the backslash: + */ +static void +remove_continuation(char * src) +{ + char * pzD; + + do { + while (*src == NL) src++; + pzD = strchr(src, NL); + if (pzD == NULL) + return; + + /* + * pzD has skipped at least one non-newline character and now + * points to a newline character. It now becomes the source and + * pzD goes to the previous character. + */ + src = pzD--; + if (*pzD != '\\') + pzD++; + } while (pzD == src); + + /* + * Start shifting text. + */ + for (;;) { + char ch = ((*pzD++) = *(src++)); + switch (ch) { + case NUL: return; + case '\\': + if (*src == NL) + --pzD; /* rewrite on next iteration */ + } + } +} + +/** + * Find the end of a quoted string, skipping escaped quote characters. + */ +static char const * +scan_q_str(char const * pzTxt) +{ + char q = *(pzTxt++); /* remember the type of quote */ + + for (;;) { + char ch = *(pzTxt++); + if (ch == NUL) + return pzTxt-1; + + if (ch == q) + return pzTxt; + + if (ch == '\\') { + ch = *(pzTxt++); + /* + * IF the next character is NUL, drop the backslash, too. + */ + if (ch == NUL) + return pzTxt - 2; + + /* + * IF the quote character or the escape character were escaped, + * then skip both, as long as the string does not end. + */ + if ((ch == q) || (ch == '\\')) { + if (*(pzTxt++) == NUL) + return pzTxt-1; + } + } + } +} + + +/** + * Associate a name with either a string or no value. + * + * @param[in,out] pp argument list to add to + * @param[in] name the name of the "suboption" + * @param[in] nm_len the length of the name + * @param[in] val the string value for the suboption + * @param[in] d_len the length of the value + * + * @returns the new value structure + */ +static tOptionValue * +add_string(void ** pp, char const * name, size_t nm_len, + char const * val, size_t d_len) +{ + tOptionValue * pNV; + size_t sz = nm_len + d_len + sizeof(*pNV); + + pNV = AGALOC(sz, "option name/str value pair"); + + if (val == NULL) { + pNV->valType = OPARG_TYPE_NONE; + pNV->pzName = pNV->v.strVal; + + } else { + pNV->valType = OPARG_TYPE_STRING; + if (d_len > 0) { + char const * src = val; + char * pzDst = pNV->v.strVal; + int ct = (int)d_len; + do { + int ch = *(src++) & 0xFF; + if (ch == NUL) goto data_copy_done; + if (ch == '&') + ch = get_special_char(&src, &ct); + *(pzDst++) = (char)ch; + } while (--ct > 0); + data_copy_done: + *pzDst = NUL; + + } else { + pNV->v.strVal[0] = NUL; + } + + pNV->pzName = pNV->v.strVal + d_len + 1; + } + + memcpy(pNV->pzName, name, nm_len); + pNV->pzName[ nm_len ] = NUL; + addArgListEntry(pp, pNV); + return pNV; +} + +/** + * Associate a name with a boolean value + * + * @param[in,out] pp argument list to add to + * @param[in] name the name of the "suboption" + * @param[in] nm_len the length of the name + * @param[in] val the boolean value for the suboption + * @param[in] d_len the length of the value + * + * @returns the new value structure + */ +static tOptionValue * +add_bool(void ** pp, char const * name, size_t nm_len, + char const * val, size_t d_len) +{ + size_t sz = nm_len + sizeof(tOptionValue) + 1; + tOptionValue * new_val = AGALOC(sz, "bool val"); + + /* + * Scan over whitespace is constrained by "d_len" + */ + while (IS_WHITESPACE_CHAR(*val) && (d_len > 0)) { + d_len--; val++; + } + + if (d_len == 0) + new_val->v.boolVal = 0; + + else if (IS_DEC_DIGIT_CHAR(*val)) + new_val->v.boolVal = (unsigned)atoi(val); + + else new_val->v.boolVal = ! IS_FALSE_TYPE_CHAR(*val); + + new_val->valType = OPARG_TYPE_BOOLEAN; + new_val->pzName = (char *)(new_val + 1); + memcpy(new_val->pzName, name, nm_len); + new_val->pzName[ nm_len ] = NUL; + addArgListEntry(pp, new_val); + return new_val; +} + +/** + * Associate a name with strtol() value, defaulting to zero. + * + * @param[in,out] pp argument list to add to + * @param[in] name the name of the "suboption" + * @param[in] nm_len the length of the name + * @param[in] val the numeric value for the suboption + * @param[in] d_len the length of the value + * + * @returns the new value structure + */ +static tOptionValue * +add_number(void ** pp, char const * name, size_t nm_len, + char const * val, size_t d_len) +{ + size_t sz = nm_len + sizeof(tOptionValue) + 1; + tOptionValue * new_val = AGALOC(sz, "int val"); + + /* + * Scan over whitespace is constrained by "d_len" + */ + while (IS_WHITESPACE_CHAR(*val) && (d_len > 0)) { + d_len--; val++; + } + if (d_len == 0) + new_val->v.longVal = 0; + else + new_val->v.longVal = strtol(val, 0, 0); + + new_val->valType = OPARG_TYPE_NUMERIC; + new_val->pzName = (char *)(new_val + 1); + memcpy(new_val->pzName, name, nm_len); + new_val->pzName[ nm_len ] = NUL; + addArgListEntry(pp, new_val); + return new_val; +} + +/** + * Associate a name with a nested/hierarchical value. + * + * @param[in,out] pp argument list to add to + * @param[in] name the name of the "suboption" + * @param[in] nm_len the length of the name + * @param[in] val the nested values for the suboption + * @param[in] d_len the length of the value + * + * @returns the new value structure + */ +static tOptionValue * +add_nested(void ** pp, char const * name, size_t nm_len, + char * val, size_t d_len) +{ + tOptionValue * new_val; + + if (d_len == 0) { + size_t sz = nm_len + sizeof(*new_val) + 1; + new_val = AGALOC(sz, "empty nest"); + new_val->v.nestVal = NULL; + new_val->valType = OPARG_TYPE_HIERARCHY; + new_val->pzName = (char *)(new_val + 1); + memcpy(new_val->pzName, name, nm_len); + new_val->pzName[ nm_len ] = NUL; + + } else { + new_val = optionLoadNested(val, name, nm_len); + } + + if (new_val != NULL) + addArgListEntry(pp, new_val); + + return new_val; +} + +/** + * We have an entry that starts with a name. Find the end of it, cook it + * (if called for) and create the name/value association. + */ +static char const * +scan_name(char const * name, tOptionValue * res) +{ + tOptionValue * new_val; + char const * pzScan = name+1; /* we know first char is a name char */ + char const * pzVal; + size_t nm_len = 1; + size_t d_len = 0; + + /* + * Scan over characters that name a value. These names may not end + * with a colon, but they may contain colons. + */ + pzScan = SPN_VALUE_NAME_CHARS(name + 1); + if (pzScan[-1] == ':') + pzScan--; + nm_len = (size_t)(pzScan - name); + + pzScan = SPN_HORIZ_WHITE_CHARS(pzScan); + + re_switch: + + switch (*pzScan) { + case '=': + case ':': + pzScan = SPN_HORIZ_WHITE_CHARS(pzScan + 1); + if ((*pzScan == '=') || (*pzScan == ':')) + goto default_char; + goto re_switch; + + case NL: + case ',': + pzScan++; + /* FALLTHROUGH */ + + case NUL: + add_string(&(res->v.nestVal), name, nm_len, NULL, (size_t)0); + break; + + case '"': + case '\'': + pzVal = pzScan; + pzScan = scan_q_str(pzScan); + d_len = (size_t)(pzScan - pzVal); + new_val = add_string(&(res->v.nestVal), name, nm_len, pzVal, + d_len); + if ((new_val != NULL) && (option_load_mode == OPTION_LOAD_COOKED)) + ao_string_cook(new_val->v.strVal, NULL); + break; + + default: + default_char: + /* + * We have found some strange text value. It ends with a newline + * or a comma. + */ + pzVal = pzScan; + for (;;) { + char ch = *(pzScan++); + switch (ch) { + case NUL: + pzScan--; + d_len = (size_t)(pzScan - pzVal); + goto string_done; + /* FALLTHROUGH */ + + case NL: + if ( (pzScan > pzVal + 2) + && (pzScan[-2] == '\\') + && (pzScan[ 0] != NUL)) + continue; + /* FALLTHROUGH */ + + case ',': + d_len = (size_t)(pzScan - pzVal) - 1; + string_done: + new_val = add_string(&(res->v.nestVal), name, nm_len, + pzVal, d_len); + if (new_val != NULL) + remove_continuation(new_val->v.strVal); + goto leave_scan_name; + } + } + break; + } leave_scan_name:; + + return pzScan; +} + +/** + * Some xml element that does not start with a name. + * The next character must be either '!' (introducing a comment), + * or '?' (introducing an XML meta-marker of some sort). + * We ignore these and indicate an error (NULL result) otherwise. + * + * @param[in] txt the text within an xml bracket + * @returns the address of the character after the closing marker, or NULL. + */ +static char const * +unnamed_xml(char const * txt) +{ + switch (*txt) { + default: + txt = NULL; + break; + + case '!': + txt = strstr(txt, "-->"); + if (txt != NULL) + txt += 3; + break; + + case '?': + txt = strchr(txt, '>'); + if (txt != NULL) + txt++; + break; + } + return txt; +} + +/** + * Scan off the xml element name, and the rest of the header, too. + * Set the value type to NONE if it ends with "/>". + * + * @param[in] name the first name character (alphabetic) + * @param[out] nm_len the length of the name + * @param[out] val set valType field to STRING or NONE. + * + * @returns the scan resumption point, or NULL on error + */ +static char const * +scan_xml_name(char const * name, size_t * nm_len, tOptionValue * val) +{ + char const * scan = SPN_VALUE_NAME_CHARS(name + 1); + *nm_len = (size_t)(scan - name); + if (*nm_len > 64) + return NULL; + val->valType = OPARG_TYPE_STRING; + + if (IS_WHITESPACE_CHAR(*scan)) { + /* + * There are attributes following the name. Parse 'em. + */ + scan = SPN_WHITESPACE_CHARS(scan); + scan = parse_attrs(NULL, scan, &option_load_mode, val); + if (scan == NULL) + return NULL; /* oops */ + } + + if (! IS_END_XML_TOKEN_CHAR(*scan)) + return NULL; /* oops */ + + if (*scan == '/') { + /* + * Single element XML entries get inserted as an empty string. + */ + if (*++scan != '>') + return NULL; + val->valType = OPARG_TYPE_NONE; + } + return scan+1; +} + +/** + * We've found a closing '>' without a preceding '/', thus we must search + * the text for '' where "name" is the name of the XML element. + * + * @param[in] name the start of the name in the element header + * @param[in] nm_len the length of that name + * @param[out] len the length of the value (string between header and + * the trailer/tail. + * @returns the character after the trailer, or NULL if not found. + */ +static char const * +find_end_xml(char const * src, size_t nm_len, char const * val, size_t * len) +{ + char z[72] = " 0); /* nm_len is known to be 64 or less */ + *(dst++) = '>'; + *dst = NUL; + + { + char const * res = strstr(val, z); + + if (res != NULL) { + char const * end = (option_load_mode != OPTION_LOAD_KEEP) + ? SPN_WHITESPACE_BACK(val, res) + : res; + *len = (size_t)(end - val); /* includes trailing white space */ + res = SPN_WHITESPACE_CHARS(res + (dst - z)); + } + return res; + } +} + +/** + * We've found a '<' character. We ignore this if it is a comment or a + * directive. If it is something else, then whatever it is we are looking + * at is bogus. Returning NULL stops processing. + * + * @param[in] xml_name the name of an xml bracket (usually) + * @param[in,out] res_val the option data derived from the XML element + * + * @returns the place to resume scanning input + */ +static char const * +scan_xml(char const * xml_name, tOptionValue * res_val) +{ + size_t nm_len, v_len; + char const * scan; + char const * val_str; + tOptionValue valu; + tOptionLoadMode save_mode = option_load_mode; + + if (! IS_VAR_FIRST_CHAR(*++xml_name)) + return unnamed_xml(xml_name); + + /* + * "scan_xml_name()" may change "option_load_mode". + */ + val_str = scan_xml_name(xml_name, &nm_len, &valu); + if (val_str == NULL) + goto bail_scan_xml; + + if (valu.valType == OPARG_TYPE_NONE) + scan = val_str; + else { + if (option_load_mode != OPTION_LOAD_KEEP) + val_str = SPN_WHITESPACE_CHARS(val_str); + scan = find_end_xml(xml_name, nm_len, val_str, &v_len); + if (scan == NULL) + goto bail_scan_xml; + } + + /* + * "scan" now points to where the scan is to resume after returning. + * It either points after "/>" at the end of the XML element header, + * or it points after the "" tail based on the name in the header. + */ + + switch (valu.valType) { + case OPARG_TYPE_NONE: + add_string(&(res_val->v.nestVal), xml_name, nm_len, NULL, 0); + break; + + case OPARG_TYPE_STRING: + { + tOptionValue * new_val = add_string( + &(res_val->v.nestVal), xml_name, nm_len, val_str, v_len); + + if (option_load_mode != OPTION_LOAD_KEEP) + munge_str(new_val->v.strVal, option_load_mode); + + break; + } + + case OPARG_TYPE_BOOLEAN: + add_bool(&(res_val->v.nestVal), xml_name, nm_len, val_str, v_len); + break; + + case OPARG_TYPE_NUMERIC: + add_number(&(res_val->v.nestVal), xml_name, nm_len, val_str, v_len); + break; + + case OPARG_TYPE_HIERARCHY: + { + char * pz = AGALOC(v_len+1, "h scan"); + memcpy(pz, val_str, v_len); + pz[v_len] = NUL; + add_nested(&(res_val->v.nestVal), xml_name, nm_len, pz, v_len); + AGFREE(pz); + break; + } + + case OPARG_TYPE_ENUMERATION: + case OPARG_TYPE_MEMBERSHIP: + default: + break; + } + + option_load_mode = save_mode; + return scan; + +bail_scan_xml: + option_load_mode = save_mode; + return NULL; +} + + +/** + * Deallocate a list of option arguments. This must have been gotten from + * a hierarchical option argument, not a stacked list of strings. It is + * an internal call, so it is not validated. The caller is responsible for + * knowing what they are doing. + */ +static void +unload_arg_list(tArgList * arg_list) +{ + int ct = arg_list->useCt; + char const ** pnew_val = arg_list->apzArgs; + + while (ct-- > 0) { + tOptionValue * new_val = (tOptionValue *)VOIDP(*(pnew_val++)); + if (new_val->valType == OPARG_TYPE_HIERARCHY) + unload_arg_list(new_val->v.nestVal); + AGFREE(new_val); + } + + AGFREE(arg_list); +} + +/*=export_func optionUnloadNested + * + * what: Deallocate the memory for a nested value + * arg: + tOptionValue const * + pOptVal + the hierarchical value + + * + * doc: + * A nested value needs to be deallocated. The pointer passed in should + * have been gotten from a call to @code{configFileLoad()} (See + * @pxref{libopts-configFileLoad}). +=*/ +void +optionUnloadNested(tOptionValue const * opt_val) +{ + if (opt_val == NULL) return; + if (opt_val->valType != OPARG_TYPE_HIERARCHY) { + errno = EINVAL; + return; + } + + unload_arg_list(opt_val->v.nestVal); + + AGFREE(opt_val); +} + +/** + * This is a _stable_ sort. The entries are sorted alphabetically, + * but within entries of the same name the ordering is unchanged. + * Typically, we also hope the input is sorted. + */ +static void +sort_list(tArgList * arg_list) +{ + int ix; + int lm = arg_list->useCt; + + /* + * This loop iterates "useCt" - 1 times. + */ + for (ix = 0; ++ix < lm;) { + int iy = ix-1; + tOptionValue * new_v = C(tOptionValue *, arg_list->apzArgs[ix]); + tOptionValue * old_v = C(tOptionValue *, arg_list->apzArgs[iy]); + + /* + * For as long as the new entry precedes the "old" entry, + * move the old pointer. Stop before trying to extract the + * "-1" entry. + */ + while (strcmp(old_v->pzName, new_v->pzName) > 0) { + arg_list->apzArgs[iy+1] = VOIDP(old_v); + old_v = (tOptionValue *)VOIDP(arg_list->apzArgs[--iy]); + if (iy < 0) + break; + } + + /* + * Always store the pointer. Sometimes it is redundant, + * but the redundancy is cheaper than a test and branch sequence. + */ + arg_list->apzArgs[iy+1] = VOIDP(new_v); + } +} + +/*= + * private: + * + * what: parse a hierarchical option argument + * arg: + char const * + pzTxt + the text to scan + + * arg: + char const * + pzName + the name for the text + + * arg: + size_t + nm_len + the length of "name" + + * + * ret_type: tOptionValue * + * ret_desc: An allocated, compound value structure + * + * doc: + * A block of text represents a series of values. It may be an + * entire configuration file, or it may be an argument to an + * option that takes a hierarchical value. + * + * If NULL is returned, errno will be set: + * @itemize @bullet + * @item + * @code{EINVAL} the input text was NULL. + * @item + * @code{ENOMEM} the storage structures could not be allocated + * @item + * @code{ENOMSG} no configuration values were found + * @end itemize +=*/ +static tOptionValue * +optionLoadNested(char const * text, char const * name, size_t nm_len) +{ + tOptionValue * res_val; + + /* + * Make sure we have some data and we have space to put what we find. + */ + if (text == NULL) { + errno = EINVAL; + return NULL; + } + text = SPN_WHITESPACE_CHARS(text); + if (*text == NUL) { + errno = ENOMSG; + return NULL; + } + res_val = AGALOC(sizeof(*res_val) + nm_len + 1, "nest args"); + res_val->valType = OPARG_TYPE_HIERARCHY; + res_val->pzName = (char *)(res_val + 1); + memcpy(res_val->pzName, name, nm_len); + res_val->pzName[nm_len] = NUL; + + { + tArgList * arg_list = AGALOC(sizeof(*arg_list), "nest arg l"); + + res_val->v.nestVal = arg_list; + arg_list->useCt = 0; + arg_list->allocCt = MIN_ARG_ALLOC_CT; + } + + /* + * Scan until we hit a NUL. + */ + do { + text = SPN_WHITESPACE_CHARS(text); + if (IS_VAR_FIRST_CHAR(*text)) + text = scan_name(text, res_val); + + else switch (*text) { + case NUL: + goto scan_done; + + case '<': + text = scan_xml(text, res_val); + if (text == NULL) + goto woops; + if (*text == ',') + text++; + break; + + case '#': + text = strchr(text, NL); + break; + + default: + goto woops; + } + } while (text != NULL); scan_done:; + + { + tArgList * al = res_val->v.nestVal; + if (al->useCt == 0) { + errno = ENOMSG; + goto woops; + } + if (al->useCt > 1) + sort_list(al); + } + + return res_val; + + woops: + AGFREE(res_val->v.nestVal); + AGFREE(res_val); + return NULL; +} + +/*=export_func optionNestedVal + * private: + * + * what: parse a hierarchical option argument + * arg: + tOptions * + opts + program options descriptor + + * arg: + tOptDesc * + od + the descriptor for this arg + + * + * doc: + * Nested value was found on the command line +=*/ +void +optionNestedVal(tOptions * opts, tOptDesc * od) +{ + if (opts < OPTPROC_EMIT_LIMIT) + return; + + if (od->fOptState & OPTST_RESET) { + tArgList * arg_list = od->optCookie; + int ct; + char const ** av; + + if (arg_list == NULL) + return; + ct = arg_list->useCt; + av = arg_list->apzArgs; + + while (--ct >= 0) { + void * p = VOIDP(*(av++)); + optionUnloadNested((tOptionValue const *)p); + } + + AGFREE(od->optCookie); + + } else { + tOptionValue * opt_val = optionLoadNested( + od->optArg.argString, od->pz_Name, strlen(od->pz_Name)); + + if (opt_val != NULL) + addArgListEntry(&(od->optCookie), VOIDP(opt_val)); + } +} + +/** + * get_special_char + */ +static int +get_special_char(char const ** ppz, int * ct) +{ + char const * pz = *ppz; + + if (*ct < 3) + return '&'; + + if (*pz == '#') { + int base = 10; + int retch; + + pz++; + if (*pz == 'x') { + base = 16; + pz++; + } + retch = (int)strtoul(pz, (char **)&pz, base); + if (*pz != ';') + return '&'; + base = (int)(++pz - *ppz); + if (base > *ct) + return '&'; + + *ct -= base; + *ppz = pz; + return retch; + } + + { + int ctr = sizeof(xml_xlate) / sizeof(xml_xlate[0]); + xml_xlate_t const * xlatp = xml_xlate; + + for (;;) { + if ( (*ct >= xlatp->xml_len) + && (strncmp(pz, xlatp->xml_txt, (size_t)xlatp->xml_len) == 0)) { + *ppz += xlatp->xml_len; + *ct -= xlatp->xml_len; + return xlatp->xml_ch; + } + + if (--ctr <= 0) + break; + xlatp++; + } + } + return '&'; +} + +/** + * emit_special_char + */ +static void +emit_special_char(FILE * fp, int ch) +{ + int ctr = sizeof(xml_xlate) / sizeof(xml_xlate[0]); + xml_xlate_t const * xlatp = xml_xlate; + + putc('&', fp); + for (;;) { + if (ch == xlatp->xml_ch) { + fputs(xlatp->xml_txt, fp); + return; + } + if (--ctr <= 0) + break; + xlatp++; + } + fprintf(fp, XML_HEX_BYTE_FMT, (ch & 0xFF)); +} + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/nested.c */ diff --git a/autoopts/numeric.c b/autoopts/numeric.c new file mode 100644 index 0000000..bbb43cc --- /dev/null +++ b/autoopts/numeric.c @@ -0,0 +1,180 @@ + +/** + * \file numeric.c + * + * Handle options with numeric (integer) arguments. + * + * @addtogroup autoopts + * @{ + */ +/* + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +/*=export_func optionShowRange + * private: + * + * what: Show info about range constraints + * arg: + tOptions * + pOpts + program options descriptor + + * arg: + tOptDesc * + pOptDesc + the descriptor for this arg + + * arg: + void * + rng_table + the value range tables + + * arg: + int + rng_count + the number of entries + + * + * doc: + * Show information about a numeric option with range constraints. +=*/ +void +optionShowRange(tOptions * pOpts, tOptDesc * pOD, void * rng_table, int rng_ct) +{ + const struct {long const rmin, rmax;} * rng = rng_table; + + char const * pz_indent = zTabHyp + tab_skip_ct; + + /* + * The range is shown only for full usage requests and an error + * in this particular option. + */ + if (pOpts != OPTPROC_EMIT_USAGE) { + if (pOpts <= OPTPROC_EMIT_LIMIT) + return; + pz_indent = ONE_TAB_STR; + + fprintf(option_usage_fp, zRangeErr, pOpts->pzProgName, + pOD->pz_Name, pOD->optArg.argInt); + pz_indent = ""; + } + + if (pOD->fOptState & OPTST_SCALED_NUM) + fprintf(option_usage_fp, zRangeScaled, pz_indent); + + fprintf(option_usage_fp, (rng_ct > 1) ? zRangeLie : zRangeOnly, pz_indent); + pz_indent = (pOpts != OPTPROC_EMIT_USAGE) + ? ONE_TAB_STR + : (zTabSpace + tab_skip_ct); + + for (;;) { + if (rng->rmax == LONG_MIN) + fprintf(option_usage_fp, zRangeExact, pz_indent, rng->rmin); + else if (rng->rmin == LONG_MIN) + fprintf(option_usage_fp, zRangeUpto, pz_indent, rng->rmax); + else if (rng->rmax == LONG_MAX) + fprintf(option_usage_fp, zRangeAbove, pz_indent, rng->rmin); + else + fprintf(option_usage_fp, zRange, pz_indent, rng->rmin, + rng->rmax); + + if (--rng_ct <= 0) { + fputc(NL, option_usage_fp); + break; + } + fputs(zRangeOr, option_usage_fp); + rng++; + } + + if (pOpts > OPTPROC_EMIT_LIMIT) + pOpts->pUsageProc(pOpts, EXIT_FAILURE); +} + +/*=export_func optionNumericVal + * private: + * + * what: process an option with a numeric value. + * arg: + tOptions * + opts + program options descriptor + + * arg: + tOptDesc * + od + the descriptor for this arg + + * + * doc: + * Decipher a numeric value. +=*/ +void +optionNumericVal(tOptions * opts, tOptDesc * od) +{ + char * pz; + long val; + + /* + * Guard against all the different ways this procedure might get invoked + * when there is no string argument provided. + */ + if (INQUERY_CALL(opts, od) || (od->optArg.argString == NULL)) + return; + + /* + * Numeric options may have a range associated with it. + * If it does, the usage procedure requests that it be + * emitted by passing a NULL od pointer. Also bail out + * if there is no option argument or if we are being reset. + */ + if ( (od == NULL) + || (od->optArg.argString == NULL) + || ((od->fOptState & OPTST_RESET) != 0) + || (opts <= OPTPROC_EMIT_LIMIT)) + return; + + errno = 0; + val = strtol(od->optArg.argString, &pz, 0); + if ((pz == od->optArg.argString) || (errno != 0)) + goto bad_number; + + if ((od->fOptState & OPTST_SCALED_NUM) != 0) + switch (*(pz++)) { + case NUL: pz--; break; + case 't': val *= 1000; /* FALLTHROUGH */ + case 'g': val *= 1000; /* FALLTHROUGH */ + case 'm': val *= 1000; /* FALLTHROUGH */ + case 'k': val *= 1000; break; + + case 'T': val *= 1024; /* FALLTHROUGH */ + case 'G': val *= 1024; /* FALLTHROUGH */ + case 'M': val *= 1024; /* FALLTHROUGH */ + case 'K': val *= 1024; break; + + default: goto bad_number; + } + + if (*pz != NUL) + goto bad_number; + + if (od->fOptState & OPTST_ALLOC_ARG) { + AGFREE(od->optArg.argString); + od->fOptState &= ~OPTST_ALLOC_ARG; + } + + od->optArg.argInt = val; + return; + + bad_number: + + fprintf( stderr, zNotNumber, opts->pzProgName, od->optArg.argString ); + if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0) + (*(opts->pUsageProc))(opts, EXIT_FAILURE); + + errno = EINVAL; + od->optArg.argInt = ~0; +} + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/numeric.c */ diff --git a/autoopts/option-value-type.c b/autoopts/option-value-type.c new file mode 100644 index 0000000..2bc8642 --- /dev/null +++ b/autoopts/option-value-type.c @@ -0,0 +1,156 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * DO NOT EDIT THIS FILE (stdin.c) + * + * It has been AutoGen-ed + * From the definitions stdin + * and the template file str2enum + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name ``Bruce Korb'' nor the name of any other + * contributor may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * str2enum IS PROVIDED BY Bruce Korb ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Bruce Korb OR ANY OTHER CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "option-value-type.h" +/* ANSI-C code produced by gperf version 3.1 */ +/* Command-line: gperf option-value-type.gp */ +/* Computed positions: -k'1' */ + + + +# if 0 /* gperf build options: */ +// %struct-type +// %language=ANSI-C +// %includes +// %global-table +// %omit-struct-type +// %readonly-tables +// %compare-strncmp +// +// %define slot-name vtp_name +// %define hash-function-name option_value_type_hash +// %define lookup-function-name find_option_value_type_name +// %define word-array-name option_value_type_table +// %define initializer-suffix ,VTP_COUNT_CMD +// +# endif + +#include "option-value-type.h" +typedef struct { + char const * vtp_name; + option_value_type_enum_t vtp_id; +} option_value_type_map_t; +#include + +/* maximum key range = 15, duplicates = 0 */ + +static unsigned int +option_value_type_hash (register const char *str, register size_t len) +{ + static const unsigned char asso_values[] = + { + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 0, 18, + 18, 18, 18, 18, 0, 10, 18, 5, 18, 18, + 5, 18, 18, 18, 18, 0, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18 + }; + return len + asso_values[(unsigned char)str[0]]; +} + +static const option_value_type_map_t option_value_type_table[] = + { + {"",VTP_COUNT_CMD}, {"",VTP_COUNT_CMD}, + {"",VTP_COUNT_CMD}, + {"set", VTP_CMD_SET}, + {"bool", VTP_CMD_BOOL}, + {"",VTP_COUNT_CMD}, + {"string", VTP_CMD_STRING}, + {"boolean", VTP_CMD_BOOLEAN}, + {"",VTP_COUNT_CMD}, + {"hierarchy", VTP_CMD_HIERARCHY}, + {"",VTP_COUNT_CMD}, + {"nested", VTP_CMD_NESTED}, + {"keyword", VTP_CMD_KEYWORD}, + {"",VTP_COUNT_CMD}, + {"set-membership", VTP_CMD_SET_MEMBERSHIP}, + {"",VTP_COUNT_CMD}, {"",VTP_COUNT_CMD}, + {"integer", VTP_CMD_INTEGER} + }; + +static inline const option_value_type_map_t * +find_option_value_type_name (register const char *str, register size_t len) +{ + if (len <= 14 && len >= 3) + { + register unsigned int key = (int)option_value_type_hash (str, len); + + if (key <= 17) + { + register const char *s = option_value_type_table[key].vtp_name; + + if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0') + return &option_value_type_table[key]; + } + } + return 0; +} + +/** + * Convert a command (keyword) to a option_value_type_enum_t enumeration value. + * + * @param[in] str a string that should start with a known key word. + * @param[in] len the provided length of the keyword at \a str. + * @returns the enumeration value. + * If not found, that value is VTP_INVALID_CMD. + */ +option_value_type_enum_t +find_option_value_type_cmd(char const * str, size_t len) +{ + option_value_type_map_t const * map; + + map = find_option_value_type_name(str, (unsigned int)len); + return (map == NULL) ? VTP_INVALID_CMD : map->vtp_id; +} + +/* end of option-value-type.c */ diff --git a/autoopts/option-value-type.h b/autoopts/option-value-type.h new file mode 100644 index 0000000..cf6dcaa --- /dev/null +++ b/autoopts/option-value-type.h @@ -0,0 +1,60 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * DO NOT EDIT THIS FILE (stdin.h) + * + * It has been AutoGen-ed + * From the definitions stdin + * and the template file str2enum + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name ``Bruce Korb'' nor the name of any other + * contributor may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * str2enum IS PROVIDED BY Bruce Korb ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Bruce Korb OR ANY OTHER CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Command/Keyword Dispatcher + */ +#ifndef STR2ENUM_OPTION_VALUE_TYPE_H_GUARD +#define STR2ENUM_OPTION_VALUE_TYPE_H_GUARD 1 +#include +#ifndef MISSING_INTTYPES_H +# include +#endif + +typedef enum { + VTP_INVALID_CMD = 0, + VTP_CMD_STRING = 1, + VTP_CMD_INTEGER = 2, + VTP_CMD_BOOL = 3, + VTP_CMD_BOOLEAN = 4, + VTP_CMD_KEYWORD = 5, + VTP_CMD_SET = 6, + VTP_CMD_SET_MEMBERSHIP = 7, + VTP_CMD_NESTED = 8, + VTP_CMD_HIERARCHY = 9, + VTP_COUNT_CMD +} option_value_type_enum_t; + +extern option_value_type_enum_t +find_option_value_type_cmd(char const * str, size_t len); + +#endif /* STR2ENUM_OPTION_VALUE_TYPE_H_GUARD */ +/* end of option-value-type.h */ diff --git a/autoopts/option-xat-attribute.c b/autoopts/option-xat-attribute.c new file mode 100644 index 0000000..a34ab1b --- /dev/null +++ b/autoopts/option-xat-attribute.c @@ -0,0 +1,148 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * DO NOT EDIT THIS FILE (stdin.c) + * + * It has been AutoGen-ed + * From the definitions stdin + * and the template file str2enum + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name ``Bruce Korb'' nor the name of any other + * contributor may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * str2enum IS PROVIDED BY Bruce Korb ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Bruce Korb OR ANY OTHER CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "option-xat-attribute.h" +/* ANSI-C code produced by gperf version 3.1 */ +/* Command-line: gperf option-xat-attribute.gp */ +/* Computed positions: -k'1' */ + + + +# if 0 /* gperf build options: */ +// %struct-type +// %language=ANSI-C +// %includes +// %global-table +// %omit-struct-type +// %readonly-tables +// %compare-strncmp +// +// %define slot-name xat_name +// %define hash-function-name option_xat_attribute_hash +// %define lookup-function-name find_option_xat_attribute_name +// %define word-array-name option_xat_attribute_table +// %define initializer-suffix ,XAT_COUNT_CMD +// +# endif + +#include "option-xat-attribute.h" +typedef struct { + char const * xat_name; + option_xat_attribute_enum_t xat_id; +} option_xat_attribute_map_t; +#include + +/* maximum key range = 6, duplicates = 0 */ + +static unsigned int +option_xat_attribute_hash (register const char *str, register size_t len) +{ + static const unsigned char asso_values[] = + { + 10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10, 0, + 10,10,10,10,10,10,10, 5,10, 0, + 10,10,10,10,10,10, 0, 0,10, 0, + 10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10,10,10,10,10, + 10,10,10,10,10,10 + }; + return len + asso_values[(unsigned char)str[0]]; +} + +static const option_xat_attribute_map_t option_xat_attribute_table[] = + { + {"",XAT_COUNT_CMD}, {"",XAT_COUNT_CMD}, + {"",XAT_COUNT_CMD}, {"",XAT_COUNT_CMD}, + {"type", XAT_CMD_TYPE}, + {"words", XAT_CMD_WORDS}, + {"cooked", XAT_CMD_COOKED}, + {"members", XAT_CMD_MEMBERS}, + {"uncooked", XAT_CMD_UNCOOKED}, + {"keep", XAT_CMD_KEEP} + }; + +static inline const option_xat_attribute_map_t * +find_option_xat_attribute_name (register const char *str, register size_t len) +{ + if (len <= 8 && len >= 4) + { + register unsigned int key = (int)option_xat_attribute_hash (str, len); + + if (key <= 9) + { + register const char *s = option_xat_attribute_table[key].xat_name; + + if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0') + return &option_xat_attribute_table[key]; + } + } + return 0; +} + +/** + * Convert a command (keyword) to a option_xat_attribute_enum_t enumeration value. + * + * @param[in] str a string that should start with a known key word. + * @param[in] len the provided length of the keyword at \a str. + * @returns the enumeration value. + * If not found, that value is XAT_INVALID_CMD. + */ +option_xat_attribute_enum_t +find_option_xat_attribute_cmd(char const * str, size_t len) +{ + option_xat_attribute_map_t const * map; + + map = find_option_xat_attribute_name(str, (unsigned int)len); + return (map == NULL) ? XAT_INVALID_CMD : map->xat_id; +} + +/* end of option-xat-attribute.c */ diff --git a/autoopts/option-xat-attribute.h b/autoopts/option-xat-attribute.h new file mode 100644 index 0000000..dde1617 --- /dev/null +++ b/autoopts/option-xat-attribute.h @@ -0,0 +1,57 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * DO NOT EDIT THIS FILE (stdin.h) + * + * It has been AutoGen-ed + * From the definitions stdin + * and the template file str2enum + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name ``Bruce Korb'' nor the name of any other + * contributor may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * str2enum IS PROVIDED BY Bruce Korb ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Bruce Korb OR ANY OTHER CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Command/Keyword Dispatcher + */ +#ifndef STR2ENUM_OPTION_XAT_ATTRIBUTE_H_GUARD +#define STR2ENUM_OPTION_XAT_ATTRIBUTE_H_GUARD 1 +#include +#ifndef MISSING_INTTYPES_H +# include +#endif + +typedef enum { + XAT_INVALID_CMD = 0, + XAT_CMD_TYPE = 1, + XAT_CMD_WORDS = 2, + XAT_CMD_MEMBERS = 3, + XAT_CMD_COOKED = 4, + XAT_CMD_UNCOOKED = 5, + XAT_CMD_KEEP = 6, + XAT_COUNT_CMD +} option_xat_attribute_enum_t; + +extern option_xat_attribute_enum_t +find_option_xat_attribute_cmd(char const * str, size_t len); + +#endif /* STR2ENUM_OPTION_XAT_ATTRIBUTE_H_GUARD */ +/* end of option-xat-attribute.h */ diff --git a/autoopts/optionFileLoad.3 b/autoopts/optionFileLoad.3 new file mode 100644 index 0000000..5256ea2 --- /dev/null +++ b/autoopts/optionFileLoad.3 @@ -0,0 +1,52 @@ +.TH optionFileLoad 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (optionFileLoad.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +optionFileLoad - Load the locatable config files, in order +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +int \fBoptionFileLoad\fP(tOptions * \fIopts\fP, char const * \fIprog\fP); +.sp 1 +.SH DESCRIPTION +This function looks in all the specified directories for a configuration +file ("rc" file or "ini" file) and processes any found twice. The first +time through, they are processed in reverse order (last file first). At +that time, only "immediate action" configurables are processed. For +example, if the last named file specifies not processing any more +configuration files, then no more configuration files will be processed. +Such an option in the \fBfirst\fP named directory will have no effect. + +Once the immediate action configurables have been handled, then the +directories are handled in normal, forward order. In that way, later +config files can override the settings of earlier config files. + +See the AutoOpts documentation for a thorough discussion of the +config file format. + +Configuration files not found or not decipherable are simply ignored. +.TP +.IR opts +program options descriptor +.TP +.IR prog +program name +.sp 1 +.SH RETURN VALUE +0 \-> SUCCESS, \-1 \-> FAILURE +.sp 1 +.SH ERRORS +Returns the value, "-1" if the program options descriptor +is out of date or indecipherable. Otherwise, the value "0" will +always be returned. +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +ao_string_tokenize(3), configFileLoad(3), optionFindNextValue(3), optionFindValue(3), optionFree(3), optionGetValue(3), optionLoadLine(3), optionMemberList(3), optionNextValue(3), optionOnlyUsage(3), optionPrintVersion(3), optionPrintVersionAndReturn(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), strequate(3), streqvcmp(3), streqvmap(3), strneqvcmp(3), strtransform(3), diff --git a/autoopts/optionFindNextValue.3 b/autoopts/optionFindNextValue.3 new file mode 100644 index 0000000..af529ed --- /dev/null +++ b/autoopts/optionFindNextValue.3 @@ -0,0 +1,50 @@ +.TH optionFindNextValue 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (optionFindNextValue.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +optionFindNextValue - find a hierarcicaly valued option instance +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +const tOptionValue * \fBoptionFindNextValue\fP(const tOptDesc * \fIodesc\fP, const tOptionValue * \fIpPrevVal\fP, char const * \fIname\fP, char const * \fIvalue\fP); +.sp 1 +.SH DESCRIPTION +This routine will find the next entry in a nested value option or +configurable. It will search through the list and return the next entry +that matches the criteria. +.TP +.IR odesc +an option with a nested arg type +.TP +.IR pPrevVal +the last entry +.TP +.IR name +name of value to find +.TP +.IR value +the matching value +.sp 1 +.SH RETURN VALUE +a compound value structure +.sp 1 +.SH ERRORS +The returned result is NULL and errno is set: +.sp 1ize @bullet +.sp 1 +\fBEINVAL\fP \- the \fBpOptValue\fP does not point to a valid +hierarchical option value. +.sp 1 +\fBENOENT\fP \- no entry matched the given name. +@end itemize +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +ao_string_tokenize(3), configFileLoad(3), optionFileLoad(3), optionFindValue(3), optionFree(3), optionGetValue(3), optionLoadLine(3), optionMemberList(3), optionNextValue(3), optionOnlyUsage(3), optionPrintVersion(3), optionPrintVersionAndReturn(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), strequate(3), streqvcmp(3), streqvmap(3), strneqvcmp(3), strtransform(3), diff --git a/autoopts/optionFindValue.3 b/autoopts/optionFindValue.3 new file mode 100644 index 0000000..57b57bf --- /dev/null +++ b/autoopts/optionFindValue.3 @@ -0,0 +1,46 @@ +.TH optionFindValue 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (optionFindValue.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +optionFindValue - find a hierarcicaly valued option instance +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +const tOptionValue * \fBoptionFindValue\fP(const tOptDesc * \fIodesc\fP, char const * \fIname\fP, char const * \fIval\fP); +.sp 1 +.SH DESCRIPTION +This routine will find an entry in a nested value option or configurable. +It will search through the list and return a matching entry. +.TP +.IR odesc +an option with a nested arg type +.TP +.IR name +name of value to find +.TP +.IR val +the matching value +.sp 1 +.SH RETURN VALUE +a compound value structure +.sp 1 +.SH ERRORS +The returned result is NULL and errno is set: +.sp 1ize @bullet +.sp 1 +\fBEINVAL\fP \- the \fBpOptValue\fP does not point to a valid +hierarchical option value. +.sp 1 +\fBENOENT\fP \- no entry matched the given name. +@end itemize +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +ao_string_tokenize(3), configFileLoad(3), optionFileLoad(3), optionFindNextValue(3), optionFree(3), optionGetValue(3), optionLoadLine(3), optionMemberList(3), optionNextValue(3), optionOnlyUsage(3), optionPrintVersion(3), optionPrintVersionAndReturn(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), strequate(3), streqvcmp(3), streqvmap(3), strneqvcmp(3), strtransform(3), diff --git a/autoopts/optionFree.3 b/autoopts/optionFree.3 new file mode 100644 index 0000000..b8b0f04 --- /dev/null +++ b/autoopts/optionFree.3 @@ -0,0 +1,31 @@ +.TH optionFree 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (optionFree.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +optionFree - free allocated option processing memory +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +void \fBoptionFree\fP(tOptions * \fIpOpts\fP); +.sp 1 +.SH DESCRIPTION +AutoOpts sometimes allocates memory and puts pointers to it in the +option state structures. This routine deallocates all such memory. +.TP +.IR pOpts +program options descriptor +.sp 1 +.SH ERRORS +As long as memory has not been corrupted, +this routine is always successful. +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +ao_string_tokenize(3), configFileLoad(3), optionFileLoad(3), optionFindNextValue(3), optionFindValue(3), optionGetValue(3), optionLoadLine(3), optionMemberList(3), optionNextValue(3), optionOnlyUsage(3), optionPrintVersion(3), optionPrintVersionAndReturn(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), strequate(3), streqvcmp(3), streqvmap(3), strneqvcmp(3), strtransform(3), diff --git a/autoopts/optionGetValue.3 b/autoopts/optionGetValue.3 new file mode 100644 index 0000000..01ce960 --- /dev/null +++ b/autoopts/optionGetValue.3 @@ -0,0 +1,47 @@ +.TH optionGetValue 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (optionGetValue.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +optionGetValue - get a specific value from a hierarcical list +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +const tOptionValue * \fBoptionGetValue\fP(const tOptionValue * \fIpOptValue\fP, char const * \fIvalueName\fP); +.sp 1 +.SH DESCRIPTION +This routine will find an entry in a nested value option or configurable. +If "valueName" is NULL, then the first entry is returned. Otherwise, +the first entry with a name that exactly matches the argument will be +returned. If there is no matching value, NULL is returned and errno is +set to ENOENT. If the provided option value is not a hierarchical value, +NULL is also returned and errno is set to EINVAL. +.TP +.IR pOptValue +a hierarchcal value +.TP +.IR valueName +name of value to get +.sp 1 +.SH RETURN VALUE +a compound value structure +.sp 1 +.SH ERRORS +The returned result is NULL and errno is set: +.sp 1ize @bullet +.sp 1 +\fBEINVAL\fP \- the \fBpOptValue\fP does not point to a valid +hierarchical option value. +.sp 1 +\fBENOENT\fP \- no entry matched the given name. +@end itemize +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +ao_string_tokenize(3), configFileLoad(3), optionFileLoad(3), optionFindNextValue(3), optionFindValue(3), optionFree(3), optionLoadLine(3), optionMemberList(3), optionNextValue(3), optionOnlyUsage(3), optionPrintVersion(3), optionPrintVersionAndReturn(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), strequate(3), streqvcmp(3), streqvmap(3), strneqvcmp(3), strtransform(3), diff --git a/autoopts/optionLoadLine.3 b/autoopts/optionLoadLine.3 new file mode 100644 index 0000000..caac444 --- /dev/null +++ b/autoopts/optionLoadLine.3 @@ -0,0 +1,45 @@ +.TH optionLoadLine 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (optionLoadLine.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +optionLoadLine - process a string for an option name and value +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +void \fBoptionLoadLine\fP(tOptions * \fIopts\fP, char const * \fIline\fP); +.sp 1 +.SH DESCRIPTION +This is a client program callable routine for setting options from, for +example, the contents of a file that they read in. Only one option may +appear in the text. It will be treated as a normal (non-preset) option. + +When passed a pointer to the option struct and a string, it will find +the option named by the first token on the string and set the option +argument to the remainder of the string. The caller must NUL terminate +the string. The caller need not skip over any introductory hyphens. +Any embedded new lines will be included in the option +argument. If the input looks like one or more quoted strings, then the +input will be "cooked". The "cooking" is identical to the string +formation used in AutoGen definition files (@pxref{basic expression}), +except that you may not use backquotes. +.TP +.IR opts +program options descriptor +.TP +.IR line +NUL-terminated text +.sp 1 +.SH ERRORS +Invalid options are silently ignored. Invalid option arguments +will cause a warning to print, but the function should return. +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +ao_string_tokenize(3), configFileLoad(3), optionFileLoad(3), optionFindNextValue(3), optionFindValue(3), optionFree(3), optionGetValue(3), optionMemberList(3), optionNextValue(3), optionOnlyUsage(3), optionPrintVersion(3), optionPrintVersionAndReturn(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), strequate(3), streqvcmp(3), streqvmap(3), strneqvcmp(3), strtransform(3), diff --git a/autoopts/optionMemberList.3 b/autoopts/optionMemberList.3 new file mode 100644 index 0000000..5edb666 --- /dev/null +++ b/autoopts/optionMemberList.3 @@ -0,0 +1,30 @@ +.TH optionMemberList 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (optionMemberList.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +optionMemberList - Get the list of members of a bit mask set +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +char * \fBoptionMemberList\fP(tOptDesc * \fIod\fP); +.sp 1 +.SH DESCRIPTION +This converts the OPT_VALUE_name mask value to a allocated string. +It is the caller's responsibility to free the string. +.TP +.IR od +the set membership option description +.sp 1 +.SH RETURN VALUE +the names of the set bits +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +ao_string_tokenize(3), configFileLoad(3), optionFileLoad(3), optionFindNextValue(3), optionFindValue(3), optionFree(3), optionGetValue(3), optionLoadLine(3), optionNextValue(3), optionOnlyUsage(3), optionPrintVersion(3), optionPrintVersionAndReturn(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), strequate(3), streqvcmp(3), streqvmap(3), strneqvcmp(3), strtransform(3), diff --git a/autoopts/optionNextValue.3 b/autoopts/optionNextValue.3 new file mode 100644 index 0000000..29dcca5 --- /dev/null +++ b/autoopts/optionNextValue.3 @@ -0,0 +1,47 @@ +.TH optionNextValue 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (optionNextValue.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +optionNextValue - get the next value from a hierarchical list +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +const tOptionValue * \fBoptionNextValue\fP(const tOptionValue * \fIpOptValue\fP, const tOptionValue * \fIpOldValue\fP); +.sp 1 +.SH DESCRIPTION +This routine will return the next entry after the entry passed in. At the +end of the list, NULL will be returned. If the entry is not found on the +list, NULL will be returned and "\fBerrno\fP" will be set to EINVAL. +The "\fBpOldValue\fP" must have been gotten from a prior call to this +routine or to "\fBopitonGetValue()\fP". +.TP +.IR pOptValue +a hierarchcal list value +.TP +.IR pOldValue +a value from this list +.sp 1 +.SH RETURN VALUE +a compound value structure +.sp 1 +.SH ERRORS +The returned result is NULL and errno is set: +.sp 1ize @bullet +.sp 1 +\fBEINVAL\fP \- the \fBpOptValue\fP does not point to a valid +hierarchical option value or \fBpOldValue\fP does not point to a +member of that option value. +.sp 1 +\fBENOENT\fP \- the supplied \fBpOldValue\fP pointed to the last entry. +@end itemize +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +ao_string_tokenize(3), configFileLoad(3), optionFileLoad(3), optionFindNextValue(3), optionFindValue(3), optionFree(3), optionGetValue(3), optionLoadLine(3), optionMemberList(3), optionOnlyUsage(3), optionPrintVersion(3), optionPrintVersionAndReturn(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), strequate(3), streqvcmp(3), streqvmap(3), strneqvcmp(3), strtransform(3), diff --git a/autoopts/optionOnlyUsage.3 b/autoopts/optionOnlyUsage.3 new file mode 100644 index 0000000..51307be --- /dev/null +++ b/autoopts/optionOnlyUsage.3 @@ -0,0 +1,31 @@ +.TH optionOnlyUsage 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (optionOnlyUsage.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +optionOnlyUsage - Print usage text for just the options +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +void \fBoptionOnlyUsage\fP(tOptions * \fIpOpts\fP, int \fIex_code\fP); +.sp 1 +.SH DESCRIPTION +This routine will print only the usage for each option. +This function may be used when the emitted usage must incorporate +information not available to AutoOpts. +.TP +.IR pOpts +program options descriptor +.TP +.IR ex_code +exit code for calling exit(3) +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +ao_string_tokenize(3), configFileLoad(3), optionFileLoad(3), optionFindNextValue(3), optionFindValue(3), optionFree(3), optionGetValue(3), optionLoadLine(3), optionMemberList(3), optionNextValue(3), optionPrintVersion(3), optionPrintVersionAndReturn(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), strequate(3), streqvcmp(3), streqvmap(3), strneqvcmp(3), strtransform(3), diff --git a/autoopts/optionPrintVersion.3 b/autoopts/optionPrintVersion.3 new file mode 100644 index 0000000..99dffba --- /dev/null +++ b/autoopts/optionPrintVersion.3 @@ -0,0 +1,29 @@ +.TH optionPrintVersion 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (optionPrintVersion.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +optionPrintVersion - Print the program version +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +void \fBoptionPrintVersion\fP(tOptions * \fIopts\fP, tOptDesc * \fIod\fP); +.sp 1 +.SH DESCRIPTION +This routine will print the version to stdout. +.TP +.IR opts +program options descriptor +.TP +.IR od +the descriptor for this arg +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +ao_string_tokenize(3), configFileLoad(3), optionFileLoad(3), optionFindNextValue(3), optionFindValue(3), optionFree(3), optionGetValue(3), optionLoadLine(3), optionMemberList(3), optionNextValue(3), optionOnlyUsage(3), optionPrintVersionAndReturn(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), strequate(3), streqvcmp(3), streqvmap(3), strneqvcmp(3), strtransform(3), diff --git a/autoopts/optionPrintVersionAndReturn.3 b/autoopts/optionPrintVersionAndReturn.3 new file mode 100644 index 0000000..d901af5 --- /dev/null +++ b/autoopts/optionPrintVersionAndReturn.3 @@ -0,0 +1,32 @@ +.TH optionPrintVersionAndReturn 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (optionPrintVersionAndReturn.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +optionPrintVersionAndReturn - Print the program version +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +void \fBoptionPrintVersionAndReturn\fP(tOptions * \fIopts\fP, tOptDesc * \fIod\fP); +.sp 1 +.SH DESCRIPTION +This routine will print the version to stdout and return +instead of exiting. Please see the source for the +\fBprint_ver\fP funtion for details on selecting how +verbose to be after this function returns. +.TP +.IR opts +program options descriptor +.TP +.IR od +the descriptor for this arg +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +ao_string_tokenize(3), configFileLoad(3), optionFileLoad(3), optionFindNextValue(3), optionFindValue(3), optionFree(3), optionGetValue(3), optionLoadLine(3), optionMemberList(3), optionNextValue(3), optionOnlyUsage(3), optionPrintVersion(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), strequate(3), streqvcmp(3), streqvmap(3), strneqvcmp(3), strtransform(3), diff --git a/autoopts/optionProcess.3 b/autoopts/optionProcess.3 new file mode 100644 index 0000000..3bd7495 --- /dev/null +++ b/autoopts/optionProcess.3 @@ -0,0 +1,55 @@ +.TH optionProcess 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (optionProcess.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +optionProcess - this is the main option processing routine +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +int \fBoptionProcess\fP(tOptions * \fIopts\fP, int \fIa_ct\fP, char ** \fIa_v\fP); +.sp 1 +.SH DESCRIPTION +This is the main entry point for processing options. It is intended +that this procedure be called once at the beginning of the execution of +a program. Depending on options selected earlier, it is sometimes +necessary to stop and restart option processing, or to select completely +different sets of options. This can be done easily, but you generally +do not want to do this. + +The number of arguments processed always includes the program name. +If one of the arguments is "--", then it is counted and the processing +stops. If an error was encountered and errors are to be tolerated, then +the returned value is the index of the argument causing the error. +A hyphen by itself ("-") will also cause processing to stop and will +\fInot\fP be counted among the processed arguments. A hyphen by itself +is treated as an operand. Encountering an operand stops option +processing. +.TP +.IR opts +program options descriptor +.TP +.IR a_ct +program arg count +.TP +.IR a_v +program arg vector +.sp 1 +.SH RETURN VALUE +the count of the arguments processed +.sp 1 +.SH ERRORS +Errors will cause diagnostics to be printed. \fBexit(3)\fP may +or may not be called. It depends upon whether or not the options +were generated with the "allow-errors" attribute, or if the +ERRSKIP_OPTERR or ERRSTOP_OPTERR macros were invoked. +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +ao_string_tokenize(3), configFileLoad(3), optionFileLoad(3), optionFindNextValue(3), optionFindValue(3), optionFree(3), optionGetValue(3), optionLoadLine(3), optionMemberList(3), optionNextValue(3), optionOnlyUsage(3), optionPrintVersion(3), optionPrintVersionAndReturn(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), strequate(3), streqvcmp(3), streqvmap(3), strneqvcmp(3), strtransform(3), diff --git a/autoopts/optionRestore.3 b/autoopts/optionRestore.3 new file mode 100644 index 0000000..3167d0a --- /dev/null +++ b/autoopts/optionRestore.3 @@ -0,0 +1,35 @@ +.TH optionRestore 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (optionRestore.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +optionRestore - restore option state from memory copy +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +void \fBoptionRestore\fP(tOptions * \fIpOpts\fP); +.sp 1 +.SH DESCRIPTION +Copy back the option state from saved memory. +The allocated memory is left intact, so this routine can be +called repeatedly without having to call optionSaveState again. +If you are restoring a state that was saved before the first call +to optionProcess(3AO), then you may change the contents of the +argc/argv parameters to optionProcess. +.TP +.IR pOpts +program options descriptor +.sp 1 +.SH ERRORS +If you have not called \fBoptionSaveState\fP before, a diagnostic is +printed to \fBstderr\fP and exit is called. +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +ao_string_tokenize(3), configFileLoad(3), optionFileLoad(3), optionFindNextValue(3), optionFindValue(3), optionFree(3), optionGetValue(3), optionLoadLine(3), optionMemberList(3), optionNextValue(3), optionOnlyUsage(3), optionPrintVersion(3), optionPrintVersionAndReturn(3), optionProcess(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), strequate(3), streqvcmp(3), streqvmap(3), strneqvcmp(3), strtransform(3), diff --git a/autoopts/optionSaveFile.3 b/autoopts/optionSaveFile.3 new file mode 100644 index 0000000..32e0af5 --- /dev/null +++ b/autoopts/optionSaveFile.3 @@ -0,0 +1,44 @@ +.TH optionSaveFile 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (optionSaveFile.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +optionSaveFile - saves the option state to a file +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +void \fBoptionSaveFile\fP(tOptions * \fIopts\fP); +.sp 1 +.SH DESCRIPTION +This routine will save the state of option processing to a file. The name +of that file can be specified with the argument to the \fB--save-opts\fP +option, or by appending the \fBrcfile\fP attribute to the last +\fBhomerc\fP attribute. If no \fBrcfile\fP attribute was specified, it +will default to \fB.\fIprogramname\fPrc\fP. If you wish to specify another +file, you should invoke the \fBSET_OPT_SAVE_OPTS(\fIfilename\fP)\fP macro. + +The recommend usage is as follows: +.nf + optionProcess(&progOptions, argc, argv); + if (i_want_a_non_standard_place_for_this) + SET_OPT_SAVE_OPTS("myfilename"); + optionSaveFile(&progOptions); +.fi +.TP +.IR opts +program options descriptor +.sp 1 +.SH ERRORS +If no \fBhomerc\fP file was specified, this routine will silently return +and do nothing. If the output file cannot be created or updated, a message +will be printed to \fBstderr\fP and the routine will return. +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +ao_string_tokenize(3), configFileLoad(3), optionFileLoad(3), optionFindNextValue(3), optionFindValue(3), optionFree(3), optionGetValue(3), optionLoadLine(3), optionMemberList(3), optionNextValue(3), optionOnlyUsage(3), optionPrintVersion(3), optionPrintVersionAndReturn(3), optionProcess(3), optionRestore(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), strequate(3), streqvcmp(3), streqvmap(3), strneqvcmp(3), strtransform(3), diff --git a/autoopts/optionSaveState.3 b/autoopts/optionSaveState.3 new file mode 100644 index 0000000..67ead60 --- /dev/null +++ b/autoopts/optionSaveState.3 @@ -0,0 +1,41 @@ +.TH optionSaveState 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (optionSaveState.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +optionSaveState - saves the option state to memory +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +void \fBoptionSaveState\fP(tOptions * \fIpOpts\fP); +.sp 1 +.SH DESCRIPTION +This routine will allocate enough memory to save the current option +processing state. If this routine has been called before, that memory +will be reused. You may only save one copy of the option state. This +routine may be called before optionProcess(3AO). If you do call it +before the first call to optionProcess, then you may also change the +contents of argc/argv after you call optionRestore(3AO) + +In fact, more strongly put: it is safest to only use this function +before having processed any options. In particular, the saving and +restoring of stacked string arguments and hierarchical values is +disabled. The values are not saved. +.TP +.IR pOpts +program options descriptor +.sp 1 +.SH ERRORS +If it fails to allocate the memory, +it will print a message to stderr and exit. +Otherwise, it will always succeed. +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +ao_string_tokenize(3), configFileLoad(3), optionFileLoad(3), optionFindNextValue(3), optionFindValue(3), optionFree(3), optionGetValue(3), optionLoadLine(3), optionMemberList(3), optionNextValue(3), optionOnlyUsage(3), optionPrintVersion(3), optionPrintVersionAndReturn(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionUnloadNested(3), optionVersion(3), strequate(3), streqvcmp(3), streqvmap(3), strneqvcmp(3), strtransform(3), diff --git a/autoopts/optionUnloadNested.3 b/autoopts/optionUnloadNested.3 new file mode 100644 index 0000000..fc4dc2b --- /dev/null +++ b/autoopts/optionUnloadNested.3 @@ -0,0 +1,28 @@ +.TH optionUnloadNested 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (optionUnloadNested.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +optionUnloadNested - Deallocate the memory for a nested value +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +void \fBoptionUnloadNested\fP(tOptionValue const * \fIpOptVal\fP); +.sp 1 +.SH DESCRIPTION +A nested value needs to be deallocated. The pointer passed in should +have been gotten from a call to \fBconfigFileLoad()\fP (See +@pxref{libopts-configFileLoad}). +.TP +.IR pOptVal +the hierarchical value +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +ao_string_tokenize(3), configFileLoad(3), optionFileLoad(3), optionFindNextValue(3), optionFindValue(3), optionFree(3), optionGetValue(3), optionLoadLine(3), optionMemberList(3), optionNextValue(3), optionOnlyUsage(3), optionPrintVersion(3), optionPrintVersionAndReturn(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionVersion(3), strequate(3), streqvcmp(3), streqvmap(3), strneqvcmp(3), strtransform(3), diff --git a/autoopts/optionVersion.3 b/autoopts/optionVersion.3 new file mode 100644 index 0000000..3eaa195 --- /dev/null +++ b/autoopts/optionVersion.3 @@ -0,0 +1,27 @@ +.TH optionVersion 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (optionVersion.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +optionVersion - return the compiled AutoOpts version number +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +char const * \fBoptionVersion\fP(void); +.sp 1 +.SH DESCRIPTION +Returns the full version string compiled into the library. +The returned string cannot be modified. +.sp 1 +.SH RETURN VALUE +the version string in constant memory +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +ao_string_tokenize(3), configFileLoad(3), optionFileLoad(3), optionFindNextValue(3), optionFindValue(3), optionFree(3), optionGetValue(3), optionLoadLine(3), optionMemberList(3), optionNextValue(3), optionOnlyUsage(3), optionPrintVersion(3), optionPrintVersionAndReturn(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), strequate(3), streqvcmp(3), streqvmap(3), strneqvcmp(3), strtransform(3), diff --git a/autoopts/parse-duration.c b/autoopts/parse-duration.c new file mode 100644 index 0000000..0f4a056 --- /dev/null +++ b/autoopts/parse-duration.c @@ -0,0 +1,604 @@ +/* Parse a time duration and return a seconds count + Copyright (C) 2008-2018 Free Software Foundation, Inc. + Written by Bruce Korb , 2008. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +#include + +/* Specification. */ +#include "parse-duration.h" + +#include +#include +#include +#include +#include +#include + +#include "intprops.h" + +#ifndef NUL +#define NUL '\0' +#endif + +#define cch_t char const + +typedef enum { + NOTHING_IS_DONE, + YEAR_IS_DONE, + MONTH_IS_DONE, + WEEK_IS_DONE, + DAY_IS_DONE, + HOUR_IS_DONE, + MINUTE_IS_DONE, + SECOND_IS_DONE +} whats_done_t; + +#define SEC_PER_MIN 60 +#define SEC_PER_HR (SEC_PER_MIN * 60) +#define SEC_PER_DAY (SEC_PER_HR * 24) +#define SEC_PER_WEEK (SEC_PER_DAY * 7) +#define SEC_PER_MONTH (SEC_PER_DAY * 30) +#define SEC_PER_YEAR (SEC_PER_DAY * 365) + +#undef MAX_DURATION +#define MAX_DURATION TYPE_MAXIMUM(time_t) + +/* Wrapper around strtoul that does not require a cast. */ +static unsigned long +str_const_to_ul (cch_t * str, cch_t ** ppz, int base) +{ + return strtoul (str, (char **)ppz, base); +} + +/* Wrapper around strtol that does not require a cast. */ +static long +str_const_to_l (cch_t * str, cch_t ** ppz, int base) +{ + return strtol (str, (char **)ppz, base); +} + +/* Returns BASE + VAL * SCALE, interpreting BASE = BAD_TIME + with errno set as an error situation, and returning BAD_TIME + with errno set in an error situation. */ +static time_t +scale_n_add (time_t base, time_t val, int scale) +{ + if (base == BAD_TIME) + { + if (errno == 0) + errno = EINVAL; + return BAD_TIME; + } + + if (val > MAX_DURATION / scale) + { + errno = ERANGE; + return BAD_TIME; + } + + val *= scale; + if (base > MAX_DURATION - val) + { + errno = ERANGE; + return BAD_TIME; + } + + return base + val; +} + +/* After a number HH has been parsed, parse subsequent :MM or :MM:SS. */ +static time_t +parse_hr_min_sec (time_t start, cch_t * pz) +{ + int lpct = 0; + + errno = 0; + + /* For as long as our scanner pointer points to a colon *AND* + we've not looped before, then keep looping. (two iterations max) */ + while ((*pz == ':') && (lpct++ <= 1)) + { + unsigned long v = str_const_to_ul (pz+1, &pz, 10); + + if (errno != 0) + return BAD_TIME; + + start = scale_n_add (v, start, 60); + + if (errno != 0) + return BAD_TIME; + } + + /* allow for trailing spaces */ + while (isspace ((unsigned char)*pz)) + pz++; + if (*pz != NUL) + { + errno = EINVAL; + return BAD_TIME; + } + + return start; +} + +/* Parses a value and returns BASE + value * SCALE, interpreting + BASE = BAD_TIME with errno set as an error situation, and returning + BAD_TIME with errno set in an error situation. */ +static time_t +parse_scaled_value (time_t base, cch_t ** ppz, cch_t * endp, int scale) +{ + cch_t * pz = *ppz; + time_t val; + + if (base == BAD_TIME) + return base; + + errno = 0; + val = str_const_to_ul (pz, &pz, 10); + if (errno != 0) + return BAD_TIME; + while (isspace ((unsigned char)*pz)) + pz++; + if (pz != endp) + { + errno = EINVAL; + return BAD_TIME; + } + + *ppz = pz; + return scale_n_add (base, val, scale); +} + +/* Parses the syntax YEAR-MONTH-DAY. + PS points into the string, after "YEAR", before "-MONTH-DAY". */ +static time_t +parse_year_month_day (cch_t * pz, cch_t * ps) +{ + time_t res = 0; + + res = parse_scaled_value (0, &pz, ps, SEC_PER_YEAR); + + pz++; /* over the first '-' */ + ps = strchr (pz, '-'); + if (ps == NULL) + { + errno = EINVAL; + return BAD_TIME; + } + res = parse_scaled_value (res, &pz, ps, SEC_PER_MONTH); + + pz++; /* over the second '-' */ + ps = pz + strlen (pz); + return parse_scaled_value (res, &pz, ps, SEC_PER_DAY); +} + +/* Parses the syntax YYYYMMDD. */ +static time_t +parse_yearmonthday (cch_t * in_pz) +{ + time_t res = 0; + char buf[8]; + cch_t * pz; + + if (strlen (in_pz) != 8) + { + errno = EINVAL; + return BAD_TIME; + } + + memcpy (buf, in_pz, 4); + buf[4] = NUL; + pz = buf; + res = parse_scaled_value (0, &pz, buf + 4, SEC_PER_YEAR); + + memcpy (buf, in_pz + 4, 2); + buf[2] = NUL; + pz = buf; + res = parse_scaled_value (res, &pz, buf + 2, SEC_PER_MONTH); + + memcpy (buf, in_pz + 6, 2); + buf[2] = NUL; + pz = buf; + return parse_scaled_value (res, &pz, buf + 2, SEC_PER_DAY); +} + +/* Parses the syntax yy Y mm M ww W dd D. */ +static time_t +parse_YMWD (cch_t * pz) +{ + time_t res = 0; + cch_t * ps = strchr (pz, 'Y'); + if (ps != NULL) + { + res = parse_scaled_value (0, &pz, ps, SEC_PER_YEAR); + pz++; + } + + ps = strchr (pz, 'M'); + if (ps != NULL) + { + res = parse_scaled_value (res, &pz, ps, SEC_PER_MONTH); + pz++; + } + + ps = strchr (pz, 'W'); + if (ps != NULL) + { + res = parse_scaled_value (res, &pz, ps, SEC_PER_WEEK); + pz++; + } + + ps = strchr (pz, 'D'); + if (ps != NULL) + { + res = parse_scaled_value (res, &pz, ps, SEC_PER_DAY); + pz++; + } + + while (isspace ((unsigned char)*pz)) + pz++; + if (*pz != NUL) + { + errno = EINVAL; + return BAD_TIME; + } + + return res; +} + +/* Parses the syntax HH:MM:SS. + PS points into the string, after "HH", before ":MM:SS". */ +static time_t +parse_hour_minute_second (cch_t * pz, cch_t * ps) +{ + time_t res = 0; + + res = parse_scaled_value (0, &pz, ps, SEC_PER_HR); + + pz++; + ps = strchr (pz, ':'); + if (ps == NULL) + { + errno = EINVAL; + return BAD_TIME; + } + + res = parse_scaled_value (res, &pz, ps, SEC_PER_MIN); + + pz++; + ps = pz + strlen (pz); + return parse_scaled_value (res, &pz, ps, 1); +} + +/* Parses the syntax HHMMSS. */ +static time_t +parse_hourminutesecond (cch_t * in_pz) +{ + time_t res = 0; + char buf[4]; + cch_t * pz; + + if (strlen (in_pz) != 6) + { + errno = EINVAL; + return BAD_TIME; + } + + memcpy (buf, in_pz, 2); + buf[2] = NUL; + pz = buf; + res = parse_scaled_value (0, &pz, buf + 2, SEC_PER_HR); + + memcpy (buf, in_pz + 2, 2); + buf[2] = NUL; + pz = buf; + res = parse_scaled_value (res, &pz, buf + 2, SEC_PER_MIN); + + memcpy (buf, in_pz + 4, 2); + buf[2] = NUL; + pz = buf; + return parse_scaled_value (res, &pz, buf + 2, 1); +} + +/* Parses the syntax hh H mm M ss S. */ +static time_t +parse_HMS (cch_t * pz) +{ + time_t res = 0; + cch_t * ps = strchr (pz, 'H'); + if (ps != NULL) + { + res = parse_scaled_value (0, &pz, ps, SEC_PER_HR); + pz++; + } + + ps = strchr (pz, 'M'); + if (ps != NULL) + { + res = parse_scaled_value (res, &pz, ps, SEC_PER_MIN); + pz++; + } + + ps = strchr (pz, 'S'); + if (ps != NULL) + { + res = parse_scaled_value (res, &pz, ps, 1); + pz++; + } + + while (isspace ((unsigned char)*pz)) + pz++; + if (*pz != NUL) + { + errno = EINVAL; + return BAD_TIME; + } + + return res; +} + +/* Parses a time (hours, minutes, seconds) specification in either syntax. */ +static time_t +parse_time (cch_t * pz) +{ + cch_t * ps; + time_t res = 0; + + /* + * Scan for a hyphen + */ + ps = strchr (pz, ':'); + if (ps != NULL) + { + res = parse_hour_minute_second (pz, ps); + } + + /* + * Try for a 'H', 'M' or 'S' suffix + */ + else if (ps = strpbrk (pz, "HMS"), + ps == NULL) + { + /* Its a YYYYMMDD format: */ + res = parse_hourminutesecond (pz); + } + + else + res = parse_HMS (pz); + + return res; +} + +/* Returns a substring of the given string, with spaces at the beginning and at + the end destructively removed, per SNOBOL. */ +static char * +trim (char * pz) +{ + /* trim leading white space */ + while (isspace ((unsigned char)*pz)) + pz++; + + /* trim trailing white space */ + { + char * pe = pz + strlen (pz); + while ((pe > pz) && isspace ((unsigned char)pe[-1])) + pe--; + *pe = NUL; + } + + return pz; +} + +/* + * Parse the year/months/days of a time period + */ +static time_t +parse_period (cch_t * in_pz) +{ + char * pT; + char * ps; + char * pz = strdup (in_pz); + void * fptr = pz; + time_t res = 0; + + if (pz == NULL) + { + errno = ENOMEM; + return BAD_TIME; + } + + pT = strchr (pz, 'T'); + if (pT != NULL) + { + *(pT++) = NUL; + pz = trim (pz); + pT = trim (pT); + } + + /* + * Scan for a hyphen + */ + ps = strchr (pz, '-'); + if (ps != NULL) + { + res = parse_year_month_day (pz, ps); + } + + /* + * Try for a 'Y', 'M' or 'D' suffix + */ + else if (ps = strpbrk (pz, "YMWD"), + ps == NULL) + { + /* Its a YYYYMMDD format: */ + res = parse_yearmonthday (pz); + } + + else + res = parse_YMWD (pz); + + if ((errno == 0) && (pT != NULL)) + { + time_t val = parse_time (pT); + res = scale_n_add (res, val, 1); + } + + free (fptr); + return res; +} + +static time_t +parse_non_iso8601 (cch_t * pz) +{ + whats_done_t whatd_we_do = NOTHING_IS_DONE; + + time_t res = 0; + + do { + time_t val; + + errno = 0; + val = str_const_to_l (pz, &pz, 10); + if (errno != 0) + goto bad_time; + + /* IF we find a colon, then we're going to have a seconds value. + We will not loop here any more. We cannot already have parsed + a minute value and if we've parsed an hour value, then the result + value has to be less than an hour. */ + if (*pz == ':') + { + if (whatd_we_do >= MINUTE_IS_DONE) + break; + + val = parse_hr_min_sec (val, pz); + + if ((whatd_we_do == HOUR_IS_DONE) && (val >= SEC_PER_HR)) + break; + + return scale_n_add (res, val, 1); + } + + { + unsigned int mult; + + /* Skip over white space following the number we just parsed. */ + while (isspace ((unsigned char)*pz)) + pz++; + + switch (*pz) + { + default: goto bad_time; + case NUL: + return scale_n_add (res, val, 1); + + case 'y': case 'Y': + if (whatd_we_do >= YEAR_IS_DONE) + goto bad_time; + mult = SEC_PER_YEAR; + whatd_we_do = YEAR_IS_DONE; + break; + + case 'M': + if (whatd_we_do >= MONTH_IS_DONE) + goto bad_time; + mult = SEC_PER_MONTH; + whatd_we_do = MONTH_IS_DONE; + break; + + case 'W': + if (whatd_we_do >= WEEK_IS_DONE) + goto bad_time; + mult = SEC_PER_WEEK; + whatd_we_do = WEEK_IS_DONE; + break; + + case 'd': case 'D': + if (whatd_we_do >= DAY_IS_DONE) + goto bad_time; + mult = SEC_PER_DAY; + whatd_we_do = DAY_IS_DONE; + break; + + case 'h': + if (whatd_we_do >= HOUR_IS_DONE) + goto bad_time; + mult = SEC_PER_HR; + whatd_we_do = HOUR_IS_DONE; + break; + + case 'm': + if (whatd_we_do >= MINUTE_IS_DONE) + goto bad_time; + mult = SEC_PER_MIN; + whatd_we_do = MINUTE_IS_DONE; + break; + + case 's': + mult = 1; + whatd_we_do = SECOND_IS_DONE; + break; + } + + res = scale_n_add (res, val, mult); + + pz++; + while (isspace ((unsigned char)*pz)) + pz++; + if (*pz == NUL) + return res; + + if (! isdigit ((unsigned char)*pz)) + break; + } + + } while (whatd_we_do < SECOND_IS_DONE); + + bad_time: + errno = EINVAL; + return BAD_TIME; +} + +time_t +parse_duration (char const * pz) +{ + while (isspace ((unsigned char)*pz)) + pz++; + + switch (*pz) + { + case 'P': + return parse_period (pz + 1); + + case 'T': + return parse_time (pz + 1); + + default: + if (isdigit ((unsigned char)*pz)) + return parse_non_iso8601 (pz); + + errno = EINVAL; + return BAD_TIME; + } +} + +/* + * Local Variables: + * mode: C + * c-file-style: "gnu" + * indent-tabs-mode: nil + * End: + * end of parse-duration.c */ diff --git a/autoopts/parse-duration.h b/autoopts/parse-duration.h new file mode 100644 index 0000000..9a7bcd5 --- /dev/null +++ b/autoopts/parse-duration.h @@ -0,0 +1,90 @@ +/* Parse a time duration and return a seconds count + Copyright (C) 2008-2018 Free Software Foundation, Inc. + Written by Bruce Korb , 2008. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . */ + +/* + + Readers and users of this function are referred to the ISO-8601 + specification, with particular attention to "Durations". + + At the time of writing, this worked: + + https://en.wikipedia.org/wiki/ISO_8601#Durations + + The string must start with a 'P', 'T' or a digit. + + ==== if it is a digit + + the string may contain: NNN Y NNN M NNN W NNN d NNN h NNN m NNN s + This represents NNN years, NNN months, NNN weeks, NNN days, NNN hours, + NNN minutes and NNN seconds. + The embedded white space is optional. + These terms must appear in this order. + Case is significant: 'M' is months and 'm' is minutes. + The final "s" is optional. + All of the terms ("NNN" plus designator) are optional. + Minutes and seconds may optionally be represented as NNN:NNN. + Also, hours, minute and seconds may be represented as NNN:NNN:NNN. + There is no limitation on the value of any of the terms, except + that the final result must fit in a time_t value. + + ==== if it is a 'P' or 'T', please see ISO-8601 for a rigorous definition. + + The 'P' term may be followed by any of three formats: + yyyymmdd + yy-mm-dd + yy Y mm M ww W dd D + + or it may be empty and followed by a 'T'. The "yyyymmdd" must be eight + digits long. + + NOTE! Months are always 30 days and years are always 365 days long. + 5 years is always 1825 days, not 1826 or 1827 depending on leap year + considerations. 3 months is always 90 days. There is no consideration + for how many days are in the current, next or previous months. + + For the final format: + * Embedded white space is allowed, but it is optional. + * All of the terms are optional. Any or all-but-one may be omitted. + * The meanings are yy years, mm months, ww weeks and dd days. + * The terms must appear in this order. + + ==== The 'T' term may be followed by any of these formats: + + hhmmss + hh:mm:ss + hh H mm M ss S + + For the final format: + * Embedded white space is allowed, but it is optional. + * All of the terms are optional. Any or all-but-one may be omitted. + * The terms must appear in this order. + + */ +#ifndef GNULIB_PARSE_DURATION_H +#define GNULIB_PARSE_DURATION_H + +#include + +/* Return value when a valid duration cannot be parsed. */ +#define BAD_TIME ((time_t)~0) + +/* Parses the given string. If it has the syntax of a valid duration, + this duration is returned. Otherwise, the return value is BAD_TIME, + and errno is set to either EINVAL (bad syntax) or ERANGE (out of range). */ +extern time_t parse_duration (char const * in_pz); + +#endif /* GNULIB_PARSE_DURATION_H */ diff --git a/autoopts/pgusage.c b/autoopts/pgusage.c new file mode 100644 index 0000000..f895b3b --- /dev/null +++ b/autoopts/pgusage.c @@ -0,0 +1,187 @@ + +/** + * \file pgusage.c + * + * Automated Options Paged Usage module. + * + * @addtogroup autoopts + * @{ + */ +/* + * This routine will run run-on options through a pager so the + * user may examine, print or edit them at their leisure. + * + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +#if defined(HAVE_WORKING_FORK) +static inline FILE * +open_tmp_usage(char ** buf) +{ + char * bf; + size_t bfsz; + + { + unsigned int my_pid = (unsigned int)getpid(); + char const * tmpdir = getenv(TMPDIR); + if (tmpdir == NULL) + tmpdir = tmp_dir; + bfsz = TMP_FILE_FMT_LEN + strlen(tmpdir) + 10; + bf = AGALOC(bfsz, "tmp fil"); + snprintf(bf, bfsz, TMP_FILE_FMT, tmpdir, my_pid); + } + + { + static mode_t const cmask = S_IRWXO | S_IRWXG; + mode_t svmsk = umask(cmask); + int fd = mkstemp(bf); + (void)umask(svmsk); + + if (fd < 0) { + AGFREE(bf); + return NULL; + } + *buf = bf; + return fdopen(fd, "w"); + } +} + +static inline char * +mk_pager_cmd(char const * fname) +{ + /* + * Page the file and remove it when done. For shell script processing, + * we must redirect the output to the current stderr, otherwise stdout. + */ + fclose(option_usage_fp); + option_usage_fp = NULL; + + { + char const * pager = (char const *)getenv(PAGER_NAME); + size_t bfsz; + char * res; + + /* + * Use the "more(1)" program if "PAGER" has not been defined + */ + if (pager == NULL) + pager = MORE_STR; + + bfsz = 2 * strlen(fname) + strlen(pager) + PAGE_USAGE_FMT_LEN; + res = AGALOC(bfsz, "more cmd"); + snprintf(res, bfsz, PAGE_USAGE_FMT, pager, fname); + AGFREE(fname); + return res; + } +} +#endif + +/*=export_func optionPagedUsage + * private: + * + * what: emit help text and pass through a pager program. + * arg: + tOptions * + opts + program options descriptor + + * arg: + tOptDesc * + od + the descriptor for this arg + + * + * doc: + * Run the usage output through a pager. + * This is very handy if it is very long. + * This is disabled on platforms without a working fork() function. +=*/ +void +optionPagedUsage(tOptions * opts, tOptDesc * od) +{ +#if ! defined(HAVE_WORKING_FORK) + if ((od->fOptState & OPTST_RESET) != 0) + return; + + (*opts->pUsageProc)(opts, EXIT_SUCCESS); +#else + static bool sv_print_exit = false; + static char * fil_name = NULL; + + /* + * IF we are being called after the usage proc is done + * (and thus has called "exit(2)") + * THEN invoke the pager to page through the usage file we created. + */ + switch (pagerState) { + case PAGER_STATE_INITIAL: + { + if ((od->fOptState & OPTST_RESET) != 0) + return; + option_usage_fp = open_tmp_usage(&fil_name); + if (option_usage_fp == NULL) + (*opts->pUsageProc)(opts, EXIT_SUCCESS); + + pagerState = PAGER_STATE_READY; + sv_print_exit = print_exit; + + /* + * Set up so this routine gets called during the exit logic + */ + atexit((void(*)(void))optionPagedUsage); + + /* + * The usage procedure will now put the usage information into + * the temporary file we created above. Keep any shell commands + * out of the result. + */ + print_exit = false; + (*opts->pUsageProc)(opts, EXIT_SUCCESS); + + /* NOTREACHED */ + _exit(EXIT_FAILURE); + } + + case PAGER_STATE_READY: + fil_name = mk_pager_cmd(fil_name); + + if (sv_print_exit) { + fputs("\nexit 0\n", stdout); + fclose(stdout); + dup2(STDERR_FILENO, STDOUT_FILENO); + + } else { + fclose(stderr); + dup2(STDOUT_FILENO, STDERR_FILENO); + } + + ignore_val( system( fil_name)); + AGFREE(fil_name); + + case PAGER_STATE_CHILD: + /* + * This is a child process used in creating shell script usage. + */ + break; + } +#endif +} + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/pgusage.c */ diff --git a/autoopts/po/usage-txt.pot b/autoopts/po/usage-txt.pot new file mode 100644 index 0000000..009f9c7 --- /dev/null +++ b/autoopts/po/usage-txt.pot @@ -0,0 +1,353 @@ +# Automated Option parsing usage text. +# Copyright (C) 1999-2018 by Bruce Korb - all rights reserved +# This file is distributed under the same licenses as the AutoOpts package. +# Bruce Korb +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: autogen \n" +"Report-Msgid-Bugs-To: autogen-users@lists.sourceforge.net\n" +"POT-Creation-Date: 2018-08-26 10:44-0700\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../autoopts.c:67 ../autoopts.c:89 +msgid "allocation of %d bytes failed\n" + +#: ../init.c:48 +msgid "AutoOpts function called without option descriptor\n" + +#: ../init.c:81 +msgid "\tThis exceeds the compiled library version: " + +#: ../init.c:79 +msgid "Automated Options Processing Error!\n" + "\t%s called AutoOpts function with structure version %d:%d:%d.\n" + +#: ../autoopts.c:78 +msgid "realloc of %d bytes at 0x%p failed\n" + +#: ../init.c:83 +msgid "\tThis is less than the minimum library version: " + +#: ../version.c:121 +msgid "Automated Options version %s\n" + "\tCopyright (C) 1999-2017 by Bruce Korb - all rights reserved\n" + +#: ../makeshell.c:49 +msgid "(AutoOpts bug): %s.\n" + +#: ../reset.c:90 +msgid "optionResetOpt() called, but reset-option not configured" + +#: ../usage.c:241 +msgid "could not locate the 'help' option" + +#: ../autoopts.c:330 +msgid "optionProcess() was called with invalid data" + +#: ../usage.c:697 +msgid "invalid argument type specified" + +#: ../find.c:568 +msgid "defaulted to option with optional arg" + +#: ../alias.c:76 +msgid "aliasing option is out of range." + +#: ../enum.c:210 +msgid "%s error: the keyword '%s' is ambiguous for %s\n" + +#: ../find.c:78 +msgid " The following options match:\n" + +#: ../find.c:263 +msgid "%s: ambiguous option name: %s (matches %d options)\n" + +#: ../check.c:161 +msgid "%s: Command line arguments required\n" + +#: ../alias.c:43 +msgid "%d %s%s options allowed\n" + +#: ../makeshell.c:56 +msgid "%s error %d (%s) calling %s for '%s'\n" + +#: ../makeshell.c:268 +msgid "interprocess pipe" + +#: ../version.c:171 +msgid "error: version option argument '%c' invalid. Use:\n" + "\t'v' - version only\n" + "\t'c' - version and copyright\n" + "\t'n' - version and full copyright notice\n" + +#: ../check.c:58 +msgid "%s error: the '%s' and '%s' options conflict\n" + +#: ../find.c:187 ../find.c:400 +msgid "%s: The '%s' option has been disabled." + +#: ../alias.c:38 +msgid "-equivalence" + +#: ../usage.c:1203 ../usage.c:1217 +msgid "=T/F" + +#: ../usage.c:1199 ../usage.c:1217 +msgid "=KWd" + +#: ../usage.c:1198 ../usage.c:1217 +msgid "=num" + +#: ../usage.c:1196 ../usage.c:1217 +msgid "=str" + +#: ../find.c:439 ../reset.c:110 +msgid "%s: illegal option -- %c\n" + +#: ../find.c:241 ../find.c:740 ../reset.c:118 +msgid "%s: illegal option -- %s\n" + +#: ../find.c:305 +msgid "%s: unknown vendor extension option -- %s\n" + +#: ../enum.c:135 ../enum.c:145 +msgid " or an integer from %d through %d\n" + +#: ../usage.c:696 ../usage.c:1030 +msgid "%s error: invalid option descriptor for %s\n" + +#: ../find.c:355 +msgid "%s: invalid option name: %s\n" + +#: ../find.c:497 +msgid "%s: The '%s' option requires an argument.\n" + +#: ../autoopts.c:150 +msgid "(AutoOpts bug): Equivalenced option '%s' was equivalenced to both\n" + "\t'%s' and '%s'." + +#: ../check.c:94 +msgid "%s error: The %s option is required\n" + +#: ../find.c:602 +msgid "%s: The '%s' option cannot have an argument.\n" + +#: ../check.c:151 +msgid "%s: Command line arguments are not allowed.\n" + +#: ../save.c:568 +msgid "error %d (%s) creating %s\n" + +#: ../enum.c:210 +msgid "%s error: '%s' does not match any %s keywords.\n" + +#: ../reset.c:93 +msgid "%s error: The '%s' option requires an argument.\n" + +#: ../save.c:122 ../save.c:175 +msgid "error %d (%s) stat-ing %s\n" + +#: ../restore.c:143 +msgid "%s error: no saved option state\n" + +#: ../autoopts.c:225 +msgid "'%s' is not a command line option.\n" + +#: ../time.c:113 +msgid "%s error: '%s' is not a recognizable date/time.\n" + +#: ../time.c:50 +msgid "%s error: '%s' is not a recognizable time duration.\n" + +#: ../check.c:92 +msgid "%s error: The %s option must appear %d times.\n" + +#: ../numeric.c:165 +msgid "%s error: '%s' is not a recognizable number.\n" + +#: ../enum.c:176 +msgid "%s error: %s exceeds %s keyword count\n" + +#: ../usage.c:279 +msgid "Try '%s %s' for more information.\n" + +#: ../alias.c:45 +msgid "one %s%s option allowed\n" + +#: ../makeshell.c:170 ../makeshell.c:905 ../usage.c:223 ../usage.c:364 ../usage.c:574 ../version.c:178 +msgid "standard output" + +#: ../usage.c:223 ../usage.c:364 ../usage.c:574 ../version.c:178 +msgid "standard error" + +#: ../makeshell.c:170 ../makeshell.c:905 ../usage.c:222 ../usage.c:363 ../usage.c:573 ../version.c:177 +msgid "write" + +#: ../numeric.c:60 +msgid "%s error: %s option value %ld is out of range.\n" + +#: ../check.c:44 +msgid "%s error: %s option requires the %s option\n" + +#: ../save.c:121 ../save.c:174 ../save.c:193 ../save.c:567 +msgid "%s warning: cannot save options - %s not regular file\n" + +#: ../usage.c:822 +msgid "\t\t\t\t- an alternate for '%s'\n" + +#: ../usage.c:1097 +msgid "Version, usage and configuration options:" + +#: ../usage.c:873 +msgid "\t\t\t\t- default option for unnamed options\n" + +#: ../usage.c:786 +msgid "\t\t\t\t- disabled as '--%s'\n" + +#: ../usage.c:1066 +msgid " --- %-14s %s\n" + +#: ../usage.c:1064 +msgid "This option has been disabled" + +#: ../usage.c:813 +msgid "\t\t\t\t- enabled by default\n" + +#: ../alias.c:40 +msgid "%s error: only " + +#: ../usage.c:1143 +msgid " - examining environment variables named %s_*\n" + +#: ../file.c:168 +msgid "\t\t\t\t- file must not pre-exist\n" + +#: ../file.c:172 +msgid "\t\t\t\t- file must pre-exist\n" + +#: ../usage.c:329 +msgid "Options are specified by doubled hyphens and their name or by a single\n" + "hyphen and the flag character.\n" + +#: ../makeshell.c:882 +msgid "\n" + "= = = = = = = =\n\n" + "This incarnation of genshell will produce\n" + "a shell script to parse the options for %s:\n\n" + +#: ../enum.c:142 +msgid " or an integer mask with any of the lower %d bits set\n" + +#: ../usage.c:846 +msgid "\t\t\t\t- is a set membership option\n" + +#: ../usage.c:867 +msgid "\t\t\t\t- must appear between %d and %d times\n" + +#: ../usage.c:331 +msgid "Options are specified by single or double hyphens and their name.\n" + +#: ../usage.c:853 +msgid "\t\t\t\t- may appear multiple times\n" + +#: ../usage.c:840 +msgid "\t\t\t\t- may not be preset\n" + +#: ../usage.c:1258 +msgid " Arg Option-Name Description\n" + +#: ../usage.c:1194 ../usage.c:1252 +msgid " Flg Arg Option-Name Description\n" + +#: ../usage.c:1253 ../usage.c:1259 +msgid " %3s %s" + +#: ../usage.c:336 +msgid "The '-#' option may omit the hash char\n" + +#: ../usage.c:332 +msgid "All arguments are named options.\n" + +#: ../usage.c:920 +msgid " - reading file %s" + +#: ../usage.c:358 ../version.c:100 ../version.c:129 +msgid "\n" + "Please send bug reports to: <%s>\n" + +#: ../usage.c:852 +msgid "\t\t\t\t- may NOT appear - preset only\n" + +#: ../usage.c:893 ../usage.c:1141 +msgid "\n" + "The following option preset mechanisms are supported:\n" + +#: ../usage.c:631 +msgid "prohibits these options:\n" + +#: ../usage.c:626 +msgid "prohibits the option '%s'\n" + +#: ../numeric.c:81 +msgid "%s%ld to %ld" + +#: ../numeric.c:79 +msgid "%sgreater than or equal to %ld" + +#: ../numeric.c:75 +msgid "%s%ld exactly" + +#: ../numeric.c:68 +msgid "%sit must lie in one of the ranges:\n" + +#: ../numeric.c:68 +msgid "%sit must be in the range:\n" + +#: ../numeric.c:88 +msgid ", or\n" + +#: ../numeric.c:66 +msgid "%sis scalable with a suffix: k/K/m/M/g/G/t/T\n" + +#: ../numeric.c:77 +msgid "%sless than or equal to %ld" + +#: ../usage.c:339 +msgid "Operands and options may be intermixed. They will be reordered.\n" + +#: ../usage.c:601 +msgid "requires the option '%s'\n" + +#: ../usage.c:604 +msgid "requires these options:\n" + +#: ../usage.c:1270 +msgid " Arg Option-Name Req? Description\n" + +#: ../usage.c:1264 +msgid " Flg Arg Option-Name Req? Description\n" + +#: ../enum.c:143 +msgid "or you may use a numeric representation. Preceding these with a '!'\n" + "will clear the bits, specifying 'none' will clear all bits, and 'all'\n" + "will set them all. Multiple entries may be passed as an option\n" + "argument list.\n" + +#: ../usage.c:859 +msgid "\t\t\t\t- may appear up to %d times\n" + +#: ../enum.c:52 +msgid "The valid \"%s\" option keywords are:\n" + +#: ../usage.c:1101 +msgid "The next option supports vendor supported extra options:" + +#: ../usage.c:722 +msgid "These additional options are:" \ No newline at end of file diff --git a/autoopts/project.h b/autoopts/project.h new file mode 100644 index 0000000..1f196ef --- /dev/null +++ b/autoopts/project.h @@ -0,0 +1,81 @@ + +/** + * \file project.h + * + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +#ifndef AUTOGEN_PROJECT_H +#define AUTOGEN_PROJECT_H + +#include "config.h" +#include "compat/compat.h" +#include "ag-char-map.h" + +/* + * Procedure success codes + * + * USAGE: define procedures to return "tSuccess". Test their results + * with the SUCCEEDED, FAILED and HADGLITCH macros. + * + * Microsoft sticks its nose into user space here, so for Windows' sake, + * make sure all of these are undefined. + */ +#undef SUCCESS +#undef FAILURE +#undef PROBLEM +#undef SUCCEEDED +#undef SUCCESSFUL +#undef FAILED +#undef HADGLITCH + +#define SUCCESS ((tSuccess) 0) +#define FAILURE ((tSuccess)-1) +#define PROBLEM ((tSuccess) 1) + +typedef int tSuccess; + +#define SUCCEEDED(p) ((p) == SUCCESS) +#define SUCCESSFUL(p) SUCCEEDED(p) +#define FAILED(p) ((p) < SUCCESS) +#define HADGLITCH(p) ((p) > SUCCESS) + +#ifndef STR +# define __STR(s) #s +# define STR(s) __STR(s) +#endif + +#ifdef DEFINING +# define VALUE(s) = s +# define MODE +#else +# define VALUE(s) +# define MODE extern +#endif + +#undef NUL +#define NUL '\0' + +#define MOD_LOCAL static +#define parse_duration option_parse_duration + +#endif /* AUTOGEN_PROJECT_H */ +/* end of project.h */ diff --git a/autoopts/proto.h b/autoopts/proto.h new file mode 100644 index 0000000..437e81e --- /dev/null +++ b/autoopts/proto.h @@ -0,0 +1,620 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * Prototypes for autoopts + * Generated Sun Aug 26 10:44:39 PDT 2018 + */ +#ifndef AUTOOPTS_PROTO_H_GUARD +#define AUTOOPTS_PROTO_H_GUARD 1 + + +/* + * Static declarations from alias.c + */ +static tSuccess +too_many_occurrences(tOptions * opts, tOptDesc * od); + +/* + * Static declarations from autoopts.c + */ +static void * +ao_malloc(size_t sz); + +static void * +ao_realloc(void *p, size_t sz); + +static char * +ao_strdup(char const *str); + +static tSuccess +handle_opt(tOptions * opts, tOptState * o_st); + +static tSuccess +next_opt(tOptions * opts, tOptState * o_st); + +static tSuccess +regular_opts(tOptions * opts); + +/* + * Static declarations from check.c + */ +static bool +has_conflict(tOptions * pOpts, tOptDesc * od); + +static bool +occurs_enough(tOptions * pOpts, tOptDesc * pOD); + +static bool +is_consistent(tOptions * pOpts); + +/* + * Static declarations from configfile.c + */ +static void +file_preset(tOptions * opts, char const * fname, int dir); + +static char * +handle_comment(char * txt); + +static char * +handle_cfg(tOptions * opts, tOptState * ost, char * txt, int dir); + +static char * +handle_directive(tOptions * opts, char * txt); + +static char * +aoflags_directive(tOptions * opts, char * txt); + +static char * +program_directive(tOptions * opts, char * txt); + +static char * +handle_section(tOptions * opts, char * txt); + +static int +parse_xml_encoding(char ** ppz); + +static char * +trim_xml_text(char * intxt, char const * pznm, tOptionLoadMode mode); + +static void +cook_xml_text(char * pzData); + +static char * +handle_struct(tOptions * opts, tOptState * ost, char * txt, int dir); + +static void +intern_file_load(tOptions * opts); + +static char const * +parse_attrs(tOptions * opts, char const * txt, tOptionLoadMode * pMode, + tOptionValue * pType); + +static char const * +parse_keyword(tOptions * opts, char const * txt, tOptionValue * typ); + +static char const * +parse_set_mem(tOptions * opts, char const * txt, tOptionValue * typ); + +static char const * +parse_value(char const * txt, tOptionValue * typ); + +/* + * Static declarations from cook.c + */ +static char * +nl_count(char * start, char * end, int * lnct_p); + +static bool +contiguous_quote(char ** pps, char * pq, int * lnct_p); + +/* + * Static declarations from enum.c + */ +static void +enum_err(tOptions * pOpts, tOptDesc * pOD, + char const * const * paz_names, int name_ct); + +static uintptr_t +find_name(char const * name, tOptions * pOpts, tOptDesc * pOD, + char const * const * paz_names, unsigned int name_ct); + +static void +set_memb_shell(tOptions * pOpts, tOptDesc * pOD, char const * const * paz_names, + unsigned int name_ct); + +static void +set_memb_names(tOptions * opts, tOptDesc * od, char const * const * nm_list, + unsigned int nm_ct); + +static uintptr_t +check_membership_start(tOptDesc * od, char const ** argp, bool * invert); + +static uintptr_t +find_member_bit(tOptions * opts, tOptDesc * od, char const * pz, int len, + char const * const * nm_list, unsigned int nm_ct); + +/* + * Static declarations from env.c + */ +static void +doPrognameEnv(tOptions * pOpts, teEnvPresetType type); + +static void +do_env_opt(tOptState * os, char * env_name, + tOptions * pOpts, teEnvPresetType type); + +static void +env_presets(tOptions * pOpts, teEnvPresetType type); + +/* + * Static declarations from file.c + */ +static void +check_existence(teOptFileType ftype, tOptions * pOpts, tOptDesc * pOD); + +static void +open_file_fd(tOptions * pOpts, tOptDesc * pOD, tuFileMode mode); + +static void +fopen_file_fp(tOptions * pOpts, tOptDesc * pOD, tuFileMode mode); + +/* + * Static declarations from find.c + */ +static int +parse_opt(char const ** nm_pp, char ** arg_pp, char * buf, size_t bufsz); + +static void +opt_ambiguities(tOptions * opts, char const * name, int nm_len); + +static int +opt_match_ct(tOptions * opts, char const * name, int nm_len, + int * ixp, bool * disable); + +static tSuccess +opt_set(tOptions * opts, char * arg, int idx, bool disable, tOptState * st); + +static tSuccess +opt_unknown(tOptions * opts, char const * name, char * arg, tOptState * st); + +static tSuccess +opt_ambiguous(tOptions * opts, char const * name, int match_ct); + +static tSuccess +opt_find_long(tOptions * opts, char const * opt_name, tOptState * state); + +static tSuccess +opt_find_short(tOptions * pOpts, uint_t optValue, tOptState * pOptState); + +static tSuccess +get_opt_arg_must(tOptions * opts, tOptState * o_st); + +static tSuccess +get_opt_arg_may(tOptions * pOpts, tOptState * o_st); + +static tSuccess +get_opt_arg_none(tOptions * pOpts, tOptState * o_st); + +static tSuccess +get_opt_arg(tOptions * opts, tOptState * o_st); + +static tSuccess +find_opt(tOptions * opts, tOptState * o_st); + +/* + * Static declarations from init.c + */ +static tSuccess +validate_struct(tOptions * opts, char const * pname); + +static tSuccess +immediate_opts(tOptions * opts); + +static tSuccess +do_presets(tOptions * opts); + +static bool +ao_initialize(tOptions * opts, int a_ct, char ** a_v); + +/* + * Static declarations from load.c + */ +static bool +get_realpath(char * buf, size_t b_sz); + +static bool +add_prog_path(char * buf, int b_sz, char const * fname, char const * prg_path); + +static bool +add_env_val(char * buf, int buf_sz, char const * name); + +static void +munge_str(char * txt, tOptionLoadMode mode); + +static char * +assemble_arg_val(char * txt, tOptionLoadMode mode); + +static char * +trim_quotes(char * arg); + +static bool +direction_ok(opt_state_mask_t f, int dir); + +static void +load_opt_line(tOptions * opts, tOptState * opt_state, char * line, + tDirection direction, tOptionLoadMode load_mode ); + +/* + * Static declarations from makeshell.c + */ +noreturn static void +option_exits(int exit_code); + +noreturn static void +ao_bug(char const * msg); + +static void +fserr_warn(char const * prog, char const * op, char const * fname); + +noreturn static void +fserr_exit(char const * prog, char const * op, char const * fname); + +static void +emit_var_text(char const * prog, char const * var, int fdin); + +static void +text_to_var(tOptions * opts, teTextTo which, tOptDesc * od); + +static void +emit_usage(tOptions * opts); + +static void +emit_wrapup(tOptions * opts); + +static void +emit_setup(tOptions * opts); + +static void +emit_action(tOptions * opts, tOptDesc * od); + +static void +emit_inaction(tOptions * opts, tOptDesc * od); + +static void +emit_flag(tOptions * opts); + +static void +emit_match_expr(char const * name, tOptDesc * cod, tOptions * opts); + +static void +emit_long(tOptions * opts); + +static char * +load_old_output(char const * fname, char const * pname); + +static void +open_out(char const * fname, char const * pname); + +/* + * Static declarations from nested.c + */ +static void +remove_continuation(char * src); + +static char const * +scan_q_str(char const * pzTxt); + +static tOptionValue * +add_string(void ** pp, char const * name, size_t nm_len, + char const * val, size_t d_len); + +static tOptionValue * +add_bool(void ** pp, char const * name, size_t nm_len, + char const * val, size_t d_len); + +static tOptionValue * +add_number(void ** pp, char const * name, size_t nm_len, + char const * val, size_t d_len); + +static tOptionValue * +add_nested(void ** pp, char const * name, size_t nm_len, + char * val, size_t d_len); + +static char const * +scan_name(char const * name, tOptionValue * res); + +static char const * +unnamed_xml(char const * txt); + +static char const * +scan_xml_name(char const * name, size_t * nm_len, tOptionValue * val); + +static char const * +find_end_xml(char const * src, size_t nm_len, char const * val, size_t * len); + +static char const * +scan_xml(char const * xml_name, tOptionValue * res_val); + +static void +unload_arg_list(tArgList * arg_list); + +static void +sort_list(tArgList * arg_list); + +static tOptionValue * +optionLoadNested(char const * text, char const * name, size_t nm_len); + +static int +get_special_char(char const ** ppz, int * ct); + +static void +emit_special_char(FILE * fp, int ch); + +/* + * Static declarations from parse-duration.c + */ +static unsigned long +str_const_to_ul (cch_t * str, cch_t ** ppz, int base); + +static long +str_const_to_l (cch_t * str, cch_t ** ppz, int base); + +static time_t +scale_n_add (time_t base, time_t val, int scale); + +static time_t +parse_hr_min_sec (time_t start, cch_t * pz); + +static time_t +parse_scaled_value (time_t base, cch_t ** ppz, cch_t * endp, int scale); + +static time_t +parse_year_month_day (cch_t * pz, cch_t * ps); + +static time_t +parse_yearmonthday (cch_t * in_pz); + +static time_t +parse_YMWD (cch_t * pz); + +static time_t +parse_hour_minute_second (cch_t * pz, cch_t * ps); + +static time_t +parse_hourminutesecond (cch_t * in_pz); + +static time_t +parse_HMS (cch_t * pz); + +static time_t +parse_time (cch_t * pz); + +static char * +trim (char * pz); + +static time_t +parse_period (cch_t * in_pz); + +static time_t +parse_non_iso8601 (cch_t * pz); + +/* + * Static declarations from pgusage.c + */ +static inline FILE * +open_tmp_usage(char ** buf); + +static inline char * +mk_pager_cmd(char const * fname); + +/* + * Static declarations from putshell.c + */ +static size_t +string_size(char const * scan, size_t nl_len); + +static char const * +print_quoted_apostrophes(char const * str); + +static void +print_quot_str(char const * str); + +static void +print_enumeration(tOptions * pOpts, tOptDesc * pOD); + +static void +print_membership(tOptions * pOpts, tOptDesc * pOD); + +static void +print_stacked_arg(tOptions * pOpts, tOptDesc * pOD); + +static void +print_reordering(tOptions * opts); + +/* + * Static declarations from reset.c + */ +static void +optionReset(tOptions * pOpts, tOptDesc * pOD); + +static void +optionResetEverything(tOptions * pOpts); + +/* + * Static declarations from restore.c + */ +static void +fixupSavedOptionArgs(tOptions * pOpts); + +/* + * Static declarations from save.c + */ +static char const * +find_dir_name(tOptions * opts, int * p_free); + +static char const * +find_file_name(tOptions * opts, int * p_free_name); + +static void +prt_entry(FILE * fp, tOptDesc * od, char const * l_arg, save_flags_mask_t save_fl); + +static void +prt_value(FILE * fp, int depth, tOptDesc * od, tOptionValue const * ovp); + +static void +prt_string(FILE * fp, char const * name, char const * pz); + +static void +prt_val_list(FILE * fp, char const * name, tArgList * al); + +static void +prt_nested(FILE * fp, tOptDesc * od, save_flags_mask_t save_fl); + +static void +remove_settings(tOptions * opts, char const * fname); + +static FILE * +open_sv_file(tOptions * opts, save_flags_mask_t save_fl); + +static void +prt_no_arg_opt(FILE * fp, tOptDesc * vod, tOptDesc * pod, save_flags_mask_t save_fl); + +static void +prt_str_arg(FILE * fp, tOptDesc * od, save_flags_mask_t save_fl); + +static void +prt_enum_arg(FILE * fp, tOptDesc * od, save_flags_mask_t save_fl); + +static void +prt_set_arg(FILE * fp, tOptDesc * od, save_flags_mask_t save_fl); + +static void +prt_file_arg(FILE * fp, tOptDesc * od, tOptions * opts, save_flags_mask_t save_fl); + +/* + * Static declarations from sort.c + */ +static tSuccess +must_arg(tOptions * opts, char * arg_txt, tOptState * pOS, + char ** opt_txt, uint32_t * opt_idx); + +static tSuccess +maybe_arg(tOptions * opts, char * arg_txt, tOptState * pOS, + char ** opt_txt, uint32_t * opt_idx); + +static tSuccess +short_opt_ck(tOptions * opts, char * arg_txt, tOptState * pOS, + char ** opt_txt, uint32_t * opt_idx); + +static void +optionSort(tOptions * opts); + +/* + * Static declarations from stack.c + */ +static void +addArgListEntry(void ** ppAL, void * entry); + +/* + * Static declarations from text_mmap.c + */ +static void +load_text_file(tmap_info_t * mapinfo, char const * pzFile); + +static void +validate_mmap(char const * fname, int prot, int flags, tmap_info_t * mapinfo); + +static void +close_mmap_files(tmap_info_t * mi); + +/* + * Static declarations from tokenize.c + */ +static void +copy_cooked(ch_t ** ppDest, char const ** ppSrc); + +static void +copy_raw(ch_t ** ppDest, char const ** ppSrc); + +static token_list_t * +alloc_token_list(char const * str); + +/* + * Static declarations from usage.c + */ +static unsigned int +parse_usage_flags(ao_flag_names_t const * fnt, char const * txt); + +static void +set_usage_flags(tOptions * opts, char const * flg_txt); + +static inline bool +do_gnu_usage(tOptions * pOpts); + +static inline bool +skip_misuse_usage(tOptions * pOpts); + +static void +print_offer_usage(tOptions * opts); + +static void +print_usage_details(tOptions * opts, int exit_code); + +static void +print_one_paragraph(char const * text, bool plain, FILE * fp); + +static void +prt_conflicts(tOptions * opts, tOptDesc * od); + +static void +prt_one_vendor(tOptions * opts, tOptDesc * od, + arg_types_t * argtp, char const * usefmt); + +static void +prt_vendor_opts(tOptions * opts, char const * title); + +static void +prt_extd_usage(tOptions * opts, tOptDesc * od, char const * title); + +static void +prt_ini_list(char const * const * papz, char const * ini_file, + char const * path_nm); + +static void +prt_preamble(tOptions * opts, tOptDesc * od, arg_types_t * at); + +static void +prt_one_usage(tOptions * opts, tOptDesc * od, arg_types_t * at); + +static void +prt_opt_usage(tOptions * opts, int ex_code, char const * title); + +static void +prt_prog_detail(tOptions * opts); + +static int +setGnuOptFmts(tOptions * opts, char const ** ptxt); + +static int +setStdOptFmts(tOptions * opts, char const ** ptxt); + +/* + * Static declarations from version.c + */ +static void +emit_first_line( + FILE * fp, char const * alt1, char const * alt2, char const * alt3); + +static void +emit_simple_ver(tOptions * o, FILE * fp); + +static void +emit_copy_full(tOptions * o, FILE * fp); + +static void +emit_copy_note(tOptions * opts, FILE * fp); + +static void +print_ver(tOptions * opts, tOptDesc * od, FILE * fp, bool call_exit); + +#endif /* AUTOOPTS_PROTO_H_GUARD */ diff --git a/autoopts/putshell.c b/autoopts/putshell.c new file mode 100644 index 0000000..84463dd --- /dev/null +++ b/autoopts/putshell.c @@ -0,0 +1,495 @@ + +/** + * \file putshell.c + * + * This module will interpret the options set in the tOptions + * structure and print them to standard out in a fashion that + * will allow them to be interpreted by the Bourne or Korn shells. + * + * @addtogroup autoopts + * @{ + */ +/* + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +/** + * Count the number of bytes required to represent a string as a + * compilable string. + * + * @param[in] scan the text to be rewritten as a C program text string. + * @param[in] nl_len the number of bytes used for each embedded newline. + * + * @returns the count, including the terminating NUL byte. + */ +static size_t +string_size(char const * scan, size_t nl_len) +{ + /* + * Start by counting the start and end quotes, plus the NUL. + */ + size_t res_ln = 3; + + for (;;) { + char ch = *(scan++); + if ((ch >= ' ') && (ch <= '~')) { + + /* + * a backslash allowance for double quotes and baskslashes + */ + res_ln += ((ch == '"') || (ch == '\\')) ? 2 : 1; + } + + /* + * When not a normal character, then count the characters + * required to represent whatever it is. + */ + else switch (ch) { + case NUL: + return res_ln; + + case NL: + res_ln += nl_len; + break; + + case HT: + case BEL: + case BS: + case FF: + case CR: + case VT: + res_ln += 2; + break; + + default: + res_ln += 4; /* text len for \xNN */ + } + } +} + +/*=export_func optionQuoteString + * private: + * + * what: Print a string as quoted text suitable for a C compiler. + * arg: + char const * + text + a block of text to quote + + * arg: + char const * + nl + line splice text + + * + * ret_type: char const * + * ret_desc: the allocated input string as a quoted string + * + * doc: + * This is for internal use by autogen and autoopts. + * It takes an input string and produces text the C compiler can process + * to produce an exact copy of the original string. + * The caller must deallocate the result. Standard C strings and + * K&R strings are distinguished by the "nl" string. +=*/ +char const * +optionQuoteString(char const * text, char const * nl) +{ + size_t nl_len = strlen(nl); + size_t out_sz = string_size(text, nl_len); + char * out; + char * res = out = AGALOC(out_sz, "quot str"); + + *(out++) = '"'; + + for (;;) { + unsigned char ch = (unsigned char)*text; + if ((ch >= ' ') && (ch <= '~')) { + if ((ch == '"') || (ch == '\\')) + /* + * We must escape these characters in the output string + */ + *(out++) = '\\'; + *(out++) = (char)ch; + + } else switch (ch) { +# define add_esc_ch(_ch) { *(out++) = '\\'; *(out++) = (_ch); } + case BEL: add_esc_ch('a'); break; + case BS: add_esc_ch('b'); break; + case HT: add_esc_ch('t'); break; + case VT: add_esc_ch('v'); break; + case FF: add_esc_ch('f'); break; + case CR: add_esc_ch('r'); break; + + case LF: + /* + * Place contiguous new-lines on a single line. + * The current character is a NL, check the next one. + */ + while (*++text == NL) + add_esc_ch('n'); + + /* + * Insert a splice before starting next line + */ + if (*text != NUL) { + memcpy(out, nl, nl_len); + out += nl_len; + + continue; /* text is already at the next character */ + } + + add_esc_ch('n'); + /* FALLTHROUGH */ + + case NUL: + /* + * End of string. Terminate the quoted output. If necessary, + * deallocate the text string. Return the scan resumption point. + */ + *(out++) = '"'; + *(out++) = NUL; +#ifndef NDEBUG + if ((size_t)(out - res) > out_sz) { + fputs(misguess_len, stderr); + option_exits(EXIT_FAILURE); + } +#endif + return res; + + default: + /* + * sprintf is safe here, because we already computed + * the amount of space we will be using. Assertion is above. + */ + out += sprintf(out, MK_STR_OCT_FMT, ch); + } + + text++; +# undef add_esc_ch + } +} + +/** + * Print out escaped apostorophes. + * + * @param[in] str the apostrophies to print + */ +static char const * +print_quoted_apostrophes(char const * str) +{ + while (*str == APOSTROPHE) { + fputs(QUOT_APOS, stdout); + str++; + } + return str; +} + +/** + * Print a single quote (apostrophe quoted) string. + * Other than somersaults for apostrophes, nothing else needs quoting. + * + * @param[in] str the string to print + */ +static void +print_quot_str(char const * str) +{ + /* + * Handle empty strings to make the rest of the logic simpler. + */ + if ((str == NULL) || (*str == NUL)) { + fputs(EMPTY_ARG, stdout); + return; + } + + /* + * Emit any single quotes/apostrophes at the start of the string and + * bail if that is all we need to do. + */ + str = print_quoted_apostrophes(str); + if (*str == NUL) + return; + + /* + * Start the single quote string + */ + fputc(APOSTROPHE, stdout); + for (;;) { + char const * pz = strchr(str, APOSTROPHE); + if (pz == NULL) + break; + + /* + * Emit the string up to the single quote (apostrophe) we just found. + */ + (void)fwrite(str, (size_t)(pz - str), (size_t)1, stdout); + + /* + * Close the current string, emit the apostrophes and re-open the + * string (IFF there is more text to print). + */ + fputc(APOSTROPHE, stdout); + str = print_quoted_apostrophes(pz); + if (*str == NUL) + return; + + fputc(APOSTROPHE, stdout); + } + + /* + * If we broke out of the loop, we must still emit the remaining text + * and then close the single quote string. + */ + fputs(str, stdout); + fputc(APOSTROPHE, stdout); +} + +static void +print_enumeration(tOptions * pOpts, tOptDesc * pOD) +{ + uintptr_t e_val = pOD->optArg.argEnum; + printf(OPT_VAL_FMT, pOpts->pzPROGNAME, pOD->pz_NAME); + + /* + * Convert value to string, print that and restore numeric value. + */ + (*(pOD->pOptProc))(OPTPROC_RETURN_VALNAME, pOD); + printf(QUOT_ARG_FMT, pOD->optArg.argString); + if (pOD->fOptState & OPTST_ALLOC_ARG) + AGFREE(pOD->optArg.argString); + pOD->optArg.argEnum = e_val; + + printf(OPT_END_FMT, pOpts->pzPROGNAME, pOD->pz_NAME); +} + +static void +print_membership(tOptions * pOpts, tOptDesc * pOD) +{ + char const * svstr = pOD->optArg.argString; + char const * pz; + uintptr_t val = 1; + printf(zOptNumFmt, pOpts->pzPROGNAME, pOD->pz_NAME, + (int)(uintptr_t)(pOD->optCookie)); + pOD->optCookie = VOIDP(~0UL); + (*(pOD->pOptProc))(OPTPROC_RETURN_VALNAME, pOD); + + pz = pOD->optArg.argString; + while (*pz != NUL) { + printf("readonly %s_", pOD->pz_NAME); + pz = SPN_PLUS_N_SPACE_CHARS(pz); + + for (;;) { + int ch = *(pz++); + if (IS_LOWER_CASE_CHAR(ch)) fputc(toupper(ch), stdout); + else if (IS_UPPER_CASE_CHAR(ch)) fputc(ch, stdout); + else if (IS_PLUS_N_SPACE_CHAR(ch)) goto name_done; + else if (ch == NUL) { pz--; goto name_done; } + else fputc('_', stdout); + } name_done:; + printf(SHOW_VAL_FMT, (unsigned long)val); + val <<= 1; + } + + AGFREE(pOD->optArg.argString); + pOD->optArg.argString = svstr; +} + +static void +print_stacked_arg(tOptions * pOpts, tOptDesc * pOD) +{ + tArgList * pAL = (tArgList *)pOD->optCookie; + char const ** ppz = pAL->apzArgs; + int ct = pAL->useCt; + + printf(zOptCookieCt, pOpts->pzPROGNAME, pOD->pz_NAME, ct); + + while (--ct >= 0) { + printf(ARG_BY_NUM_FMT, pOpts->pzPROGNAME, pOD->pz_NAME, + pAL->useCt - ct); + print_quot_str(*(ppz++)); + printf(EXPORT_ARG_FMT, pOpts->pzPROGNAME, pOD->pz_NAME, + pAL->useCt - ct); + } +} + +/** + * emit the arguments as readily parsed text. + * The program options are set by emitting the shell "set" command. + * + * @param[in] opts the program options structure + */ +static void +print_reordering(tOptions * opts) +{ + unsigned int ix; + + fputs(set_dash, stdout); + + for (ix = opts->curOptIdx; + ix < opts->origArgCt; + ix++) { + fputc(' ', stdout); + print_quot_str(opts->origArgVect[ ix ]); + } + fputs(init_optct, stdout); +} + +/*=export_func optionPutShell + * what: write a portable shell script to parse options + * private: + * arg: tOptions *, pOpts, the program options descriptor + * doc: This routine will emit portable shell script text for parsing + * the options described in the option definitions. +=*/ +void +optionPutShell(tOptions * pOpts) +{ + int optIx = 0; + + printf(zOptCtFmt, pOpts->curOptIdx-1); + + do { + tOptDesc * pOD = pOpts->pOptDesc + optIx; + + if ((pOD->fOptState & OPTST_NO_OUTPUT_MASK) != 0) + continue; + + /* + * Equivalence classes are hard to deal with. Where the + * option data wind up kind of squishes around. For the purposes + * of emitting shell state, they are not recommended, but we'll + * do something. I guess we'll emit the equivalenced-to option + * at the point in time when the base option is found. + */ + if (pOD->optEquivIndex != NO_EQUIVALENT) + continue; /* equivalence to a different option */ + + /* + * Equivalenced to a different option. Process the current option + * as the equivalenced-to option. Keep the persistent state bits, + * but copy over the set-state bits. + */ + if (pOD->optActualIndex != optIx) { + tOptDesc * p = pOpts->pOptDesc + pOD->optActualIndex; + p->optArg = pOD->optArg; + p->fOptState &= OPTST_PERSISTENT_MASK; + p->fOptState |= pOD->fOptState & ~OPTST_PERSISTENT_MASK; + printf(zEquivMode, pOpts->pzPROGNAME, pOD->pz_NAME, p->pz_NAME); + pOD = p; + } + + /* + * If the argument type is a set membership bitmask, then we always + * emit the thing. We do this because it will always have some sort + * of bitmask value and we need to emit the bit values. + */ + if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_MEMBERSHIP) { + print_membership(pOpts, pOD); + continue; + } + + /* + * IF the option was either specified or it wakes up enabled, + * then we will emit information. Otherwise, skip it. + * The idea is that if someone defines an option to initialize + * enabled, we should tell our shell script that it is enabled. + */ + if (UNUSED_OPT(pOD) && DISABLED_OPT(pOD)) + continue; + + /* + * Handle stacked arguments + */ + if ( (pOD->fOptState & OPTST_STACKED) + && (pOD->optCookie != NULL) ) { + print_stacked_arg(pOpts, pOD); + continue; + } + + /* + * If the argument has been disabled, + * Then set its value to the disablement string + */ + if ((pOD->fOptState & OPTST_DISABLED) != 0) { + printf(zOptDisabl, pOpts->pzPROGNAME, pOD->pz_NAME, + (pOD->pz_DisablePfx != NULL) + ? pOD->pz_DisablePfx : "false"); + continue; + } + + /* + * If the argument type is numeric, the last arg pointer + * is really the VALUE of the string that was pointed to. + */ + if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_NUMERIC) { + printf(zOptNumFmt, pOpts->pzPROGNAME, pOD->pz_NAME, + (int)pOD->optArg.argInt); + continue; + } + + /* + * If the argument type is an enumeration, then it is much + * like a text value, except we call the callback function + * to emit the value corresponding to the "optArg" number. + */ + if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_ENUMERATION) { + print_enumeration(pOpts, pOD); + continue; + } + + /* + * If the argument type is numeric, the last arg pointer + * is really the VALUE of the string that was pointed to. + */ + if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_BOOLEAN) { + printf(zFullOptFmt, pOpts->pzPROGNAME, pOD->pz_NAME, + (pOD->optArg.argBool == 0) ? "false" : "true"); + continue; + } + + /* + * IF the option has an empty value, + * THEN we set the argument to the occurrence count. + */ + if ( (pOD->optArg.argString == NULL) + || (pOD->optArg.argString[0] == NUL) ) { + + printf(zOptNumFmt, pOpts->pzPROGNAME, pOD->pz_NAME, + pOD->optOccCt); + continue; + } + + /* + * This option has a text value + */ + printf(OPT_VAL_FMT, pOpts->pzPROGNAME, pOD->pz_NAME); + print_quot_str(pOD->optArg.argString); + printf(OPT_END_FMT, pOpts->pzPROGNAME, pOD->pz_NAME); + + } while (++optIx < pOpts->presetOptCt ); + + if ( ((pOpts->fOptSet & OPTPROC_REORDER) != 0) + && (pOpts->curOptIdx < pOpts->origArgCt)) + print_reordering(pOpts); + + fflush(stdout); +} + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/putshell.c */ diff --git a/autoopts/reset.c b/autoopts/reset.c new file mode 100644 index 0000000..f7b58e8 --- /dev/null +++ b/autoopts/reset.c @@ -0,0 +1,141 @@ + +/** + * \file reset.c + * + * Reset the option state to the compiled state. + * + * @addtogroup autoopts + * @{ + */ +/* + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +static void +optionReset(tOptions * pOpts, tOptDesc * pOD) +{ + pOD->fOptState &= OPTST_PERSISTENT_MASK; + pOD->fOptState |= OPTST_RESET; + if (pOD->pOptProc != NULL) + pOD->pOptProc(pOpts, pOD); + pOD->optArg.argString = + pOpts->originalOptArgArray[ pOD->optIndex ].argString; + pOD->optCookie = pOpts->originalOptArgCookie[ pOD->optIndex ]; + pOD->fOptState &= OPTST_PERSISTENT_MASK; +} + + +static void +optionResetEverything(tOptions * pOpts) +{ + tOptDesc * pOD = pOpts->pOptDesc; + int ct = pOpts->presetOptCt; + + for (;;) { + optionReset(pOpts, pOD); + + if (--ct <= 0) + break; + pOD++; + } +} + + +/*=export_func optionResetOpt + * private: + * + * what: Reset the value of an option + * arg: + tOptions * + pOpts + program options descriptor + + * arg: + tOptDesc * + pOptDesc + the descriptor for this arg + + * + * doc: + * This code will cause another option to be reset to its initial state. + * For example, --reset=foo will cause the --foo option to be reset. +=*/ +void +optionResetOpt(tOptions * pOpts, tOptDesc * pOD) +{ + static bool reset_active = false; + + tOptState opt_state = OPTSTATE_INITIALIZER(DEFINED); + char const * pzArg = pOD->optArg.argString; + tSuccess succ; + + if (pOpts <= OPTPROC_EMIT_LIMIT) + return; + + if (reset_active) + return; + + if ( (! HAS_originalOptArgArray(pOpts)) + || (pOpts->originalOptArgCookie == NULL)) + ao_bug(zno_reset); + + if ((pzArg == NULL) || (*pzArg == NUL)) { + fprintf(stderr, zreset_arg, pOpts->pzProgName, pOD->pz_Name); + pOpts->pUsageProc(pOpts, EXIT_FAILURE); + /* NOTREACHED */ + assert(0 == 1); + } + + reset_active = true; + + if (pzArg[1] == NUL) { + if (*pzArg == '*') { + optionResetEverything(pOpts); + reset_active = false; + return; + } + + succ = opt_find_short(pOpts, (uint8_t)*pzArg, &opt_state); + if (! SUCCESSFUL(succ)) { + fprintf(stderr, zIllOptChr, pOpts->pzProgPath, *pzArg); + pOpts->pUsageProc(pOpts, EXIT_FAILURE); + /* NOTREACHED */ + assert(0 == 1); + } + } else { + succ = opt_find_long(pOpts, (char *)pzArg, &opt_state); + if (! SUCCESSFUL(succ)) { + fprintf(stderr, zIllOptStr, pOpts->pzProgPath, pzArg); + pOpts->pUsageProc(pOpts, EXIT_FAILURE); + /* NOTREACHED */ + assert(0 == 1); + } + } + + /* + * We've found the indicated option. Turn off all non-persistent + * flags because we're forcing the option back to its initialized state. + * Call any callout procedure to handle whatever it needs to. + * Finally, clear the reset flag, too. + */ + optionReset(pOpts, opt_state.pOD); + reset_active = false; +} +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/reset.c */ diff --git a/autoopts/restore.c b/autoopts/restore.c new file mode 100644 index 0000000..36ebbce --- /dev/null +++ b/autoopts/restore.c @@ -0,0 +1,223 @@ + +/* + * \file restore.c + * + * This module's routines will save the current option state to memory + * and restore it. If saved prior to the initial optionProcess call, + * then the initial state will be restored. + * + * @addtogroup autoopts + * @{ + */ +/* + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +/* + * optionFixupSavedOpts Really, it just wipes out option state for + * options that are troublesome to copy. viz., stacked strings and + * hierarcicaly valued option args. We do duplicate string args that + * have been marked as allocated though. + */ +static void +fixupSavedOptionArgs(tOptions * pOpts) +{ + tOptions * p = pOpts->pSavedState; + tOptDesc * pOD = pOpts->pOptDesc; + int ct = pOpts->optCt; + + /* + * Make sure that allocated stuff is only referenced in the + * archived copy of the data. + */ + for (; ct-- > 0; pOD++) { + switch (OPTST_GET_ARGTYPE(pOD->fOptState)) { + case OPARG_TYPE_STRING: + if (pOD->fOptState & OPTST_STACKED) { + tOptDesc * q = p->pOptDesc + (pOD - pOpts->pOptDesc); + q->optCookie = NULL; + } + if (pOD->fOptState & OPTST_ALLOC_ARG) { + tOptDesc * q = p->pOptDesc + (pOD - pOpts->pOptDesc); + AGDUPSTR(q->optArg.argString, pOD->optArg.argString, "arg"); + } + break; + + case OPARG_TYPE_HIERARCHY: + { + tOptDesc * q = p->pOptDesc + (pOD - pOpts->pOptDesc); + q->optCookie = NULL; + } + } + } +} + +/*=export_func optionSaveState + * + * what: saves the option state to memory + * arg: tOptions *, pOpts, program options descriptor + * + * doc: + * + * This routine will allocate enough memory to save the current option + * processing state. If this routine has been called before, that memory + * will be reused. You may only save one copy of the option state. This + * routine may be called before optionProcess(3AO). If you do call it + * before the first call to optionProcess, then you may also change the + * contents of argc/argv after you call optionRestore(3AO) + * + * In fact, more strongly put: it is safest to only use this function + * before having processed any options. In particular, the saving and + * restoring of stacked string arguments and hierarchical values is + * disabled. The values are not saved. + * + * err: If it fails to allocate the memory, + * it will print a message to stderr and exit. + * Otherwise, it will always succeed. +=*/ +void +optionSaveState(tOptions * pOpts) +{ + tOptions * p = (tOptions *)pOpts->pSavedState; + + if (p == NULL) { + size_t sz = sizeof(*pOpts) + + ((size_t)pOpts->optCt * sizeof(tOptDesc)); + p = AGALOC(sz, "saved option state"); + + pOpts->pSavedState = p; + } + + memcpy(p, pOpts, sizeof(*p)); + memcpy(p + 1, pOpts->pOptDesc, (size_t)p->optCt * sizeof(tOptDesc)); + + fixupSavedOptionArgs(pOpts); +} + + +/*=export_func optionRestore + * + * what: restore option state from memory copy + * arg: tOptions *, pOpts, program options descriptor + * + * doc: Copy back the option state from saved memory. + * The allocated memory is left intact, so this routine can be + * called repeatedly without having to call optionSaveState again. + * If you are restoring a state that was saved before the first call + * to optionProcess(3AO), then you may change the contents of the + * argc/argv parameters to optionProcess. + * + * err: If you have not called @code{optionSaveState} before, a diagnostic is + * printed to @code{stderr} and exit is called. +=*/ +void +optionRestore(tOptions * pOpts) +{ + tOptions * p = (tOptions *)pOpts->pSavedState; + + if (p == NULL) { + char const * pzName = pOpts->pzProgName; + if (pzName == NULL) { + pzName = pOpts->pzPROGNAME; + if (pzName == NULL) + pzName = zNil; + } + fprintf(stderr, zNoState, pzName); + option_exits(EXIT_FAILURE); + } + + pOpts->pSavedState = NULL; + optionFree(pOpts); + + memcpy(pOpts, p, sizeof(*p)); + memcpy(pOpts->pOptDesc, p+1, (size_t)p->optCt * sizeof(tOptDesc)); + pOpts->pSavedState = p; + + fixupSavedOptionArgs(pOpts); +} + +/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */ + +/*=export_func optionFree + * + * what: free allocated option processing memory + * arg: tOptions *, pOpts, program options descriptor + * + * doc: AutoOpts sometimes allocates memory and puts pointers to it in the + * option state structures. This routine deallocates all such memory. + * + * err: As long as memory has not been corrupted, + * this routine is always successful. +=*/ +void +optionFree(tOptions * pOpts) +{ + free_saved_state: + { + tOptDesc * p = pOpts->pOptDesc; + int ct = pOpts->optCt; + do { + if (p->fOptState & OPTST_ALLOC_ARG) { + AGFREE(p->optArg.argString); + p->optArg.argString = NULL; + p->fOptState &= ~OPTST_ALLOC_ARG; + } + + switch (OPTST_GET_ARGTYPE(p->fOptState)) { + case OPARG_TYPE_STRING: +#ifdef WITH_LIBREGEX + if ( (p->fOptState & OPTST_STACKED) + && (p->optCookie != NULL)) { + p->optArg.argString = ".*"; + optionUnstackArg(pOpts, p); + } +#else + /* leak memory */; +#endif + break; + + case OPARG_TYPE_HIERARCHY: + if (p->optCookie != NULL) + unload_arg_list(p->optCookie); + break; + } + + p->optCookie = NULL; + } while (p++, --ct > 0); + } + if (pOpts->pSavedState != NULL) { + tOptions * p = (tOptions *)pOpts->pSavedState; + memcpy(pOpts, p, sizeof(*p)); + memcpy(pOpts->pOptDesc, p+1, (size_t)p->optCt * sizeof(tOptDesc)); + AGFREE(pOpts->pSavedState); + pOpts->pSavedState = NULL; + goto free_saved_state; + } +} + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/restore.c */ diff --git a/autoopts/save-flags.c b/autoopts/save-flags.c new file mode 100644 index 0000000..d295170 --- /dev/null +++ b/autoopts/save-flags.c @@ -0,0 +1,248 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * DO NOT EDIT THIS FILE (save-flags.c) + * + * It has been AutoGen-ed + * From the definitions /tmp/.ag-ufBbQe/save-flags.def + * and the template file str2enum + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name ``Bruce Korb'' nor the name of any other + * contributor may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * str2enum IS PROVIDED BY Bruce Korb ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Bruce Korb OR ANY OTHER CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "save-flags.h" +#include +#ifndef MISSING_INTTYPES_H +# include +#endif + +typedef enum { + SVFL_BNM_DEFAULT = 0, + SVFL_BNM_USAGE = 1, + SVFL_BNM_UPDATE = 2, + SVFL_COUNT_BNM +} save_flags_enum_t; + +static save_flags_enum_t +find_save_flags_bnm(char const * str, size_t len); + + +#include +#include +#ifndef NUL +#define NUL '\0' +#endif + +/* ANSI-C code produced by gperf version 3.1 */ +/* Command-line: gperf save-flags.gp */ +/* Computed positions: -k'' */ + + +# if 0 /* gperf build options: */ +// %struct-type +// %language=ANSI-C +// %includes +// %global-table +// %omit-struct-type +// %readonly-tables +// %compare-strncmp +// +// %define slot-name svfl_name +// %define hash-function-name save_flags_hash +// %define lookup-function-name find_save_flags_name +// %define word-array-name save_flags_table +// %define initializer-suffix ,SVFL_COUNT_BNM +// +# endif + +#include "save-flags.h" +typedef struct { + char const * svfl_name; + save_flags_enum_t svfl_id; +} save_flags_map_t; +#include + +/* maximum key range = 3, duplicates = 0 */ + +static unsigned int +save_flags_hash (register const char *str, register size_t len) +{ + (void)str; + (void)len; + return len; +} + +static const save_flags_map_t save_flags_table[] = + { + {"",SVFL_COUNT_BNM}, {"",SVFL_COUNT_BNM}, + {"",SVFL_COUNT_BNM}, {"",SVFL_COUNT_BNM}, + {"",SVFL_COUNT_BNM}, + {"usage", SVFL_BNM_USAGE}, + {"update", SVFL_BNM_UPDATE}, + {"default", SVFL_BNM_DEFAULT} + }; + +static inline const save_flags_map_t * +find_save_flags_name (register const char *str, register size_t len) +{ + if (len <= 7 && len >= 5) + { + register unsigned int key = (int)save_flags_hash (str, len); + + if (key <= 7) + { + register const char *s = save_flags_table[key].svfl_name; + + if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0') + return &save_flags_table[key]; + } + } + return 0; +} + +/** + * Convert a command (keyword) to a save_flags_enum_t enumeration value. + * + * @param[in] str a string that should start with a known key word. + * @param[in] len the provided length of the keyword at \a str. + * @returns the enumeration value. + * If not found, that value is SVFL_COUNT_BNM. + */ +static save_flags_enum_t +find_save_flags_bnm(char const * str, size_t len) +{ + save_flags_map_t const * map; + + map = find_save_flags_name(str, (unsigned int)len); + if (map != NULL) + return map->svfl_id; + /* Check for a partial match */ + { + /* + * Indexes of valid save_flags_table entries in sorted order: + */ + static unsigned int const ix_map[] = { + 7, 6, 5 }; + save_flags_enum_t res = SVFL_COUNT_BNM; + static int const HI = (sizeof(ix_map) / sizeof(ix_map[0])) - 1; + int lo = 0; + int hi = HI; + int av; + int cmp; + + for (;;) { + av = (hi + lo) / 2; + map = save_flags_table + ix_map[av]; + cmp = strncmp(map->svfl_name, str, len); + if (cmp == 0) break; + if (cmp > 0) + hi = av - 1; + else lo = av + 1; + if (lo > hi) + return SVFL_COUNT_BNM; + } + res = map->svfl_id; + /* + * If we have an exact match, accept it. + */ + if (map->svfl_name[len] == NUL) + return res; + /* + * Check for a duplicate partial match (a partial match + * with a higher or lower index than "av". + */ + if (av < HI) { + map = save_flags_table + ix_map[av + 1]; + if (strncmp(map->svfl_name, str, len) == 0) + return SVFL_COUNT_BNM; + } + if (av > 0) { + map = save_flags_table + ix_map[av - 1]; + if (strncmp(map->svfl_name, str, len) == 0) + return SVFL_COUNT_BNM; + } + return res; + } +} + +/** + * Convert a string to a save_flags_mask_t mask. + * Bit names prefixed with a hyphen have the bit removed from the mask. + * If the string starts with a '-', '+' or '|' character, then + * the old value is used as a base, otherwise the result mask + * is initialized to zero. Separating bit names with '+' or '|' + * characters is optional. By default, the bits are "or"-ed into the + * result. + * + * @param[in] str string with a list of bit names + * @param[in] old previous value, used if \a str starts with a '+' or '-'. + * + * @returns an unsigned integer with the bits set. + */ +save_flags_mask_t +save_flags_str2mask(char const * str, save_flags_mask_t old) +{ + static char const white[] = ", \t\f"; + static char const name_chars[] = + "adefglpstu" + "ADEFGLPSTU"; + + save_flags_mask_t res = 0; + int have_data = 0; + + for (;;) { + save_flags_enum_t val; + unsigned int val_len; + unsigned int invert = 0; + + str += strspn(str, white); + switch (*str) { + case NUL: return res; + case '-': case '~': + invert = 1; + /* FALLTHROUGH */ + + case '+': case '|': + if (have_data == 0) + res = old; + + str += 1 + strspn(str + 1, white); + if (*str == NUL) + return 0; + } + + val_len = strspn(str, name_chars); + if (val_len == 0) + return 0; + val = find_save_flags_bnm(str, val_len); + if (val == SVFL_COUNT_BNM) + return 0; + if (invert) + res &= ~((save_flags_mask_t)1 << val); + else + res |= (save_flags_mask_t)1 << val; + have_data = 1; + str += val_len; + } +} +/* end of save-flags.c */ diff --git a/autoopts/save-flags.h b/autoopts/save-flags.h new file mode 100644 index 0000000..dcfe0c9 --- /dev/null +++ b/autoopts/save-flags.h @@ -0,0 +1,68 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * DO NOT EDIT THIS FILE (save-flags.h) + * + * It has been AutoGen-ed + * From the definitions /tmp/.ag-ufBbQe/save-flags.def + * and the template file str2enum + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name ``Bruce Korb'' nor the name of any other + * contributor may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * str2enum IS PROVIDED BY Bruce Korb ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL Bruce Korb OR ANY OTHER CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Command/Keyword Dispatcher + */ +#ifndef STR2ENUM_SAVE_FLAGS_H_GUARD +#define STR2ENUM_SAVE_FLAGS_H_GUARD 1 +#include +#include + +/** integral type for holding save_flags masks */ +typedef uint32_t save_flags_mask_t; + +/** bits defined for save_flags_mask_t */ +/** include default values in commentary */ +#define SVFL_DEFAULT 0x0001U +/** include usage text in commentary */ +#define SVFL_USAGE 0x0002U +/** replace or append state */ +#define SVFL_UPDATE 0x0004U + +/** bits in USAGE_DEFAULT mask: + * usage default */ +#define SVFL_USAGE_DEFAULT_MASK 0x0003U + +/** all bits in save_flags_mask_t masks */ +#define SVFL_MASK_ALL 0x0007U + +/** no bits in save_flags_mask_t */ +#define SVFL_NONE 0x0000U + +/** buffer size needed to hold all bit names for save_flags_mask_t masks */ +#define MAX_SAVE_FLAGS_NAME_SIZE 21 + +extern save_flags_mask_t +save_flags_str2mask(char const * str, save_flags_mask_t old); + +#endif /* STR2ENUM_SAVE_FLAGS_H_GUARD */ +/* end of save-flags.h */ diff --git a/autoopts/save.c b/autoopts/save.c new file mode 100644 index 0000000..8b1fba9 --- /dev/null +++ b/autoopts/save.c @@ -0,0 +1,916 @@ + +/* + * \file save.c + * + * This module's routines will take the currently set options and + * store them into an ".rc" file for re-interpretation the next + * time the invoking program is run. + * + * @addtogroup autoopts + * @{ + */ +/* + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ +#include "save-flags.h" + +/** + * find the config file directory name + * + * @param opts the options descriptor + * @param p_free tell caller if name was allocated or not + */ +static char const * +find_dir_name(tOptions * opts, int * p_free) +{ + char const * dir; + + if ( (opts->specOptIdx.save_opts == NO_EQUIVALENT) + || (opts->specOptIdx.save_opts == 0)) + return NULL; + + dir = opts->pOptDesc[ opts->specOptIdx.save_opts ].optArg.argString; + if ((dir != NULL) && (*dir != NUL)) { + char const * pz = strchr(dir, '>'); + if (pz == NULL) + return dir; + while (*(++pz) == '>') ; + pz += strspn(pz, " \t"); + dir = pz; + if (*dir != NUL) + return dir; + } + + if (opts->papzHomeList == NULL) + return NULL; + + /* + * This function only works if there is a directory where + * we can stash the RC (INI) file. + */ + for (int idx = 0;; idx++) { + char f_name[ AG_PATH_MAX+1 ]; + + dir = opts->papzHomeList[idx]; + + switch (*dir) { + case '$': + break; + case NUL: + continue; + default: + return dir; + } + if (optionMakePath(f_name, (int)sizeof(f_name), dir, opts->pzProgPath)) { + *p_free = true; + AGDUPSTR(dir, f_name, "homerc"); + return dir; + } + } + return NULL; +} + +/** + * Find the name of the save-the-options file + * + * @param opts the options descriptor + * @param p_free_name tell caller if name was allocated or not + */ +static char const * +find_file_name(tOptions * opts, int * p_free_name) +{ + struct stat stBuf; + int free_dir_name = 0; + + char const * res = find_dir_name(opts, &free_dir_name); + if (res == NULL) + return res; + + /* + * See if we can find the specified directory. We use a once-only loop + * structure so we can bail out early. + */ + if (stat(res, &stBuf) != 0) do { + char z[AG_PATH_MAX]; + char * dirchp; + + /* + * IF we could not, check to see if we got a full + * path to a file name that has not been created yet. + */ + if (errno != ENOENT) { + bogus_name: + fprintf(stderr, zsave_warn, opts->pzProgName, res); + fprintf(stderr, zNoStat, errno, strerror(errno), res); + if (free_dir_name) + AGFREE(res); + return NULL; + } + + /* + * Strip off the last component, stat the remaining string and + * that string must name a directory + */ + dirchp = strrchr(res, DIRCH); + if (dirchp == NULL) { + stBuf.st_mode = S_IFREG; + break; /* found directory -- viz., "." */ + } + + if ((size_t)(dirchp - res) >= sizeof(z)) + goto bogus_name; + + memcpy(z, res, (size_t)(dirchp - res)); + z[dirchp - res] = NUL; + + if ((stat(z, &stBuf) != 0) || ! S_ISDIR(stBuf.st_mode)) + goto bogus_name; + stBuf.st_mode = S_IFREG; /* file within this directory */ + } while (false); + + /* + * IF what we found was a directory, + * THEN tack on the config file name + */ + if (S_ISDIR(stBuf.st_mode)) { + + { + size_t sz = strlen(res) + strlen(opts->pzRcName) + 2; + char * pzPath = (char *)AGALOC(sz, "file name"); + if ( snprintf(pzPath, sz, "%s/%s", res, opts->pzRcName) + >= (int)sz) + option_exits(EXIT_FAILURE); + + if (free_dir_name) + AGFREE(res); + res = pzPath; + free_dir_name = 1; + } + + /* + * IF we cannot stat the object for any reason other than + * it does not exist, then we bail out + */ + if (stat(res, &stBuf) != 0) { + if (errno != ENOENT) { + fprintf(stderr, zsave_warn, opts->pzProgName, res); + fprintf(stderr, zNoStat, errno, strerror(errno), + res); + AGFREE(res); + return NULL; + } + + /* + * It does not exist yet, but it will be a regular file + */ + stBuf.st_mode = S_IFREG; + } + } + + /* + * Make sure that whatever we ultimately found, that it either is + * or will soon be a file. + */ + if (! S_ISREG(stBuf.st_mode)) { + fprintf(stderr, zsave_warn, opts->pzProgName, res); + if (free_dir_name) + AGFREE(res); + return NULL; + } + + /* + * Get rid of the old file + */ + *p_free_name = free_dir_name; + return res; +} + +/** + * print one option entry to the save file. + * + * @param[in] fp the file pointer for the save file + * @param[in] od the option descriptor to print + * @param[in] l_arg the last argument for the option + * @param[in] save_fl include usage in comments + */ +static void +prt_entry(FILE * fp, tOptDesc * od, char const * l_arg, save_flags_mask_t save_fl) +{ + int space_ct; + + if (save_fl & SVFL_USAGE) + fprintf(fp, ao_name_use_fmt, od->pz_Name, od->pzText); + if (UNUSED_OPT(od) && (save_fl & SVFL_DEFAULT)) + fputs(ao_default_use, fp); + + /* + * There is an argument. Pad the name so values line up. + * Not disabled *OR* this got equivalenced to another opt, + * then use current option name. + * Otherwise, there must be a disablement name. + */ + { + char const * pz = + (od->pz_DisableName == NULL) + ? od->pz_Name + : (DISABLED_OPT(od) + ? od->pz_DisableName + : ((od->optEquivIndex == NO_EQUIVALENT) + ? od->pz_Name : od->pz_DisableName) + ); + + space_ct = 17 - strlen(pz); + fputs(pz, fp); + } + + if ( (l_arg == NULL) + && (OPTST_GET_ARGTYPE(od->fOptState) != OPARG_TYPE_NUMERIC)) + goto end_entry; + + fputs(" = ", fp); + while (space_ct-- > 0) fputc(' ', fp); + + /* + * IF the option is numeric only, + * THEN the char pointer is really the number + */ + if (OPTST_GET_ARGTYPE(od->fOptState) == OPARG_TYPE_NUMERIC) + fprintf(fp, "%d", (int)(intptr_t)l_arg); + + else { + for (;;) { + char const * eol = strchr(l_arg, NL); + + /* + * IF this is the last line + * THEN bail and print it + */ + if (eol == NULL) + break; + + /* + * Print the continuation and the text from the current line + */ + (void)fwrite(l_arg, (size_t)(eol - l_arg), (size_t)1, fp); + l_arg = eol+1; /* advance the Last Arg pointer */ + fputs("\\\n", fp); + } + + /* + * Terminate the entry + */ + fputs(l_arg, fp); + } + +end_entry: + fputc(NL, fp); +} + +/** + * print an option's value + * + * @param[in] fp the file pointer for the save file + * @param[in] od the option descriptor to print + */ +static void +prt_value(FILE * fp, int depth, tOptDesc * od, tOptionValue const * ovp) +{ + while (--depth >= 0) + putc(' ', fp), putc(' ', fp); + + switch (ovp->valType) { + default: + case OPARG_TYPE_NONE: + fprintf(fp, NULL_ATR_FMT, ovp->pzName); + break; + + case OPARG_TYPE_STRING: + prt_string(fp, ovp->pzName, ovp->v.strVal); + break; + + case OPARG_TYPE_ENUMERATION: + case OPARG_TYPE_MEMBERSHIP: + if (od != NULL) { + uint32_t opt_state = od->fOptState; + uintptr_t val = od->optArg.argEnum; + char const * typ = (ovp->valType == OPARG_TYPE_ENUMERATION) + ? "keyword" : "set-membership"; + + fprintf(fp, TYPE_ATR_FMT, ovp->pzName, typ); + + /* + * This is a magic incantation that will convert the + * bit flag values back into a string suitable for printing. + */ + (*(od->pOptProc))(OPTPROC_RETURN_VALNAME, od ); + if (od->optArg.argString != NULL) { + fputs(od->optArg.argString, fp); + + if (ovp->valType != OPARG_TYPE_ENUMERATION) { + /* + * set membership strings get allocated + */ + AGFREE(od->optArg.argString); + } + } + + od->optArg.argEnum = val; + od->fOptState = opt_state; + fprintf(fp, END_XML_FMT, ovp->pzName); + break; + } + /* FALLTHROUGH */ + + case OPARG_TYPE_NUMERIC: + fprintf(fp, NUMB_ATR_FMT, ovp->pzName, ovp->v.longVal); + break; + + case OPARG_TYPE_BOOLEAN: + fprintf(fp, BOOL_ATR_FMT, ovp->pzName, + ovp->v.boolVal ? "true" : "false"); + break; + + case OPARG_TYPE_HIERARCHY: + prt_val_list(fp, ovp->pzName, ovp->v.nestVal); + break; + } +} + +/** + * Print a string value in XML format + * + * @param[in] fp the file pointer for the save file + */ +static void +prt_string(FILE * fp, char const * name, char const * pz) +{ + fprintf(fp, OPEN_XML_FMT, name); + for (;;) { + int ch = ((int)*(pz++)) & 0xFF; + + switch (ch) { + case NUL: goto string_done; + + case '&': + case '<': + case '>': +#if __GNUC__ >= 4 + case 1 ... (' ' - 1): + case ('~' + 1) ... 0xFF: +#endif + emit_special_char(fp, ch); + break; + + default: +#if __GNUC__ < 4 + if ( ((ch >= 1) && (ch <= (' ' - 1))) + || ((ch >= ('~' + 1)) && (ch <= 0xFF)) ) { + emit_special_char(fp, ch); + break; + } +#endif + putc(ch, fp); + } + } string_done:; + fprintf(fp, END_XML_FMT, name); +} + +/** + * Print an option that can have multiple values in XML format + * + * @param[in] fp file pointer + */ +static void +prt_val_list(FILE * fp, char const * name, tArgList * al) +{ + static int depth = 1; + + int sp_ct; + int opt_ct; + void ** opt_list; + + if (al == NULL) + return; + opt_ct = al->useCt; + opt_list = (void **)al->apzArgs; + + if (opt_ct <= 0) { + fprintf(fp, OPEN_CLOSE_FMT, name); + return; + } + + fprintf(fp, NESTED_OPT_FMT, name); + + depth++; + while (--opt_ct >= 0) { + tOptionValue const * ovp = *(opt_list++); + + prt_value(fp, depth, NULL, ovp); + } + depth--; + + for (sp_ct = depth; --sp_ct >= 0;) + putc(' ', fp), putc(' ', fp); + fprintf(fp, "\n", name); +} + +/** + * printed a nested/hierarchical value + * + * @param[in] fp file pointer + * @param[in] od option descriptor + * @param[in] save_fl include usage in comments + */ +static void +prt_nested(FILE * fp, tOptDesc * od, save_flags_mask_t save_fl) +{ + int opt_ct; + tArgList * al = od->optCookie; + void ** opt_list; + + if (save_fl & SVFL_USAGE) + fprintf(fp, ao_name_use_fmt, od->pz_Name, od->pzText); + + /* + * Never show a default value if a hierarchical value is empty. + */ + if (UNUSED_OPT(od) || (al == NULL)) + return; + + opt_ct = al->useCt; + opt_list = (void **)al->apzArgs; + + if (opt_ct <= 0) + return; + + do { + tOptionValue const * base = *(opt_list++); + tOptionValue const * ovp = optionGetValue(base, NULL); + + if (ovp == NULL) + continue; + + fprintf(fp, NESTED_OPT_FMT, od->pz_Name); + + do { + prt_value(fp, 1, od, ovp); + + } while (ovp = optionNextValue(base, ovp), + ovp != NULL); + + fprintf(fp, "\n", od->pz_Name); + } while (--opt_ct > 0); +} + +/** + * remove the current program settings + * + * @param[in] opts the program options structure + * @param[in] fname the save file name + */ +static void +remove_settings(tOptions * opts, char const * fname) +{ + size_t const name_len = strlen(opts->pzProgName); + tmap_info_t map_info; + char * text = text_mmap(fname, PROT_READ|PROT_WRITE, MAP_PRIVATE, &map_info); + char * scan = text; + + for (;;) { + char * next = scan = strstr(scan, zCfgProg); + if (scan == NULL) + goto leave; + + scan = SPN_WHITESPACE_CHARS(scan + zCfgProg_LEN); + if ( (strneqvcmp(scan, opts->pzProgName, (int)name_len) == 0) + && (IS_END_XML_TOKEN_CHAR(scan[name_len])) ) { + + scan = next; + break; + } + } + + /* + * If not NULL, "scan" points to the "pzProgName, fname); + fprintf(stderr, zNoCreat, errno, strerror(errno), fname); + if (free_name) + AGFREE(fname); + return fp; + } + + if (free_name) + AGFREE(fname); + } + + do { + struct stat sbuf; + if (fstat(fileno(fp), &sbuf) < 0) + break; + + if (sbuf.st_size > zPresetFile_LEN) { + /* non-zero size implies save_fl is non-zero */ + fprintf(fp, zFmtProg, opts->pzProgName); + return fp; + } + } while (false); + + /* + * We have a new file. Insert a header + */ + fputs("# ", fp); + { + char const * e = strchr(opts->pzUsageTitle, NL); + if (e++ != NULL) + fwrite(opts->pzUsageTitle, 1, e - opts->pzUsageTitle, fp); + } + + { + time_t cur_time = time(NULL); + char * time_str = ctime(&cur_time); + + fprintf(fp, zPresetFile, time_str); +#ifdef HAVE_ALLOCATED_CTIME + /* + * The return values for ctime(), localtime(), and gmtime() + * normally point to static data that is overwritten by each call. + * The test to detect allocated ctime, so we leak the memory. + */ + AGFREE(time_str); +#endif + } + if (save_fl != 0) + fprintf(fp, zFmtProg, opts->pzProgName); + return fp; +} + +/** + * print option without an arg + * + * @param[in] fp file pointer + * @param[in] vod value option descriptor + * @param[in] pod primary option descriptor + * @param[in] save_fl include usage in comments + */ +static void +prt_no_arg_opt(FILE * fp, tOptDesc * vod, tOptDesc * pod, save_flags_mask_t save_fl) +{ + /* + * The aliased to argument indicates whether or not the option + * is "disabled". However, the original option has the name + * string, so we get that there, not with "vod". + */ + char const * pznm = + (DISABLED_OPT(vod)) ? pod->pz_DisableName : pod->pz_Name; + /* + * If the option was disabled and the disablement name is NULL, + * then the disablement was caused by aliasing. + * Use the name as the string to emit. + */ + if (pznm == NULL) + pznm = pod->pz_Name; + + if (save_fl & SVFL_USAGE) + fprintf(fp, ao_name_use_fmt, pod->pz_Name, pod->pzText); + if (UNUSED_OPT(pod) && (save_fl & SVFL_DEFAULT)) + fputs(ao_default_use, fp); + + fprintf(fp, "%s\n", pznm); +} + +/** + * print the string valued argument(s). + * + * @param[in] fp file pointer + * @param[in] od value option descriptor + * @param[in] save_fl include usage in comments + */ +static void +prt_str_arg(FILE * fp, tOptDesc * od, save_flags_mask_t save_fl) +{ + if (UNUSED_OPT(od) || ((od->fOptState & OPTST_STACKED) == 0)) { + char const * arg = od->optArg.argString; + if (arg == NULL) + arg = "''"; + prt_entry(fp, od, arg, save_fl); + + } else { + tArgList * pAL = (tArgList *)od->optCookie; + int uct = pAL->useCt; + char const ** ppz = pAL->apzArgs; + + /* + * un-disable multiple copies of disabled options. + */ + if (uct > 1) + od->fOptState &= ~OPTST_DISABLED; + + while (uct-- > 0) { + prt_entry(fp, od, *(ppz++), save_fl); + save_fl &= ~SVFL_USAGE; + } + } +} + +/** + * print the string value of an enumeration. + * + * @param[in] fp the file pointer to write to + * @param[in] od the option descriptor with the enumerated value + * @param[in] save_fl include usage in comments + */ +static void +prt_enum_arg(FILE * fp, tOptDesc * od, save_flags_mask_t save_fl) +{ + uintptr_t val = od->optArg.argEnum; + + /* + * This is a magic incantation that will convert the + * bit flag values back into a string suitable for printing. + */ + (*(od->pOptProc))(OPTPROC_RETURN_VALNAME, od); + prt_entry(fp, od, VOIDP(od->optArg.argString), save_fl); + + od->optArg.argEnum = val; +} + +/** + * Print the bits set in a bit mask option. + * + * We call the option handling function with a magic value for + * the options pointer and it allocates and fills in the string. + * We print that with a call to prt_entry(). + * + * @param[in] fp the file pointer to write to + * @param[in] od the option descriptor with a bit mask value type + * @param[in] save_fl include usage in comments + */ +static void +prt_set_arg(FILE * fp, tOptDesc * od, save_flags_mask_t save_fl) +{ + char * list = optionMemberList(od); + size_t len = strlen(list); + char * buf = (char *)AGALOC(len + 3, "dir name"); + *buf= '='; + memcpy(buf+1, list, len + 1); + prt_entry(fp, od, buf, save_fl); + AGFREE(buf); + AGFREE(list); +} + +/** + * figure out what the option file name argument is. + * If one can be found, call prt_entry() to emit it. + * + * @param[in] fp the file pointer to write to. + * @param[in] od the option descriptor with a bit mask value type + * @param[in] opts the program options descriptor + * @param[in] save_fl include usage in comments + */ +static void +prt_file_arg(FILE * fp, tOptDesc * od, tOptions * opts, save_flags_mask_t save_fl) +{ + /* + * If the cookie is not NULL, then it has the file name, period. + * Otherwise, if we have a non-NULL string argument, then.... + */ + if (od->optCookie != NULL) + prt_entry(fp, od, od->optCookie, save_fl); + + else if (HAS_originalOptArgArray(opts)) { + char const * orig = + opts->originalOptArgArray[od->optIndex].argString; + + if (od->optArg.argString == orig) { + if (save_fl) + fprintf(fp, ao_name_use_fmt, od->pz_Name, od->pzText); + return; + } + + prt_entry(fp, od, od->optArg.argString, save_fl); + + } else if (save_fl) + fprintf(fp, ao_name_use_fmt, od->pz_Name, od->pzText); +} + +/*=export_func optionSaveFile + * + * what: saves the option state to a file + * + * arg: tOptions *, opts, program options descriptor + * + * doc: + * + * This routine will save the state of option processing to a file. The name + * of that file can be specified with the argument to the @code{--save-opts} + * option, or by appending the @code{rcfile} attribute to the last + * @code{homerc} attribute. If no @code{rcfile} attribute was specified, it + * will default to @code{.@i{programname}rc}. If you wish to specify another + * file, you should invoke the @code{SET_OPT_SAVE_OPTS(@i{filename})} macro. + * + * The recommend usage is as follows: + * @example + * optionProcess(&progOptions, argc, argv); + * if (i_want_a_non_standard_place_for_this) + * SET_OPT_SAVE_OPTS("myfilename"); + * optionSaveFile(&progOptions); + * @end example + * + * err: + * + * If no @code{homerc} file was specified, this routine will silently return + * and do nothing. If the output file cannot be created or updated, a message + * will be printed to @code{stderr} and the routine will return. +=*/ +void +optionSaveFile(tOptions * opts) +{ + tOptDesc * od; + int ct; + FILE * fp; + save_flags_mask_t save_flags = SVFL_NONE; + + do { + char * temp_str; + char const * dir = opts->pOptDesc[ opts->specOptIdx.save_opts ].optArg.argString; + size_t flen; + + if (dir == NULL) + break; + temp_str = strchr(dir, '>'); + if (temp_str == NULL) + break; + if (temp_str[1] == '>') + save_flags = SVFL_UPDATE; + flen = (temp_str - dir); + if (flen == 0) + break; + temp_str = AGALOC(flen + 1, "flag search str"); + memcpy(temp_str, dir, flen); + temp_str[flen] = NUL; + save_flags |= save_flags_str2mask(temp_str, SVFL_NONE); + AGFREE(temp_str); + } while (false); + + fp = open_sv_file(opts, save_flags & SVFL_UPDATE); + if (fp == NULL) + return; + + /* + * FOR each of the defined options, ... + */ + ct = opts->presetOptCt; + od = opts->pOptDesc; + do { + tOptDesc * vod; + + /* + * Equivalenced options get picked up when the equivalenced-to + * option is processed. And do not save options with any state + * bits in the DO_NOT_SAVE collection + * + * ** option cannot be preset + * #define OPTST_NO_INIT 0x0000100U + * ** disable from cmd line + * #define OPTST_NO_COMMAND 0x2000000U + * ** alias for other option + * #define OPTST_ALIAS 0x8000000U + */ + if ((od->fOptState & OPTST_DO_NOT_SAVE_MASK) != 0) + continue; + + if ( (od->optEquivIndex != NO_EQUIVALENT) + && (od->optEquivIndex != od->optIndex)) + continue; + + if (UNUSED_OPT(od) && ((save_flags & SVFL_USAGE_DEFAULT_MASK) == SVFL_NONE)) + continue; + + /* + * The option argument data are found at the equivalenced-to option, + * but the actual option argument type comes from the original + * option descriptor. Be careful! + */ + vod = ((od->fOptState & OPTST_EQUIVALENCE) != 0) + ? (opts->pOptDesc + od->optActualIndex) : od; + + switch (OPTST_GET_ARGTYPE(od->fOptState)) { + case OPARG_TYPE_NONE: + prt_no_arg_opt(fp, vod, od, save_flags); + break; + + case OPARG_TYPE_NUMERIC: + prt_entry(fp, vod, VOIDP(vod->optArg.argInt), save_flags); + break; + + case OPARG_TYPE_STRING: + prt_str_arg(fp, vod, save_flags); + break; + + case OPARG_TYPE_ENUMERATION: + prt_enum_arg(fp, vod, save_flags); + break; + + case OPARG_TYPE_MEMBERSHIP: + prt_set_arg(fp, vod, save_flags); + break; + + case OPARG_TYPE_BOOLEAN: + prt_entry(fp, vod, vod->optArg.argBool ? "true" : "false", save_flags); + break; + + case OPARG_TYPE_HIERARCHY: + prt_nested(fp, vod, save_flags); + break; + + case OPARG_TYPE_FILE: + prt_file_arg(fp, vod, opts, save_flags); + break; + + default: + break; /* cannot handle - skip it */ + } + } while (od++, (--ct > 0)); + + fclose(fp); +} +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/save.c */ diff --git a/autoopts/sort.c b/autoopts/sort.c new file mode 100644 index 0000000..b4bd5cb --- /dev/null +++ b/autoopts/sort.c @@ -0,0 +1,326 @@ + +/* + * \file sort.c + * + * This module implements argument sorting. + * + * @addtogroup autoopts + * @{ + */ +/* + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +/* + * "must_arg" and "maybe_arg" are really similar. The biggest + * difference is that "may" will consume the next argument only if it + * does not start with a hyphen and "must" will consume it, hyphen or not. + */ +static tSuccess +must_arg(tOptions * opts, char * arg_txt, tOptState * pOS, + char ** opt_txt, uint32_t * opt_idx) +{ + /* + * An option argument is required. Long options can either have + * a separate command line argument, or an argument attached by + * the '=' character. Figure out which. + */ + switch (pOS->optType) { + case TOPT_SHORT: + /* + * See if an arg string follows the flag character. If not, + * the next arg must be the option argument. + */ + if (*arg_txt != NUL) + return SUCCESS; + break; + + case TOPT_LONG: + /* + * See if an arg string has already been assigned (glued on + * with an `=' character). If not, the next is the opt arg. + */ + if (pOS->pzOptArg != NULL) + return SUCCESS; + break; + + default: + return FAILURE; + } + if (opts->curOptIdx >= opts->origArgCt) + return FAILURE; + + opt_txt[ (*opt_idx)++ ] = opts->origArgVect[ (opts->curOptIdx)++ ]; + return SUCCESS; +} + +static tSuccess +maybe_arg(tOptions * opts, char * arg_txt, tOptState * pOS, + char ** opt_txt, uint32_t * opt_idx) +{ + /* + * An option argument is optional. + */ + switch (pOS->optType) { + case TOPT_SHORT: + /* + * IF nothing is glued on after the current flag character, + * THEN see if there is another argument. If so and if it + * does *NOT* start with a hyphen, then it is the option arg. + */ + if (*arg_txt != NUL) + return SUCCESS; + break; + + case TOPT_LONG: + /* + * Look for an argument if we don't already have one (glued on + * with a `=' character) + */ + if (pOS->pzOptArg != NULL) + return SUCCESS; + break; + + default: + return FAILURE; + } + if (opts->curOptIdx >= opts->origArgCt) + return PROBLEM; + + arg_txt = opts->origArgVect[ opts->curOptIdx ]; + if (*arg_txt != '-') + opt_txt[ (*opt_idx)++ ] = opts->origArgVect[ (opts->curOptIdx)++ ]; + return SUCCESS; +} + +/* + * Process a string of short options glued together. If the last one + * does or may take an argument, the do the argument processing and leave. + */ +static tSuccess +short_opt_ck(tOptions * opts, char * arg_txt, tOptState * pOS, + char ** opt_txt, uint32_t * opt_idx) +{ + while (*arg_txt != NUL) { + if (FAILED(opt_find_short(opts, (uint8_t)*arg_txt, pOS))) + return FAILURE; + + /* + * See if we can have an arg. + */ + if (OPTST_GET_ARGTYPE(pOS->pOD->fOptState) == OPARG_TYPE_NONE) { + arg_txt++; + + } else if (pOS->pOD->fOptState & OPTST_ARG_OPTIONAL) { + /* + * Take an argument if it is not attached and it does not + * start with a hyphen. + */ + if (arg_txt[1] != NUL) + return SUCCESS; + + arg_txt = opts->origArgVect[ opts->curOptIdx ]; + if (*arg_txt != '-') + opt_txt[ (*opt_idx)++ ] = + opts->origArgVect[ (opts->curOptIdx)++ ]; + return SUCCESS; + + } else { + /* + * IF we need another argument, be sure it is there and + * take it. + */ + if (arg_txt[1] == NUL) { + if (opts->curOptIdx >= opts->origArgCt) + return FAILURE; + opt_txt[ (*opt_idx)++ ] = + opts->origArgVect[ (opts->curOptIdx)++ ]; + } + return SUCCESS; + } + } + return SUCCESS; +} + +/* + * If the program wants sorted options (separated operands and options), + * then this routine will to the trick. + */ +static void +optionSort(tOptions * opts) +{ + char ** opt_txt; + char ** ppzOpds; + uint32_t optsIdx = 0; + uint32_t opdsIdx = 0; + + tOptState os = OPTSTATE_INITIALIZER(DEFINED); + + /* + * Disable for POSIX conformance, or if there are no operands. + */ + if ( (getenv("POSIXLY_CORRECT") != NULL) + || NAMED_OPTS(opts)) + return; + + /* + * Make sure we can allocate two full-sized arg vectors. + */ + opt_txt = malloc(opts->origArgCt * sizeof(char *)); + if (opt_txt == NULL) + goto exit_no_mem; + + ppzOpds = malloc(opts->origArgCt * sizeof(char *)); + if (ppzOpds == NULL) { + free(opt_txt); + goto exit_no_mem; + } + + opts->curOptIdx = 1; + opts->pzCurOpt = NULL; + + /* + * Now, process all the options from our current position onward. + * (This allows interspersed options and arguments for the few + * non-standard programs that require it.) + */ + for (;;) { + char * arg_txt; + tSuccess res; + + /* + * If we're out of arguments, we're done. Join the option and + * operand lists into the original argument vector. + */ + if (opts->curOptIdx >= opts->origArgCt) { + errno = 0; + goto joinLists; + } + + arg_txt = opts->origArgVect[ opts->curOptIdx ]; + if (*arg_txt != '-') { + ppzOpds[ opdsIdx++ ] = opts->origArgVect[ (opts->curOptIdx)++ ]; + continue; + } + + switch (arg_txt[1]) { + case NUL: + /* + * A single hyphen is an operand. + */ + ppzOpds[ opdsIdx++ ] = opts->origArgVect[ (opts->curOptIdx)++ ]; + continue; + + case '-': + /* + * Two consecutive hypens. Put them on the options list and then + * _always_ force the remainder of the arguments to be operands. + */ + if (arg_txt[2] == NUL) { + opt_txt[ optsIdx++ ] = + opts->origArgVect[ (opts->curOptIdx)++ ]; + goto restOperands; + } + res = opt_find_long(opts, arg_txt+2, &os); + break; + + default: + /* + * If short options are not allowed, then do long + * option processing. Otherwise the character must be a + * short (i.e. single character) option. + */ + if ((opts->fOptSet & OPTPROC_SHORTOPT) == 0) { + res = opt_find_long(opts, arg_txt+1, &os); + } else { + res = opt_find_short(opts, (uint8_t)arg_txt[1], &os); + } + break; + } + if (FAILED(res)) { + errno = EINVAL; + goto freeTemps; + } + + /* + * We've found an option. Add the argument to the option list. + * Next, we have to see if we need to pull another argument to be + * used as the option argument. + */ + opt_txt[ optsIdx++ ] = opts->origArgVect[ (opts->curOptIdx)++ ]; + + if (OPTST_GET_ARGTYPE(os.pOD->fOptState) == OPARG_TYPE_NONE) { + /* + * No option argument. If we have a short option here, + * then scan for short options until we get to the end + * of the argument string. + */ + if ( (os.optType == TOPT_SHORT) + && FAILED(short_opt_ck(opts, arg_txt+2, &os, opt_txt, + &optsIdx)) ) { + errno = EINVAL; + goto freeTemps; + } + + } else if (os.pOD->fOptState & OPTST_ARG_OPTIONAL) { + switch (maybe_arg(opts, arg_txt+2, &os, opt_txt, &optsIdx)) { + case FAILURE: errno = EIO; goto freeTemps; + case PROBLEM: errno = 0; goto joinLists; + } + + } else { + switch (must_arg(opts, arg_txt+2, &os, opt_txt, &optsIdx)) { + case PROBLEM: + case FAILURE: errno = EIO; goto freeTemps; + } + } + } /* for (;;) */ + + restOperands: + while (opts->curOptIdx < opts->origArgCt) + ppzOpds[ opdsIdx++ ] = opts->origArgVect[ (opts->curOptIdx)++ ]; + + joinLists: + if (optsIdx > 0) + memcpy(opts->origArgVect + 1, opt_txt, + (size_t)optsIdx * sizeof(char *)); + if (opdsIdx > 0) + memcpy(opts->origArgVect + 1 + optsIdx, ppzOpds, + (size_t)opdsIdx * sizeof(char *)); + + freeTemps: + free(opt_txt); + free(ppzOpds); + return; + + exit_no_mem: + errno = ENOMEM; + return; +} + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/sort.c */ diff --git a/autoopts/stack.c b/autoopts/stack.c new file mode 100644 index 0000000..39a328a --- /dev/null +++ b/autoopts/stack.c @@ -0,0 +1,267 @@ + +/** + * \file stack.c + * + * This is a special option processing routine that will save the + * argument to an option in a FIFO queue. + * + * @addtogroup autoopts + * @{ + */ +/* + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +#ifdef WITH_LIBREGEX +# include REGEX_HEADER +#endif + +/*=export_func optionUnstackArg + * private: + * + * what: Remove option args from a stack + * arg: + tOptions * + opts + program options descriptor + + * arg: + tOptDesc * + od + the descriptor for this arg + + * + * doc: + * Invoked for options that are equivalenced to stacked options. +=*/ +void +optionUnstackArg(tOptions * opts, tOptDesc * od) +{ + tArgList * arg_list; + + if (INQUERY_CALL(opts, od)) + return; + + arg_list = (tArgList *)od->optCookie; + + /* + * IF we don't have any stacked options, + * THEN indicate that we don't have any of these options + */ + if (arg_list == NULL) { + od->fOptState &= OPTST_PERSISTENT_MASK; + if ((od->fOptState & OPTST_INITENABLED) == 0) + od->fOptState |= OPTST_DISABLED; + return; + } + +#ifdef WITH_LIBREGEX + { + regex_t re; + int i, ct, dIdx; + + if (regcomp(&re, od->optArg.argString, REG_NOSUB) != 0) + return; + + /* + * search the list for the entry(s) to remove. Entries that + * are removed are *not* copied into the result. The source + * index is incremented every time. The destination only when + * we are keeping a define. + */ + for (i = 0, dIdx = 0, ct = arg_list->useCt; --ct >= 0; i++) { + char const * pzSrc = arg_list->apzArgs[ i ]; + char * pzEq = strchr(pzSrc, '='); + int res; + + + if (pzEq != NULL) + *pzEq = NUL; + + res = regexec(&re, pzSrc, (size_t)0, NULL, 0); + switch (res) { + case 0: + /* + * Remove this entry by reducing the in-use count + * and *not* putting the string pointer back into + * the list. + */ + AGFREE(pzSrc); + arg_list->useCt--; + break; + + default: + case REG_NOMATCH: + if (pzEq != NULL) + *pzEq = '='; + + /* + * IF we have dropped an entry + * THEN we have to move the current one. + */ + if (dIdx != i) + arg_list->apzArgs[ dIdx ] = pzSrc; + dIdx++; + } + } + + regfree(&re); + } +#else /* not WITH_LIBREGEX */ + { + int i, ct, dIdx; + + /* + * search the list for the entry(s) to remove. Entries that + * are removed are *not* copied into the result. The source + * index is incremented every time. The destination only when + * we are keeping a define. + */ + for (i = 0, dIdx = 0, ct = arg_list->useCt; --ct >= 0; i++) { + const char * pzSrc = arg_list->apzArgs[ i ]; + char * pzEq = strchr(pzSrc, '='); + + if (pzEq != NULL) + *pzEq = NUL; + + if (strcmp(pzSrc, od->optArg.argString) == 0) { + /* + * Remove this entry by reducing the in-use count + * and *not* putting the string pointer back into + * the list. + */ + AGFREE(pzSrc); + arg_list->useCt--; + } else { + if (pzEq != NULL) + *pzEq = '='; + + /* + * IF we have dropped an entry + * THEN we have to move the current one. + */ + if (dIdx != i) + arg_list->apzArgs[ dIdx ] = pzSrc; + dIdx++; + } + } + } +#endif /* WITH_LIBREGEX */ + /* + * IF we have unstacked everything, + * THEN indicate that we don't have any of these options + */ + if (arg_list->useCt == 0) { + od->fOptState &= OPTST_PERSISTENT_MASK; + if ((od->fOptState & OPTST_INITENABLED) == 0) + od->fOptState |= OPTST_DISABLED; + AGFREE(arg_list); + od->optCookie = NULL; + } +} + + +/* + * Put an entry into an argument list. The first argument points to + * a pointer to the argument list structure. It gets passed around + * as an opaque address. + */ +static void +addArgListEntry(void ** ppAL, void * entry) +{ + tArgList * pAL = *(void **)ppAL; + + /* + * IF we have never allocated one of these, + * THEN allocate one now + */ + if (pAL == NULL) { + pAL = (tArgList *)AGALOC(sizeof(*pAL), "new option arg stack"); + if (pAL == NULL) + return; + pAL->useCt = 0; + pAL->allocCt = MIN_ARG_ALLOC_CT; + *ppAL = VOIDP(pAL); + } + + /* + * ELSE if we are out of room + * THEN make it bigger + */ + else if (pAL->useCt >= pAL->allocCt) { + size_t sz = sizeof(*pAL); + pAL->allocCt += INCR_ARG_ALLOC_CT; + + /* + * The base structure contains space for MIN_ARG_ALLOC_CT + * pointers. We subtract it off to find our augment size. + */ + sz += sizeof(char *) * ((size_t)pAL->allocCt - MIN_ARG_ALLOC_CT); + pAL = (tArgList *)AGREALOC(VOIDP(pAL), sz, "expanded opt arg stack"); + if (pAL == NULL) + return; + *ppAL = VOIDP(pAL); + } + + /* + * Insert the new argument into the list + */ + pAL->apzArgs[ (pAL->useCt)++ ] = entry; +} + + +/*=export_func optionStackArg + * private: + * + * what: put option args on a stack + * arg: + tOptions * + opts + program options descriptor + + * arg: + tOptDesc * + od + the descriptor for this arg + + * + * doc: + * Keep an entry-ordered list of option arguments. +=*/ +void +optionStackArg(tOptions * opts, tOptDesc * od) +{ + char * pz; + + if (INQUERY_CALL(opts, od)) + return; + + if ((od->fOptState & OPTST_RESET) != 0) { + tArgList * arg_list = od->optCookie; + int ix; + if (arg_list == NULL) + return; + + ix = arg_list->useCt; + while (--ix >= 0) + AGFREE(arg_list->apzArgs[ix]); + AGFREE(arg_list); + + } else { + if (od->optArg.argString == NULL) + return; + + AGDUPSTR(pz, od->optArg.argString, "stack arg"); + addArgListEntry(&(od->optCookie), VOIDP(pz)); + } +} +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/stack.c */ diff --git a/autoopts/stdnoreturn.in.h b/autoopts/stdnoreturn.in.h new file mode 100644 index 0000000..bf46c08 --- /dev/null +++ b/autoopts/stdnoreturn.in.h @@ -0,0 +1,60 @@ +/* A substitute for ISO C11 . + + Copyright 2012-2018 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1, 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program; if not, see . */ + +/* Written by Paul Eggert. */ + +#ifndef noreturn + +/* ISO C11 for platforms that lack it. + + References: + ISO C11 (latest free draft + ) + section 7.23 */ + +/* The definition of _Noreturn is copied here. */ + +#if 1200 <= _MSC_VER || defined __CYGWIN__ +/* On MSVC, standard include files contain declarations like + __declspec (noreturn) void abort (void); + "#define noreturn _Noreturn" would cause this declaration to be rewritten + to the invalid + __declspec (__declspec (noreturn)) void abort (void); + + Similarly, on Cygwin, standard include files contain declarations like + void __cdecl abort (void) __attribute__ ((noreturn)); + "#define noreturn _Noreturn" would cause this declaration to be rewritten + to the invalid + void __cdecl abort (void) __attribute__ ((__attribute__ ((__noreturn__)))); + + Instead, define noreturn to empty, so that such declarations are rewritten to + __declspec () void abort (void); + or + void __cdecl abort (void) __attribute__ (()); + respectively. This gives up on noreturn's advice to the compiler but at + least it is valid code. */ +# define noreturn /*empty*/ +#else +# define noreturn _Noreturn +#endif + +/* Did he ever return? + No he never returned + And his fate is still unlearn'd ... + -- Steiner J, Hawes BL. M.T.A. (1949) */ + +#endif /* noreturn */ diff --git a/autoopts/strequate.3 b/autoopts/strequate.3 new file mode 100644 index 0000000..362c439 --- /dev/null +++ b/autoopts/strequate.3 @@ -0,0 +1,32 @@ +.TH strequate 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (strequate.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +strequate - map a list of characters to the same value +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +void \fBstrequate\fP(char const * \fIch_list\fP); +.sp 1 +.SH DESCRIPTION +Each character in the input string get mapped to the first character +in the string. +This function name is mapped to option_strequate so as to not conflict +with the POSIX name space. +.TP +.IR ch_list +characters to equivalence +.sp 1 +.SH ERRORS +none. +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +ao_string_tokenize(3), configFileLoad(3), optionFileLoad(3), optionFindNextValue(3), optionFindValue(3), optionFree(3), optionGetValue(3), optionLoadLine(3), optionMemberList(3), optionNextValue(3), optionOnlyUsage(3), optionPrintVersion(3), optionPrintVersionAndReturn(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), streqvcmp(3), streqvmap(3), strneqvcmp(3), strtransform(3), diff --git a/autoopts/streqvcmp.3 b/autoopts/streqvcmp.3 new file mode 100644 index 0000000..87b7ea2 --- /dev/null +++ b/autoopts/streqvcmp.3 @@ -0,0 +1,39 @@ +.TH streqvcmp 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (streqvcmp.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +streqvcmp - compare two strings with an equivalence mapping +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +int \fBstreqvcmp\fP(char const * \fIstr1\fP, char const * \fIstr2\fP); +.sp 1 +.SH DESCRIPTION +Using a character mapping, two strings are compared for "equivalence". +Each input character is mapped to a comparison character and the +mapped-to characters are compared for the two NUL terminated input strings. +This function name is mapped to option_streqvcmp so as to not conflict +with the POSIX name space. +.TP +.IR str1 +first string +.TP +.IR str2 +second string +.sp 1 +.SH RETURN VALUE +the difference between two differing characters +.sp 1 +.SH ERRORS +none checked. Caller responsible for seg faults. +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +ao_string_tokenize(3), configFileLoad(3), optionFileLoad(3), optionFindNextValue(3), optionFindValue(3), optionFree(3), optionGetValue(3), optionLoadLine(3), optionMemberList(3), optionNextValue(3), optionOnlyUsage(3), optionPrintVersion(3), optionPrintVersionAndReturn(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), strequate(3), streqvmap(3), strneqvcmp(3), strtransform(3), diff --git a/autoopts/streqvcmp.c b/autoopts/streqvcmp.c new file mode 100644 index 0000000..53477d6 --- /dev/null +++ b/autoopts/streqvcmp.c @@ -0,0 +1,284 @@ + +/** + * \file streqvcmp.c + * + * String Equivalence Comparison + * + * These routines allow any character to be mapped to any other + * character before comparison. In processing long option names, + * the characters "-", "_" and "^" all need to be equivalent + * (because they are treated so by different development environments). + * + * @addtogroup autoopts + * @{ + */ +/* + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + * + * This array is designed for mapping upper and lower case letter + * together for a case independent comparison. The mappings are + * based upon ascii character sequences. + */ + static unsigned char charmap[] = { + NUL, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, '\a', + '\b', '\t', NL, '\v', '\f', '\r', 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + + ' ', '!', '"', '#', '$', '%', '&', '\'', + '(', ')', '*', '+', ',', '-', '.', '/', + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', ':', ';', '<', '=', '>', '?', + + '@', 'a', 'b', 'c', 'd', 'e', 'f', 'g', + 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', + 'x', 'y', 'z', '[', '\\', ']', '^', '_', + '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', + 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', + 'x', 'y', 'z', '{', '|', '}', '~', 0x7f, + + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, + 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, + 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, + 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, + 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, + + 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, + 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, + 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, + 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, + 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, + 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, + 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, + 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, +}; + + +/*=export_func strneqvcmp + * + * what: compare two strings with an equivalence mapping + * + * arg: + char const * + str1 + first string + + * arg: + char const * + str2 + second string + + * arg: + int + ct + compare length + + * + * ret_type: int + * ret_desc: the difference between two differing characters + * + * doc: + * + * Using a character mapping, two strings are compared for "equivalence". + * Each input character is mapped to a comparison character and the + * mapped-to characters are compared for the two NUL terminated input strings. + * The comparison is limited to @code{ct} bytes. + * This function name is mapped to option_strneqvcmp so as to not conflict + * with the POSIX name space. + * + * err: none checked. Caller responsible for seg faults. +=*/ +int +strneqvcmp(char const * s1, char const * s2, int ct) +{ + for (; ct > 0; --ct) { + unsigned char u1 = (unsigned char) *s1++; + unsigned char u2 = (unsigned char) *s2++; + int dif; + if (u1 == u2) { + if (u1 == NUL) + return 0; + continue; + } + + dif = charmap[ u1 ] - charmap[ u2 ]; + + if (dif != 0) + return dif; + + if (u1 == NUL) + return 0; + } + + return 0; +} + + +/*=export_func streqvcmp + * + * what: compare two strings with an equivalence mapping + * + * arg: + char const * + str1 + first string + + * arg: + char const * + str2 + second string + + * + * ret_type: int + * ret_desc: the difference between two differing characters + * + * doc: + * + * Using a character mapping, two strings are compared for "equivalence". + * Each input character is mapped to a comparison character and the + * mapped-to characters are compared for the two NUL terminated input strings. + * This function name is mapped to option_streqvcmp so as to not conflict + * with the POSIX name space. + * + * err: none checked. Caller responsible for seg faults. +=*/ +int +streqvcmp(char const * s1, char const * s2) +{ + for (;;) { + unsigned char u1 = (unsigned char) *s1++; + unsigned char u2 = (unsigned char) *s2++; + int dif; + if (u1 == u2) { + if (u1 == NUL) + return 0; + continue; + } + + dif = charmap[ u1 ] - charmap[ u2 ]; + + if (dif != 0) + return dif; + + if (u1 == NUL) + return 0; + } +} + + +/*=export_func streqvmap + * + * what: Set the character mappings for the streqv functions + * + * arg: + char + from + Input character + + * arg: + char + to + Mapped-to character + + * arg: + int + ct + compare length + + * + * doc: + * + * Set the character mapping. If the count (@code{ct}) is set to zero, then + * the map is cleared by setting all entries in the map to their index + * value. Otherwise, the "@code{From}" character is mapped to the "@code{To}" + * character. If @code{ct} is greater than 1, then @code{From} and @code{To} + * are incremented and the process repeated until @code{ct} entries have been + * set. For example, + * @example + * streqvmap('a', 'A', 26); + * @end example + * @noindent + * will alter the mapping so that all English lower case letters + * will map to upper case. + * + * This function name is mapped to option_streqvmap so as to not conflict + * with the POSIX name space. + * + * err: none. +=*/ +void +streqvmap(char from, char to, int ct) +{ + if (ct == 0) { + ct = sizeof(charmap) - 1; + do { + charmap[ct] = (unsigned char)ct; + } while (--ct >= 0); + } + + else { + unsigned int i_to = (int)to & 0xFF; + unsigned int i_from = (int)from & 0xFF; + + do { + charmap[i_from] = (unsigned char)i_to; + i_from++; + i_to++; + if ((i_from >= sizeof(charmap)) || (i_to >= sizeof(charmap))) + break; + } while (--ct > 0); + } +} + + +/*=export_func strequate + * + * what: map a list of characters to the same value + * + * arg: + char const * + ch_list + characters to equivalence + + * + * doc: + * + * Each character in the input string get mapped to the first character + * in the string. + * This function name is mapped to option_strequate so as to not conflict + * with the POSIX name space. + * + * err: none. +=*/ +void +strequate(char const * s) +{ + if ((s != NULL) && (*s != NUL)) { + unsigned char equiv = (unsigned char)*s; + while (*s != NUL) + charmap[(unsigned char)*(s++)] = equiv; + } +} + + +/*=export_func strtransform + * + * what: convert a string into its mapped-to value + * + * arg: + char * + dest + output string + + * arg: + char const * + src + input string + + * + * doc: + * + * Each character in the input string is mapped and the mapped-to + * character is put into the output. + * This function name is mapped to option_strtransform so as to not conflict + * with the POSIX name space. + * + * The source and destination may be the same. + * + * err: none. +=*/ +void +strtransform(char * d, char const * s) +{ + do { + *(d++) = (char)charmap[(unsigned char)*s]; + } while (*(s++) != NUL); +} + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/streqvcmp.c */ diff --git a/autoopts/streqvmap.3 b/autoopts/streqvmap.3 new file mode 100644 index 0000000..a4aad67 --- /dev/null +++ b/autoopts/streqvmap.3 @@ -0,0 +1,48 @@ +.TH streqvmap 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (streqvmap.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +streqvmap - Set the character mappings for the streqv functions +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +void \fBstreqvmap\fP(char \fIfrom\fP, char \fIto\fP, int \fIct\fP); +.sp 1 +.SH DESCRIPTION +Set the character mapping. If the count (\fBct\fP) is set to zero, then +the map is cleared by setting all entries in the map to their index +value. Otherwise, the "\fBFrom\fP" character is mapped to the "\fBTo\fP" +character. If \fBct\fP is greater than 1, then \fBFrom\fP and \fBTo\fP +are incremented and the process repeated until \fBct\fP entries have been +set. For example, +.nf + streqvmap('a', 'A', 26); +.fi +will alter the mapping so that all English lower case letters +will map to upper case. + +This function name is mapped to option_streqvmap so as to not conflict +with the POSIX name space. +.TP +.IR from +Input character +.TP +.IR to +Mapped-to character +.TP +.IR ct +compare length +.sp 1 +.SH ERRORS +none. +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +ao_string_tokenize(3), configFileLoad(3), optionFileLoad(3), optionFindNextValue(3), optionFindValue(3), optionFree(3), optionGetValue(3), optionLoadLine(3), optionMemberList(3), optionNextValue(3), optionOnlyUsage(3), optionPrintVersion(3), optionPrintVersionAndReturn(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), strequate(3), streqvcmp(3), strneqvcmp(3), strtransform(3), diff --git a/autoopts/strneqvcmp.3 b/autoopts/strneqvcmp.3 new file mode 100644 index 0000000..c123db9 --- /dev/null +++ b/autoopts/strneqvcmp.3 @@ -0,0 +1,43 @@ +.TH strneqvcmp 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (strneqvcmp.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +strneqvcmp - compare two strings with an equivalence mapping +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +int \fBstrneqvcmp\fP(char const * \fIstr1\fP, char const * \fIstr2\fP, int \fIct\fP); +.sp 1 +.SH DESCRIPTION +Using a character mapping, two strings are compared for "equivalence". +Each input character is mapped to a comparison character and the +mapped-to characters are compared for the two NUL terminated input strings. +The comparison is limited to \fBct\fP bytes. +This function name is mapped to option_strneqvcmp so as to not conflict +with the POSIX name space. +.TP +.IR str1 +first string +.TP +.IR str2 +second string +.TP +.IR ct +compare length +.sp 1 +.SH RETURN VALUE +the difference between two differing characters +.sp 1 +.SH ERRORS +none checked. Caller responsible for seg faults. +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +ao_string_tokenize(3), configFileLoad(3), optionFileLoad(3), optionFindNextValue(3), optionFindValue(3), optionFree(3), optionGetValue(3), optionLoadLine(3), optionMemberList(3), optionNextValue(3), optionOnlyUsage(3), optionPrintVersion(3), optionPrintVersionAndReturn(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), strequate(3), streqvcmp(3), streqvmap(3), strtransform(3), diff --git a/autoopts/strtransform.3 b/autoopts/strtransform.3 new file mode 100644 index 0000000..01f6104 --- /dev/null +++ b/autoopts/strtransform.3 @@ -0,0 +1,37 @@ +.TH strtransform 3 2018-08-26 "" "Programmer's Manual" +.\" DO NOT EDIT THIS FILE (strtransform.3) +.\" +.\" It has been AutoGen-ed +.\" From the definitions ./funcs.def +.\" and the template file agman3.tpl +.SH NAME +strtransform - convert a string into its mapped-to value +.sp 1 +.SH SYNOPSIS + +#include <\fIyour-opts.h\fP> +.br +cc [...] -o outfile infile.c -l\fBopts\fP [...] +.sp 1 +void \fBstrtransform\fP(char * \fIdest\fP, char const * \fIsrc\fP); +.sp 1 +.SH DESCRIPTION +Each character in the input string is mapped and the mapped-to +character is put into the output. +This function name is mapped to option_strtransform so as to not conflict +with the POSIX name space. + +The source and destination may be the same. +.TP +.IR dest +output string +.TP +.IR src +input string +.sp 1 +.SH ERRORS +none. +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fIopts\fP library. +.br +ao_string_tokenize(3), configFileLoad(3), optionFileLoad(3), optionFindNextValue(3), optionFindValue(3), optionFree(3), optionGetValue(3), optionLoadLine(3), optionMemberList(3), optionNextValue(3), optionOnlyUsage(3), optionPrintVersion(3), optionPrintVersionAndReturn(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), strequate(3), streqvcmp(3), streqvmap(3), strneqvcmp(3), diff --git a/autoopts/test/Makefile.am b/autoopts/test/Makefile.am new file mode 100644 index 0000000..33633e4 --- /dev/null +++ b/autoopts/test/Makefile.am @@ -0,0 +1,55 @@ +## -*- Mode: Makefile -*- +## +## Makefile.am +## +## Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +libsrc = libopts-@AO_CURRENT@.@AO_REVISION@.@AO_AGE@.tar.gz +EXTRA_DIST = defs.in stdopts.def $(TESTS) +TESTS = \ + alias.test argument.test cfg-edit.test cond.test \ + config.test doc.test enums.test equiv.test \ + errors.test getopt.test handler.test immediate.test \ + keyword.test library.test main.test nested.test \ + nls.test rc.test shell.test stdopts.test \ + time.test usage.test vendor.test vers.test + +getopt.test : ../$(libsrc) +../$(libsrc): + cd .. ; echo $(MAKE) $(libsrc) ; $(MAKE) $(libsrc) >/dev/null 2>&1 + +distclean-local: + @-rm -rf *-testd FAILURES + +check : perm-stamp + +perm-stamp : + @-cd $(srcdir) ; chmod +x *.test 2>/dev/null + +verbose : distclean-local + VERBOSE=true ; export VERBOSE ; \ + $(MAKE) check TESTS="$(TESTS)" + +.PHONY : distclean-local verbose perm-stamp + +# Makefile.am ends here diff --git a/autoopts/test/Makefile.in b/autoopts/test/Makefile.in new file mode 100644 index 0000000..9c45047 --- /dev/null +++ b/autoopts/test/Makefile.in @@ -0,0 +1,901 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 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. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = autoopts/test +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/ag_macros.m4 \ + $(top_srcdir)/config/asm-underscore.m4 \ + $(top_srcdir)/config/extensions.m4 \ + $(top_srcdir)/config/guile.m4 \ + $(top_srcdir)/config/host-cpu-c-abi.m4 \ + $(top_srcdir)/config/lib-ld.m4 \ + $(top_srcdir)/config/lib-link.m4 \ + $(top_srcdir)/config/lib-prefix.m4 \ + $(top_srcdir)/config/libopts.m4 \ + $(top_srcdir)/config/libtool.m4 \ + $(top_srcdir)/config/ltoptions.m4 \ + $(top_srcdir)/config/ltsugar.m4 \ + $(top_srcdir)/config/ltversion.m4 \ + $(top_srcdir)/config/lt~obsolete.m4 \ + $(top_srcdir)/config/onceonly.m4 $(top_srcdir)/config/pkg.m4 \ + $(top_srcdir)/config/snprintfv.m4 \ + $(top_srcdir)/config/stdnoreturn.m4 \ + $(top_srcdir)/config/unlocked-io.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = defs +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red=''; \ + grn=''; \ + lgn=''; \ + blu=''; \ + mgn=''; \ + brg=''; \ + std=''; \ + fi; \ +} +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__recheck_rx = ^[ ]*:recheck:[ ]* +am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* +am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* +# A command that, given a newline-separated list of test names on the +# standard input, print the name of the tests that are to be re-run +# upon "make recheck". +am__list_recheck_tests = $(AWK) '{ \ + recheck = 1; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + { \ + if ((getline line2 < ($$0 ".log")) < 0) \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ + { \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ + { \ + break; \ + } \ + }; \ + if (recheck) \ + print $$0; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# A command that, given a newline-separated list of test names on the +# standard input, create the global log from their .trs and .log files. +am__create_global_log = $(AWK) ' \ +function fatal(msg) \ +{ \ + print "fatal: making $@: " msg | "cat >&2"; \ + exit 1; \ +} \ +function rst_section(header) \ +{ \ + print header; \ + len = length(header); \ + for (i = 1; i <= len; i = i + 1) \ + printf "="; \ + printf "\n\n"; \ +} \ +{ \ + copy_in_global_log = 1; \ + global_test_result = "RUN"; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".trs"); \ + if (line ~ /$(am__global_test_result_rx)/) \ + { \ + sub("$(am__global_test_result_rx)", "", line); \ + sub("[ ]*$$", "", line); \ + global_test_result = line; \ + } \ + else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ + copy_in_global_log = 0; \ + }; \ + if (copy_in_global_log) \ + { \ + rst_section(global_test_result ": " $$0); \ + while ((rc = (getline line < ($$0 ".log"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".log"); \ + print line; \ + }; \ + printf "\n"; \ + }; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# Restructured Text title. +am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } +# Solaris 10 'make', and several other traditional 'make' implementations, +# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it +# by disabling -e (using the XSI extension "set +e") if it's set. +am__sh_e_setup = case $$- in *e*) set +e;; esac +# Default flags passed to test drivers. +am__common_driver_flags = \ + --color-tests "$$am__color_tests" \ + --enable-hard-errors "$$am__enable_hard_errors" \ + --expect-failure "$$am__expect_failure" +# To be inserted before the command running the test. Creates the +# directory for the log if needed. Stores in $dir the directory +# containing $f, in $tst the test, in $log the log. Executes the +# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and +# passes TESTS_ENVIRONMENT. Set up options for the wrapper that +# will run the test scripts (or their associated LOG_COMPILER, if +# thy have one). +am__check_pre = \ +$(am__sh_e_setup); \ +$(am__vpath_adj_setup) $(am__vpath_adj) \ +$(am__tty_colors); \ +srcdir=$(srcdir); export srcdir; \ +case "$@" in \ + */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ + *) am__odir=.;; \ +esac; \ +test "x$$am__odir" = x"." || test -d "$$am__odir" \ + || $(MKDIR_P) "$$am__odir" || exit $$?; \ +if test -f "./$$f"; then dir=./; \ +elif test -f "$$f"; then dir=; \ +else dir="$(srcdir)/"; fi; \ +tst=$$dir$$f; log='$@'; \ +if test -n '$(DISABLE_HARD_ERRORS)'; then \ + am__enable_hard_errors=no; \ +else \ + am__enable_hard_errors=yes; \ +fi; \ +case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ + am__expect_failure=yes;; \ + *) \ + am__expect_failure=no;; \ +esac; \ +$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) +# A shell command to get the names of the tests scripts with any registered +# extension removed (i.e., equivalently, the names of the test logs, with +# the '.log' extension removed). The result is saved in the shell variable +# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, +# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", +# since that might cause problem with VPATH rewrites for suffix-less tests. +# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. +am__set_TESTS_bases = \ + bases='$(TEST_LOGS)'; \ + bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ + bases=`echo $$bases` +RECHECK_LOGS = $(TEST_LOGS) +AM_RECURSIVE_TARGETS = check recheck +TEST_SUITE_LOG = test-suite.log +TEST_EXTENSIONS = @EXEEXT@ .test +am__test_logs1 = $(TESTS:=.log) +am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) +TEST_LOGS = $(am__test_logs2:.test.log=.log) +TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/config/test-driver +TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ + $(TEST_LOG_FLAGS) +am__set_b = \ + case '$@' in \ + */*) \ + case '$*' in \ + */*) b='$*';; \ + *) b=`echo '$@' | sed 's/\.log$$//'`; \ + esac;; \ + *) \ + b='$*';; \ + esac +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/defs.in \ + $(top_srcdir)/config/test-driver +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AGEN5_TESTS = @AGEN5_TESTS@ +AG_LDFLAGS = @AG_LDFLAGS@ +AG_MAJOR_VERSION = @AG_MAJOR_VERSION@ +AG_MINOR_VERSION = @AG_MINOR_VERSION@ +AG_STATIC_AUTOGEN = @AG_STATIC_AUTOGEN@ +AG_TIMEOUT = @AG_TIMEOUT@ +AG_VERSION = @AG_VERSION@ +AG_XML2 = @AG_XML2@ +AGexe = @AGexe@ +AGnam = @AGnam@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AO_AGE = @AO_AGE@ +AO_CURRENT = @AO_CURRENT@ +AO_REVISION = @AO_REVISION@ +AO_TEMPLATE_VERSION = @AO_TEMPLATE_VERSION@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLexe = @CLexe@ +CLnam = @CLnam@ +CONFIG_SHELL = @CONFIG_SHELL@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBUG_ENABLED = @DEBUG_ENABLED@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +DYNAMIC_AG = @DYNAMIC_AG@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_STATIC = @ENABLE_STATIC@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GDexe = @GDexe@ +GDnam = @GDnam@ +GO_AGE = @GO_AGE@ +GO_CURRENT = @GO_CURRENT@ +GO_REVISION = @GO_REVISION@ +GREP = @GREP@ +GUILE_CFLAGS = @GUILE_CFLAGS@ +GUILE_EFFECTIVE_VERSION = @GUILE_EFFECTIVE_VERSION@ +GUILE_LDFLAGS = @GUILE_LDFLAGS@ +GUILE_LIBS = @GUILE_LIBS@ +GUILE_LTLIBS = @GUILE_LTLIBS@ +HOST_CPU = @HOST_CPU@ +HOST_CPU_C_ABI = @HOST_CPU_C_ABI@ +INCLIST = @INCLIST@ +INCSNPRINTFV = @INCSNPRINTFV@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSNPRINTFV = @LIBSNPRINTFV@ +LIBTOOL = @LIBTOOL@ +LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ +LIBXML2_LIBS = @LIBXML2_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +M4_SRC = @M4_SRC@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPTS_TESTDIR = @OPTS_TESTDIR@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSIX_SHELL = @POSIX_SHELL@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STDNORETURN_H = @STDNORETURN_H@ +STRIP = @STRIP@ +TEXI2HTML = @TEXI2HTML@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_aux_dir = @ac_aux_dir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +libsrc = libopts-@AO_CURRENT@.@AO_REVISION@.@AO_AGE@.tar.gz +EXTRA_DIST = defs.in stdopts.def $(TESTS) +TESTS = \ + alias.test argument.test cfg-edit.test cond.test \ + config.test doc.test enums.test equiv.test \ + errors.test getopt.test handler.test immediate.test \ + keyword.test library.test main.test nested.test \ + nls.test rc.test shell.test stdopts.test \ + time.test usage.test vendor.test vers.test + +all: all-am + +.SUFFIXES: +.SUFFIXES: .log .test .test$(EXEEXT) .trs +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu autoopts/test/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu autoopts/test/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +defs: $(top_builddir)/config.status $(srcdir)/defs.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: + + +# Recover from deleted '.trs' file; this should ensure that +# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create +# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells +# to avoid problems with "make -n". +.log.trs: + rm -f $< $@ + $(MAKE) $(AM_MAKEFLAGS) $< + +# Leading 'am--fnord' is there to ensure the list of targets does not +# expand to empty, as could happen e.g. with make check TESTS=''. +am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) +am--force-recheck: + @: + +$(TEST_SUITE_LOG): $(TEST_LOGS) + @$(am__set_TESTS_bases); \ + am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ + redo_bases=`for i in $$bases; do \ + am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ + done`; \ + if test -n "$$redo_bases"; then \ + redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ + redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ + if $(am__make_dryrun); then :; else \ + rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ + fi; \ + fi; \ + if test -n "$$am__remaking_logs"; then \ + echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ + "recursion detected" >&2; \ + elif test -n "$$redo_logs"; then \ + am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ + fi; \ + if $(am__make_dryrun); then :; else \ + st=0; \ + errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ + for i in $$redo_bases; do \ + test -f $$i.trs && test -r $$i.trs \ + || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ + test -f $$i.log && test -r $$i.log \ + || { echo "$$errmsg $$i.log" >&2; st=1; }; \ + done; \ + test $$st -eq 0 || exit 1; \ + fi + @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ + ws='[ ]'; \ + results=`for b in $$bases; do echo $$b.trs; done`; \ + test -n "$$results" || results=/dev/null; \ + all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ + pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ + fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ + skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ + xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ + xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ + error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ + if test `expr $$fail + $$xpass + $$error` -eq 0; then \ + success=true; \ + else \ + success=false; \ + fi; \ + br='==================='; br=$$br$$br$$br$$br; \ + result_count () \ + { \ + if test x"$$1" = x"--maybe-color"; then \ + maybe_colorize=yes; \ + elif test x"$$1" = x"--no-color"; then \ + maybe_colorize=no; \ + else \ + echo "$@: invalid 'result_count' usage" >&2; exit 4; \ + fi; \ + shift; \ + desc=$$1 count=$$2; \ + if test $$maybe_colorize = yes && test $$count -gt 0; then \ + color_start=$$3 color_end=$$std; \ + else \ + color_start= color_end=; \ + fi; \ + echo "$${color_start}# $$desc $$count$${color_end}"; \ + }; \ + create_testsuite_report () \ + { \ + result_count $$1 "TOTAL:" $$all "$$brg"; \ + result_count $$1 "PASS: " $$pass "$$grn"; \ + result_count $$1 "SKIP: " $$skip "$$blu"; \ + result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ + result_count $$1 "FAIL: " $$fail "$$red"; \ + result_count $$1 "XPASS:" $$xpass "$$red"; \ + result_count $$1 "ERROR:" $$error "$$mgn"; \ + }; \ + { \ + echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ + $(am__rst_title); \ + create_testsuite_report --no-color; \ + echo; \ + echo ".. contents:: :depth: 2"; \ + echo; \ + for b in $$bases; do echo $$b; done \ + | $(am__create_global_log); \ + } >$(TEST_SUITE_LOG).tmp || exit 1; \ + mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ + if $$success; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ + fi; \ + echo "$${col}$$br$${std}"; \ + echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ + echo "$${col}$$br$${std}"; \ + create_testsuite_report --maybe-color; \ + echo "$$col$$br$$std"; \ + if $$success; then :; else \ + echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ + if test -n "$(PACKAGE_BUGREPORT)"; then \ + echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ + fi; \ + echo "$$col$$br$$std"; \ + fi; \ + $$success || exit 1 + +check-TESTS: + @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list + @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + trs_list=`for i in $$bases; do echo $$i.trs; done`; \ + log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ + exit $$?; +recheck: all + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + bases=`for i in $$bases; do echo $$i; done \ + | $(am__list_recheck_tests)` || exit 1; \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + log_list=`echo $$log_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ + am__force_recheck=am--force-recheck \ + TEST_LOGS="$$log_list"; \ + exit $$? +.test.log: + @p='$<'; \ + $(am__set_b); \ + $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +@am__EXEEXT_TRUE@.test$(EXEEXT).log: +@am__EXEEXT_TRUE@ @p='$<'; \ +@am__EXEEXT_TRUE@ $(am__set_b); \ +@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ +@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ +@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ +@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) + -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) + -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-local + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: check-am install-am install-strip + +.PHONY: all all-am check check-TESTS check-am clean clean-generic \ + clean-libtool cscopelist-am ctags-am distclean \ + distclean-generic distclean-libtool distclean-local distdir \ + dvi dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am recheck tags-am \ + uninstall uninstall-am + +.PRECIOUS: Makefile + + +getopt.test : ../$(libsrc) +../$(libsrc): + cd .. ; echo $(MAKE) $(libsrc) ; $(MAKE) $(libsrc) >/dev/null 2>&1 + +distclean-local: + @-rm -rf *-testd FAILURES + +check : perm-stamp + +perm-stamp : + @-cd $(srcdir) ; chmod +x *.test 2>/dev/null + +verbose : distclean-local + VERBOSE=true ; export VERBOSE ; \ + $(MAKE) check TESTS="$(TESTS)" + +.PHONY : distclean-local verbose perm-stamp + +# Makefile.am ends here + +# 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/autoopts/test/alias.test b/autoopts/test/alias.test new file mode 100755 index 0000000..b7195e6 --- /dev/null +++ b/autoopts/test/alias.test @@ -0,0 +1,119 @@ +#! /bin/sh +# +# alias.test --- test option aliasing +# +# Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +. ./defs + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +echo "creating ${testname}.def in `pwd`" +testname="${testname}" test_main="YES" \ +argument="arg [...]" long_opts="YES" use_flags=true \ +${SHELLX} ${stdopts} option:'opt init' second=020 || \ + failure "Could not run stdopts.def" +: add defs +cat >> ${testname}.def <<- \_EOF_ + + flag = { + name = a-opt; + value = a; + aliases = option; + }; + + flag = { + name = b-second; + value = b; + aliases = second; + }; + _EOF_ + +echo ${AG_L} ${testname}.def +${AG_L} ${testname}.def || \ + failure AutoGen could not process + +compile "-?" + +# # # # # # # # # # FIRST TEST # # # # # # # # # + +echo creating ${testname}-1.help +clean_help > ${testname}-1.help <<'_EOF_' +test_alias - Test AutoOpts for alias +Usage: alias [ - [] | --[{=| }] ]... arg [...] + Flg Arg Option-Name Description + -o Str option The option option descrip + -s Num second The second option descrip + -a Str a-opt an alias for the 'option' option + -b Num b-second an alias for the 'second' option + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + +Options are specified by doubled hyphens and their name or by a single +hyphen and the flag character. +_EOF_ + +cmp -s ${testname}-1.help ${testname}.help || \ + failure "`diff ${testname}-1.help ${testname}.help`" + +./${testname} -o foo -a bar && \ + failure "both -o and -a were accepted" + +./${testname} -a bar fumble > ${testname}.out +cat > ${testname}.base <<- \_EOF_ + OPTION_CT=2 + export OPTION_CT + TEST_ALIAS_OPTION='bar' + export TEST_ALIAS_OPTION + _EOF_ + +cmp -s ${testname}.out ${testname}.base || \ + failure "`diff ${testname}.out ${testname}.base`" + +run_ag als -T agtexi-cmd.tpl ${testname}.def +test -f invoke-test_${testname}.menu || \ + failure "no menu entry output" +rm -f invoke-test_${testname}.menu +test -f invoke-test_${testname}.texi || \ + failure "no texi output" +mv -f invoke-test_${testname}.texi ${testname}.texi + +run_ag als -T agmdoc-cmd.tpl ${testname}.def +test -f test_${testname}.1 || failure "no man page output" +mv test_${testname}.1 ${testname}.1 +lnct=` + ${EGREP} 'an alias for the .*(option|second).* option' \ + ${testname}.texi ${testname}.1 | \ + wc -l` +test $lnct -eq 4 || \ + failure "bad documentation output" + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## End: + +# end of cond.test diff --git a/autoopts/test/argument.test b/autoopts/test/argument.test new file mode 100755 index 0000000..f3b0058 --- /dev/null +++ b/autoopts/test/argument.test @@ -0,0 +1,237 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# ---------------------------------------------------------------------- +# argument.test --- test argument program attribute +# make sure that when it is not specified +# then option processing consumes all args. +# +# Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +echo "creating ${testname}.def in `pwd`" +export testname test_main argument long_opts +${SHELLX} ${stdopts} option:'opt init' second=020 || \ + failure "Could not run stdopts.def" + +${AG_L} ${testname}.def || \ + failure AutoGen could not process + +compile "-?" + +# # # # # # # # # # HELP OUTPUT FILE # # # # # # # # # + +basehlp=${testname}.hlp +echo creating ${basehlp} +clean_help > ${basehlp} <<'_EOF_' +test_argument - Test AutoOpts for argument +Usage: argument [ - [] ]... + Flg Arg Option-Name Description + -o Str option The option option descrip + -s Num second The second option descrip + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + +_EOF_ + +cmp -s ${testname}.h*lp || \ + failure "`diff ${basehlp} ${testname}.help`" + +./${testname} mumble 2> /dev/null && \ + failure ${testname} should not accept non-options + +./${testname} -s mumble 2> /dev/null && \ + failure ${testname} should not accept bad options + +./${testname} -o string -s 99 > /dev/null || \ + failure ${testname} did not handle its options + +# # # # # # # # # # T E S T 2 # # # # # # # # # # # + +exec 3> ${testname}2.def +${SED} '/arg-type = number/q' ${testname}.def >&3 +cat >&3 <<- _EOF_ + arg-range = "-1"; + arg-range = "3->021"; + arg-range = "040->0x1FFF"; + scaled; + flag-code[1] = ' /* no-op one */;'; + flag-code[0] = ' /* no-op zero */;'; + }; + include = '#include '; + _EOF_ +exec 3>&- + +${AG_L} ${testname}2.def || \ + failure AutoGen could not process +{ + ${SED} '/#if.*TEST-MAIN-PROCEDURE:/,/#endif.*END-TEST-MAIN/d + /^#/s/_ARGUMENT_/_ARGUMENT2_/' \ + ${testname}2.c + cat < XX +mv ${testname}2.c ${testname}2.c.save +mv -f XX ${testname}2.c + +Csrc=${testname}2 +compile "-?" + +clean_help > ${testname}2.hlp <<'_EOF_' +test_argument - Test AutoOpts for argument +Usage: argument2 [ - [] ]... + Flg Arg Option-Name Description + -o Str option The option option descrip + -s Num second The second option descrip + - is scalable with a suffix: k/K/m/M/g/G/t/T + - it must lie in one of the ranges: + -1 exactly, or + 3 to 17, or + 32 to 8191 + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + +_EOF_ + +cmp -s ${testname}2.hlp ${testname}2.help || \ + failure "`diff ${testname}2.hlp ${testname}2.help`" + +./${testname}2 -o string -s 037 > /dev/null && \ + failure ${testname} handled wrong sized option + +./${testname}2 -o string -s 0x37 > /dev/null || \ + failure ${testname} did not handle its options + +./${testname}2 -o string -s 8k > /dev/null || \ + failure ${testname} could not handle 8k + +./${testname}2 -o string -s 8K > ${testname}2-bad.out 2>&1 && \ + failure ${testname} did handle 8K + +${GREP} 'error:.* value .* is out of range\.$' ${testname}2-bad.out || \ + failure "missing 'is out of range' message" + +# # # # # # # # # # T E S T 3 # # # # # # # # # # # + +exec 3> ${testname}3.def +${SED} '/value = .s.;/q' ${testname}.def >&3 +cat >&3 <<- _EOF_ + arg-type = file; + file-exists = yes; + open-file = fopen; + file-mode = "r"; + }; + _EOF_ +exec 3>&- + +${AG_L} ${testname}3.def || \ + failure AutoGen could not process +{ + ${SED} '/^#if.*TEST MAIN PROCEDURE:/,/#endif.*defined TEST_/d + /^#/s/_ARGUMENT_/_ARGUMENT3_/' \ + ${testname}3.c + cat < XX +mv ${testname}3.c ${testname}3.c.save +mv -f XX ${testname}3.c + +Csrc=${testname}3 +compile "-?" + +clean_help > ${testname}3.hlp <<'_EOF_' +test_argument - Test AutoOpts for argument +Usage: argument3 [ - [] ]... + Flg Arg Option-Name Description + -o Str option The option option descrip + -s Fil second The second option descrip + - file must pre-exist + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + +_EOF_ + +cmp -s ${testname}3.hlp ${testname}3.help || \ + failure "`diff ${testname}3.hlp ${testname}3.help`" + +./${testname}3 -o string -s `pwd`/bogusfilename.c > /dev/null && \ + failure ${testname} handled non-existent file + +./${testname}3 -o string -s `pwd`/${testname}3.hlp > ${testname}3-a.hlp || \ + failure ${testname} could not handle existing file + +cmp -s ${testname}3.hlp ${testname}3-a.hlp || \ + failure "`diff ${testname}3.hlp ${testname}3-a.hlp`" +# # # # # # # # # # T E S T 4 # # # # # # # # # # # + +${SED} /arg-range/d ${testname}2.def > ${testname}4.def + +${AG_L} ${testname}4.def || \ + failure AutoGen could not process +${SED} -n '/^doOptSecond/,/^}/p' ${testname}4.c > ${testname}4.res +Csrc=${testname}4 +compile '-?' + +cat > ${testname}4.base <<- _EOF_ + doOptSecond(tOptions* pOptions, tOptDesc* pOptDesc) + { + /* + * Be sure the flag-code[0] handles special values for the options pointer + * viz. (poptions <= OPTPROC_EMIT_LIMIT) *and also* the special flag bit + * ((poptdesc->fOptState & OPTST_RESET) != 0) telling the option to + * reset its state. + */ + /* extracted from argument4.def, line 22 */ + /* no-op zero */; + optionNumericVal(pOptions, pOptDesc); + /* no-op one */; + } + _EOF_ + +cmp -s ${testname}4.base ${testname}4.res || \ + failure "`diff ${testname}4.base ${testname}4.res`" + +# # # # # # # # # # T E S T E N D # # # # # # # # # # + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## End: + +# end of argument.test diff --git a/autoopts/test/cfg-edit.test b/autoopts/test/cfg-edit.test new file mode 100755 index 0000000..f0d7ffc --- /dev/null +++ b/autoopts/test/cfg-edit.test @@ -0,0 +1,330 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# +# cfg-edit.test --- test changing the configuration for a daemon process +# +# Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +. ./defs + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +cfg_file=`basename ${TMPDIR}`/${testname}.cfg + +exec 5> ${testname}.def +cat >&5 <<- _EOF_ + + AutoGen definitions options; + + config-header = 'config.h'; + prog-name = "test_${testname}"; + prog-title = "Test AutoOpts for ${testname}"; + homerc = ${cfg_file}; + resettable; + argument = '[ ]'; + + flag = { + name = struct; + value = s; + max = NOLIMIT; + descrip = 'structured argument val'; + arg-type = nested; + }; + + flag = { + name = members; + value = m; + descrip = 'membership set'; + keyword = one, two, three, four, five, six, seven, eight, nine, ten; + arg-default = five; + arg-type = set; + }; + + flag = { + name = enumerate; + value = e; + descrip = 'a test enumeration'; + keyword = uno, dos, tres, quatro, cinco, seis, siete, ocho; + arg-default = cinco; + arg-type = keyword; + }; + + flag = { + name = stacking; + value = k; + descrip = 'stack up a list'; + arg-default = initialized; + arg-type = string; + stack-arg; max = NOLIMIT; + }; + + flag = { + name = number; + value = n; + descrip = 'a range constrained int'; + arg-default = 32; + arg-type = number; + arg-range = '->-1', '1->31', '33', '64->'; + }; + + flag = { + name = boolean; + value = b; + descrip = 'a boolean value'; + arg-default = true; + arg-type = boolean; + }; + + flag = { + name = in-file; + value = I; + descrip = 'an input file'; + arg-type = file; + open-file = descriptor; + file-mode = O_RDONLY; + file-exists = yes; + }; + + flag = { + name = out-file; + value = O; + descrip = 'an output file'; + arg-type = file; + open-file = fopen; + file-mode = w; + file-exists = no; + }; + + flag = { + name = test-file; + value = T; + descrip = 'a test file'; + arg-type = file; + }; + + main = { + main-type = main; + _EOF_ + +asl='<''<' +cat >&5 <<- _EOF_ + main-text = ${asl}- _EOCode_ + { + tOptions * const pOpts = &test_${test_name}Options; + int svix = pOpts->specOptIdx.save_opts; + char const * pzFile = "${cfg_file}-default"; + + if (argc > 0) + pzFile = *argv; + if (svix == 0) exit(1); + SET_OPT_SAVE_OPTS(pzFile); + optionSaveFile(pOpts); + } + _EOF_ + +echo "_EOCode_; };" >&5 + +exec 5>&- + +# # # # # # # # # # CREATE PROGRAM # # # # # # # # # + +echo ${AG_L} ${testname}.def +${AG_L} ${testname}.def || \ + failure AutoGen could not process + +compile "-?" + +# # # # # # # # # # HELP OUTPUT FILE # # # # # # # # # + +basehelp=${testname}-base.help +echo creating ${basehelp} +clean_help > ${basehelp} <<_EOF_ +test_${testname} - Test AutoOpts for ${testname} +Usage: ${testname} [ - [] ]... [ ] + Flg Arg Option-Name Description + -s Cpx struct structured argument val + - may appear multiple times + -m Mbr members membership set + - is a set membership option + -e KWd enumerate a test enumeration + -k Str stacking stack up a list + - may appear multiple times + -n Num number a range constrained int + - it must lie in one of the ranges: + less than or equal to -1, or + 1 to 31, or + 33 exactly, or + greater than or equal to 64 + -b T/F boolean a boolean value + -I Fil in-file an input file + - file must pre-exist + -O Fil out-file an output file + - file must not pre-exist + -T Fil test-file a test file + -R Str reset-option reset an option's state + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + -> opt save-opts save the option state to a config file + -< Str load-opts load options from a config file + - disabled as '--no-load-opts' + - may appear multiple times + + +The following option preset mechanisms are supported: + - reading file ${testname}.cfg + +The valid "members" option keywords are: + one two three four five six seven eight nine ten + or an integer mask with any of the lower 10 bits set +or you may use a numeric representation. Preceding these with a '!' +will clear the bits, specifying 'none' will clear all bits, and 'all' +will set them all. Multiple entries may be passed as an option +argument list. +The valid "enumerate" option keywords are: + uno dos tres quatro cinco seis siete ocho + or an integer from 0 through 7 +_EOF_ + +${SED} "/ - reading file/s/ file .*/ file ${testname}.cfg/" \ + ${testname}.help > X$$ +mv -f X$$ ${testname}.help +pair="${basehelp} ${testname}.help" +cmp -s ${pair} || \ + failure "$testname help mismatch$nl`diff ${pair}`" + +rm -f ${testname}.cfg +./${testname} -m '+ one + three + seven' '->' +members=`${SED} -n 's/^members *= *=//p' ${cfg_file}` +case "${members}" in +'one + three + five + seven' ) : ;; +* ) failure "members not set to one, three, five and seven" ;; +esac + +./${testname} -R '*' '->' +members=`${SED} -n 's/^members *//p' ${cfg_file}` 2>/dev/null +case "${members}" in +'' ) : ;; +* ) failure "members entry not removed" +esac + +arg1="stumble, foo${ht}lish, 1234, able" +arg2='foo, 4321 one, two=2, three' +dir=`echo ${TMPDIR} | ${SED} "s@^\`pwd\`//*@@"` +out_file=${dir}/${testname}-out-file +rm -f ${out_file} +./${testname} -m 'one + three' -b true -m 'seven' \ + -s "${arg1}" -n -200 -s "${arg2}" -e ocho \ + -I ${srcdir}/${testname}.test \ + -O ${out_file} \ + -T ${dir}/${testname}-test-file \ + '->' +${SED} '/^#/d' ${cfg_file} > ${testname}-X +mv -f ${testname}-X ${cfg_file} +cat > ${testname}.sample-cfg <<- \_EOF_ + + + 0x4D2 + foo lish + + + + 0x10E1 + + + + + 2 + + + members = =one + three + five + seven + enumerate = ocho + number = -200 + boolean = true + _EOF_ + +cat >> ${testname}.sample-cfg <<- _EOF_ + in-file = ${srcdir}/${testname}.test + out-file = ${out_file} + test-file = ${dir}/${testname}-test-file + _EOF_ +pair=${testname}.sample-cfg\ ${cfg_file} +cmp ${pair} || \ + failure "improperly saved state:${nl}`diff ${pair}`" + +rm -f ${out_file} +./${testname} ${cfg_file}-2 +${SED} '/^#/d' ${cfg_file}-2 > ${testname}-X +mv -f ${testname}-X ${cfg_file}-2 +cmp ${cfg_file} ${cfg_file}-2 || \ + failure "mismatched: re-saved config${nl}`diff ${cfg_file} ${cfg_file}-2`" + +rm -f ${cfg_file}-2 +rm -f ${out_file} +./${testname} -R struct ${cfg_file}-2 +test "X`egrep -v '^#' ${cfg_file}-2`" = "X`egrep '^[a-z]' ${cfg_file}`" || \ + failure "structure not erased${nl}`cat ${cfg_file}-2`" + +opt_ct=7 +mv -f ${cfg_file}-2 ${cfg_file} +ct=`egrep '^[a-z]' ${cfg_file} | wc -l` +test ${ct} -eq ${opt_ct} || failure "wrong line count${nl}`cat ${cfg_file}`" + +rm -f ${out_file} + +remove_opt() { + opt_ct=`expr $opt_ct - 1` + ./${testname} -R ${1} '->' + ct=`egrep '^[a-z]' ${cfg_file} | wc -l` + test ${ct} -eq ${opt_ct} || \ + failure "${1} is still there${nl}`cat ${cfg_file}`" +} + +for f in out-file in-file test-file boolean members enumerate number +do + remove_opt $f +done + +./${testname} -k alpha -k beta -k omega ${cfg_file}-XX +${SED} '/^#/d' ${cfg_file}-XX > ${cfg_file}-2 +cat > ${cfg_file}-3 <<- _EOF_ + stacking = alpha + stacking = beta + stacking = omega + _EOF_ +cmp ${cfg_file}-[23] || \ + failure "missing stacking args:${nl}`diff -c ${cfg_file}-[23]`" +./${testname} -R k ${cfg_file}-2 +ct=`egrep '^[a-z]' ${cfg_file}-2 | wc -l` +test ${ct} -eq 0 || failure "arg values still stacked" + +# # # # # # # # # # TEST OPERATION # # # # # # # # # # + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## End: + +# end of cfg-edit.test diff --git a/autoopts/test/cond.test b/autoopts/test/cond.test new file mode 100755 index 0000000..2324211 --- /dev/null +++ b/autoopts/test/cond.test @@ -0,0 +1,193 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# ---------------------------------------------------------------------- +# cond.test --- test conditionally compiled option +# +# Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +echo "creating ${testname}.def in `pwd`" +testname="${testname}" test_main="${test_main}" \ +argument="${argument}" long_opts="${long_opts}" \ +${SHELLX} ${stdopts} option:'opt init' second=020 || \ + failure "Could not run stdopts.def" +cat >> ${testname}.def < ${testname}-1.help <<'_EOF_' +test_cond - Test AutoOpts for cond +Usage: cond [ - [] ]... + Flg Arg Option-Name Description + -o Str option The option option descrip + -s Num second The second option descrip + -I Num interfere cond interference test + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + +_EOF_ + +cmp -s ${testname}-1.help ${testname}.help || \ + failure "TEST 1 FAILED${nl}`diff ${testname}-1.help ${testname}.help`" + +./${testname}-1 -c 123 2>/dev/null && \ + failure "*DID* process -c option" + +# # # # # # # # # # SECOND TEST # # # # # # # # # + +INC="${INC} -DCOND=1" +compile "-?" +mv ${testname} ${testname}-2 +clean_help > ${testname}-2.help <<'_EOF_' +test_cond - Test AutoOpts for cond +Usage: cond [ - [] ]... + Flg Arg Option-Name Description + -o Str option The option option descrip + -s Num second The second option descrip + -c Num condition cond test + -I Num interfere cond interference test + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + +_EOF_ + +cmp -s ${testname}-2.help ${testname}.help || \ + failure "TEST 2 FAILED${nl}`diff ${testname}-2.help ${testname}.help`" + +# # # # # # # # # # THIRD TEST # # # # # # # # # + +echo guard-option-names\; >> ${testname}.def +echo ${AG_L} ${testname}.def +${AG_L} ${testname}.def || failure AutoGen could not process + +( cc_cmd=`echo ${cc_cmd} | \ + ${SED} "s/-DTEST_TEST/-DSECOND -DTEST_TEST/" ` + eval "$cc_cmd" 2>&1 ) \ + | ${SED} -n '/undefining SECOND due to option name conflict/p' \ + > ${testname}-cc.log + +test -s ${testname}-cc.log || \ + failure "warning diffs: 'undefining SECOND' not found" + +# # # # # # # # # # FOURTH TEST # # # # # # # # # + +${SED} '/value = c/s/$/ deprecated;/' ${testname}.def > ${testname}.def4 + +echo ${AG_L} ${testname}.def4 +${AG_L} ${testname}.def4 || \ + failure AutoGen could not process ${testname}.def4 + +compile "-?" +mv ${testname} ${testname}-4 +cmp -s ${testname}-1.help ${testname}.help || \ + failure "TEST 4 FAILED${nl}`diff ${testname}-1.help ${testname}.help`" + +./${testname}-4 -c 123 || \ + failure "could not process -c option" + +# # # # # # # # # # FIFTH TEST # # # # # # # # # + +${SED} '/deprecated/s/deprecated.*/arg-range = "0->1000";/' \ + ${testname}.def4 > ${testname}.def5 + +echo ${AG_L} ${testname}.def5 +${AG_L} ${testname}.def5 || \ + failure AutoGen could not process ${testname}.def5 + +compile "-?" +mv ${testname} ${testname}-5 +clean_help > ${testname}-5.help <<'_EOF_' +test_cond - Test AutoOpts for cond +Usage: cond [ - [] ]... + Flg Arg Option-Name Description + -o Str option The option option descrip + -s Num second The second option descrip + -c Num condition cond test + - it must be in the range: + 0 to 1000 + -I Num interfere cond interference test + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + +_EOF_ + +cmp -s ${testname}-5.help ${testname}.help || \ + failure "TEST 5 FAILED${nl}`diff -u ${testname}-5.help ${testname}.help`" + +# # # # # # # # # # SIXTH TEST # # # # # # # # # + +INC=`echo ${INC} | sed 's/ -DCOND=1//'` +compile "-?" +mv ${testname} ${testname}-6 +clean_help > ${testname}-6.help <<'_EOF_' +test_cond - Test AutoOpts for cond +Usage: cond [ - [] ]... + Flg Arg Option-Name Description + -o Str option The option option descrip + -s Num second The second option descrip + -I Num interfere cond interference test + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + +_EOF_ + +cmp -s ${testname}-6.help ${testname}.help || \ + failure "TEST 6 FAILED${nl}`diff -u ${testname}-6.help ${testname}.help`" + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## End: + +# end of cond.test diff --git a/autoopts/test/config.test b/autoopts/test/config.test new file mode 100755 index 0000000..0b2b273 --- /dev/null +++ b/autoopts/test/config.test @@ -0,0 +1,200 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# ---------------------------------------------------------------------- +# rc.test --- test loading and saving of rc files +# +# Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd +# +# ---------------------------------------------------------------------- +. ./defs + +# # # # # # # # # # PROGRAM FILE # # # # # # # # # + +cat > ${testname}.c <<- _EOTest_ + #include + #include "config.h" + #include + + int print_entry( const tOptionValue* pGV ); + int print_entry( const tOptionValue* pGV ) { + if (pGV == NULL) { + fprintf( stderr, "ENTRY NOT FOUND\n" ); + return 1; + } + printf( "%-8s -- ", pGV->pzName ); + switch (pGV->valType) { + case OPARG_TYPE_NONE: + fputs( "no value\n", stdout ); break; + + case OPARG_TYPE_STRING: + printf( "string: %s\n", pGV->v.strVal ); break; + + case OPARG_TYPE_ENUMERATION: + printf( "enum: %d\n", pGV->v.enumVal ); break; + + case OPARG_TYPE_BOOLEAN: + printf( "bool: %s\n", + pGV->v.boolVal ? "TRUE" : "false" ); break; + + case OPARG_TYPE_MEMBERSHIP: + printf( "members: 0x%08lX\n", (unsigned long)pGV->v.setVal ); break; + + case OPARG_TYPE_NUMERIC: + printf( "integer: %ld\n", pGV->v.longVal ); break; + + case OPARG_TYPE_HIERARCHY: + printf( "nested: 0x%08lX\n", (unsigned long)pGV->v.nestVal ); break; + + default: + printf( "bad type: %d\n", pGV->valType ); + return 1; + } + return 0; + } + + int main( int argc, char** argv ) { + int res = 0; + const tOptionValue* pOV; + if ((argc < 3) || (argv[1][0] == '-')) { + fputs( "help\n", stdout ); + return 0; + } + pOV = configFileLoad( *++argv ); + if (pOV == NULL) { + fprintf( stderr, "Could not load: %s\n", *argv ); + return 1; + } + argc -= 2; + while (argc-- > 0) { + const tOptionValue* pGV = optionGetValue( pOV, *++argv ); + res |= print_entry( pGV ); + } + + { + const tOptionValue* pGV = optionGetValue( pOV, "n4_ty" ); + pGV = optionGetValue( pGV, "b4r" ); + if (pGV->valType != OPARG_TYPE_BOOLEAN) { + res = 1; + } else if (pGV->v.boolVal) { + fputs( "YES!!\n", stdout ); + } else { + fputs( "oops!!\n", stdout ); + res = 1; + } + } + + { + const tOptionValue* pGV = optionGetValue( pOV, NULL ); + while (pGV != NULL) { + res |= print_entry( pGV ); + pGV = optionNextValue( pOV, pGV ); + } + } + + print_entry( pOV ); + optionUnloadNested( pOV ); + return res; + } + _EOTest_ + +compile --help + +# # # # # # # # # # RUN TESTS # # # # # # # # # + +echo Constructing test ${testname} files +cat > ${testname}.cfg <<- \_EOConfig_ + mumble = grumble + grumble : rumble + + stumble "The\tquick\ + brown fox\tjumped\n\ + over everything." + + stumble2 The\ + quick\ + brown\ + \ + fix. + + + foo : foolish + YES!! + + alpha, beta ', gamma' + "Carol\tTine\n" + + 42 + _EOConfig_ + +cat > ${testname}.res <<- \_EOResult_ + mumble -- string: grumble + grumble -- string: rumble + stumble -- string: The quickbrown fox jumped + over everything. + alpha -- no value + beta -- string: , gamma + zzyzx -- integer: 42 + YES!! + alpha -- no value + beta -- string: , gamma + beta -- string: Carol Tine + + grumble -- string: rumble + mumble -- string: grumble + n4_ty -- nested: 0xXXXXXXXX + stumble -- string: The quickbrown fox jumped + over everything. + stumble2 -- string: The + quick + brown + + fix. + zzyzx -- integer: 42 + ./config.cfg -- nested: 0xXXXXXXXX + _EOResult_ + +./${testname} ./${testname}.cfg mumble grumble stumble alpha beta zzyzx \ + > ${testname}.tmp-out || { + failure "Cannot run ${testname}" +} + +${SED} '/ -- nested:/s/0x.*/0xXXXXXXXX/' \ + ${testname}.tmp-out > ${testname}.out +cmp ${testname}.out ${testname}.res || { + failure "`diff -c ${testname}.out ${testname}.res`" +} + +./${testname} ${testname}.cfg gamma >/dev/null && \ + failure "found non-existent value" + +# # # # # # # # # # CLEANUP # # # # # # # # # + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## End: + +# end of config.test diff --git a/autoopts/test/defs.in b/autoopts/test/defs.in new file mode 100644 index 0000000..a026d89 --- /dev/null +++ b/autoopts/test/defs.in @@ -0,0 +1,392 @@ +#! /bin/echo this_file_should_be_sourced,_not_executed +# -*- Mode: Shell-script -*- +# +# defs --- define the environment for autogen tests. +# +# Author: Bruce Korb +# +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# C O N F I G U R E D V A L U E S +# +# Make sure srcdir is an absolute path. Supply the variable +# if it does not exist. We want to be able to run the tests +# stand-alone!! +# +cfg_vals() +{ + case `uname -s` in + SunOS ) + if test "X$BASH_VERSION" = X + then + # On Solaris, make certain we do not use /bin/sh + sh=`which bash` + test "X$sh" = X && sh=/usr/xpg4/bin/sh + BASH_VERSION=not-good-enough + export BASH_VERSION + exec $sh "$0" "$@" + fi + ;; + esac + + set -a + TESTS='' + builddir=`pwd` + progpid=$$ + : ${top_builddir=@top_builddir@} + top_builddir=`cd ${top_builddir} >/dev/null ; pwd` + : ${top_srcdir=@top_srcdir@} + top_srcdir=`cd ${top_srcdir} >/dev/null ; pwd` + : ${srcdir=@srcdir@} + srcdir=`cd $srcdir >/dev/null && pwd` + . ${top_builddir}/config/shdefs "${builddir}/` + echo $0|${SED:-sed} 's@.*/@@'`" + progname=`echo "$1" | ${SED} 's,^.*/,,'` + testname=`echo "$progname" | ${SED} 's,\..*$,,'` + testsubdir=${testname}-testd + tstdir=${builddir}/${testsubdir} + PS4=">${testname}-\${FUNCNAME}> " + test_name=`echo ${testname} | ${SED} 's/-/_/g'` + ( exec 2>/dev/null; ulimit -c unlimited ) && \ + ulimit -c unlimited + + CFLAGS="${CFLAGS} ${DEFS}" + : ${PAGER=more} + + stdopts=${top_srcdir}/autoopts/test/stdopts.def + test_main=yes + use_flags=true + sed_omit_license="/-\*- buffer-read-only:/,/^ \*\//d" + TERM='' + set +a + + ( + test_local() { + local local_works=yes + } + test_local + ) || eval 'local() { : ; }' + + vars=`set | ${SED} -n '/^\(LANG\|LC_[A-Z_]*\)=/s/=.*//p'` 2>/dev/null + unset AUTOOPTS_USAGE $vars CONTENT_LENGTH REQUEST_METHOD QUERY_STRING +} + +# If only the "rm(1)" command could be relied upon.... +# +purge() +{ + rm -rf ${*} 2>/dev/null + bad='' + for f + do test -f ${f} -o -d ${f} && bad="${bad} ${f}" + done + test -z "$bad" && return 0 + + # NFS "busy" files and MS-DOS fs sometimes fail. + # + set -- $bad + test "x${RANDOM}" = "x${RANDOM}" && RANDOM=`expr 0${RANDOM} + 1 2>/dev/null` + + f=zzPURGE-${1}-${RANDOM}-${progpid} + if test $# -gt 1 + then mkdir "${f}" + mv $* "${f}/." + else mv $1 "${f}" + fi +} + +init_tests() +{ + exec 8>&2 + BASH_XTRACEFD=8 + + TMPDIR="${tstdir}/${testname}-tmpd" + mkdir -p ${TMPDIR} + CFLAGS=`echo ${CFLAGS} | \ + ${SED} "s/-Werror[^ ${ht}]*//g;s/-Wextra//g"` + + lo_dir=${top_builddir}/autoopts + lo_lib=`find ${lo_dir} -type f -name "*libopts.${OBJEXT}" | head -n1` + test -f "$lo_lib" || { + lo_lib=`find ${lo_dir} -type f -name "*libopts.lo" | head -n1` + test -f "$lo_lib" || die "no libopts lib" + } + lo_dir=${lo_lib%/*} + test "X${LD_LIBRARY_PATH}" = X || \ + LD_LIBRARY_PATH=:${LD_LIBRARY_PATH} + LD_LIBRARY_PATH=${lo_dir}:${LIBGUILE_PATH}${LD_LIBRARY_PATH} + + case ${AG_VERSION} in + *pre* ) GUILE_WARN_DEPRECATED=detailed ;; + * ) GUILE_WARN_DEPRECATED=no ;; + esac + + case "$LIB" in + *-lgen* ) : ;; + * ) + for f in /usr/lib*/libgen.so /lib*/libgen.so + do + test -f $f && { + LIB="${LIB} -lgen" + break + } + done + ;; + esac + LIB="${lo_lib} ${LIB}" + + AG_L=run_ag\ ao + agl_opts="-L${top_builddir}/autoopts/tpl" + test "L${top_builddir}" = "L${top_srcdir}" || \ + agl_opts="$agl_opts -L${top_srcdir}/autoopts/tpl" + export TMPDIR PATH LD_LIBRARY_PATH \ + GUILE_WARN_DEPRECATED LIB AG_L agl_opts \ + CC LIBGUILE AG_VERSION +} + +be_silent() +{ + setx=: + msg=echo + VERBOSE=false + purge ${testsubdir} + + run_ag() + { + local opts= + opts='' + shift + + case " $* " in + *' -L'* ) : ;; + * ) opts="${agl_opts}" ;; + esac + + ${AGexe} ${opts} "$@" + } + + init_tests +} + +be_verbose() +{ + set -x + setx='set -x' + msg=: + VERBOSE=true + test -d ${testsubdir} || mkdir ${testsubdir} || exit 1 + + run_ag() + { + local opts= tfile=${testname}-aglog-${1}-${progpid}.log + ${verb_ok:-true} && { + case " $* " in + *' --trace'* ) : ;; + * ) + opts="--trace=every --trace-out=>>${tfile}" + ;; + esac + AUTOGEN_TRACE=every + AUTOGEN_TRACE_OUT=">>`pwd`/${tfile}" + export AUTOGEN_TRACE_OUT AUTOGEN_TRACE + } + shift + + case " $* " in + *' -L'* ) : ;; + * ) opts="${opts} ${agl_opts}" ;; + esac + + MALLOC_CHECK_=3 ${AGexe} ${opts} "$@" + } + + init_tests +} + +cfg_inc() +{ + test_src=$srcdir/${testname}.test + cd ${testsubdir} || { + echo "Cannot make or change into ${testsubdir}" + exit 1 + } + + dirs=` + for f in ${top_builddir} ${top_srcdir} + do + for d in . autoopts agen5 + do + cd $f/$d + pwd >&9 + cd - + done 9>&1 1>/dev/null + done | sort -u | ${SED} 's/^/-I/'` + + INC=`echo ${dirs} ${CPPFLAGS}` + + : "=== Running $progname for ${testname} using ${SHELL} ===" + chmod +w * > /dev/null 2>&1 || : + ${VERBOSE} && SHELLX="${SHELL} -x" || SHELLX="${SHELL}" +} + +# # # # +# +# "clean_help" -- remove variable parts so results can be compared +# +nl=' +' +ht=' ' +basic_help_clean="/^Packaged by/d +/^Report .* bugs to/d +/[Pp]lease send bug reports/d +/^exit [0-9]/d +/^[ ${ht}]*\$/d" +TR=`command -v tr` +test -x "$TR" || die "cannot run tests without 'tr' program" + +export nl ht basic_help_clean TR +readonly nl ht basic_help_clean TR + +clean_help() { + test -z "$sedcmd" && \ + s=${basic_help_clean} || \ + s="${sedcmd}${nl}${basic_help_clean}" + + ${SED} "${s}" ${1+"$@"} +} + +compile() +{ + ${setx} + test "X${Csrc}" = "X" && Csrc="${testname}" + test "X${Cexe}" = "X" && Cexe="${Csrc}" + test "X${Dnam}" = "X" && Dnam="${testname}" + + d=`echo TEST_TEST_${Dnam}_OPTS | ${TR} '[a-z]-' '[A-Z]_'` + cc_cmd="${CC} ${CFLAGS} -D$d ${INC} -o ${Cexe} ${Csrc}.c ${LIB}" + eval ${cc_cmd} || \ + failure cannot compile ${Csrc}.c + if test $# -gt 0 + then + ( set +xe + exec 2>&1 + ./${Cexe} ${*} ${dosed} + ) || failure cannot obtain help output for ${Csrc} + fi > ${Cexe}.RAW-HELP + clean_help ${Cexe}.RAW-HELP > ${Csrc}.help + Csrc='' Cexe='' Dnam='' +} + +cleanup() +{ + kill -9 $THUMPER_PID + trap '' 15 + ${setx} + ${VERBOSE} || { + cd ${builddir} + purge ${testsubdir} + } + ${msg} ${testname} done + exit 0 +} + +# A standard failure function +# +failure() +{ + kill -9 $THUMPER_PID + trap '' 15 + set -x + cd ${tstdir}/.. + if test -d FAILURES + then test -d "FAILURES/${testsubdir}" && \ + purge "FAILURES/${testsubdir}" + else mkdir FAILURES + fi + + mv "${testsubdir}" "FAILURES/${testsubdir}" + test -f "${testname}.log" && { + mv "${testname}.log" "FAILURES/${testsubdir}/amtest-${testname}.log" + ln -s "FAILURES/${testsubdir}/amtest-${testname}.log" "${testname}.log" + } + echo FAILURE: "$*" + exit 1 +} + +thumper() +{ + exec > /dev/null 2>&1 /dev/null ; pwd` + cd / + rpid=${progpid} + test -z "${kill_delay}" && kill_delay=3 + kill_delay=`expr $kill_delay '*' $AG_TIMEOUT` + while test ${kill_delay} -gt 0 + do sleep 1 + ps -p ${rpid} || exit 0 + kill_delay=`expr $kill_delay - 1` + done + kill -15 ${rpid} + sleep 1 + ps -p ${rpid} || exit + test -d "$bdir" && { + test -d ${bdir}/FAILURES || \ + mkdir ${bdir}/FAILURES + mv -f "${tstdir}" "${bdir}/FAILURES/." + } + kill -9 ${rpid} +} + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +cfg_vals $0 + +case "${VERBOSE}" in +'' | [Nn]* | 0 | [Ff]* ) + be_silent ;; + +[Yy]* | [0-9] | [Tt]* ) + be_verbose ;; + +* ) + case "$-" in + *x* ) be_verbose ;; + * ) be_silent ;; + esac +esac + +thumper & +THUMPER_PID=$! +cfg_inc + +trap "failure 'test ${testname} killed on timeout'" 15 + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# defs.in ends here diff --git a/autoopts/test/doc.test b/autoopts/test/doc.test new file mode 100755 index 0000000..ff522c4 --- /dev/null +++ b/autoopts/test/doc.test @@ -0,0 +1,854 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# +# doc.test --- test doc templates +# +# Author: Bruce Korb +# +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +. ./defs + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # +echo make defs from test file +${SED} "1,/^##* *BEGIN-DEFS/d + /^prog-name/s/=.*/= ${testname};/ + \\@^// *END-DEFS@q" \ + ${test_src} > ${testname}.def + +# # # # # # # # # # TEXI DOC CHECK # # # # # # # # # +run_ag tc -Tagtexi-cmd ${testname}.def +test -f invoke-${testname}.menu -a -f invoke-${testname}.texi || \ + failure "invoke-${testname}.{menu,texi} not built" +${SED} '/^@ignore/,/^@end ignore/d' \ + invoke-${testname}.texi > ${testname}-res.texi +rm -f invoke-${testname}.menu invoke-${testname}.texi + +${SED} -n '1,/^##* *BEGIN-TEXI/d + /^## END-TEXI/q + /^/p' \ + ${test_src} > ${testname}-base.texi + +outfiles="${testname}-res.texi ${testname}-base.texi" +cmp -s ${outfiles} || \ + failure "Differences: ${outfiles}${nl}`diff ${outfiles}`" + +# # # # # # # # # # MAN DOC CHECK # # # # # # # # # +run_ag mn -Tagman-cmd ${testname}.def +test -f ${testname}.1 || \ + failure "${testname}.1 not built" + +{ + ${SED} '/^\.\\"/d;/^$/d;/^\.TH/s/ *".*//' ${testname}.1 + rm -f ${testname}.1 + echo +} > ${testname}-res.1 + +${SED} "1,/^##* *BEGIN-MAN/d + /^## END-MAN/{;s/.*//;q;}" ${test_src} > ${testname}-base.1 + +outfiles="${testname}-base.1 ${testname}-res.1" +cmp -s ${outfiles} || \ + failure "Differences: ${outfiles}${nl}`diff -u ${outfiles}`" + +# # # # # # # # # # MDOC DOC CHECK # # # # # # # # # +run_ag md -Tagmdoc-cmd ${testname}.def +test -f ${testname}.1 || \ + failure "${testname}.1 not built" + +{ + ${EGREP} -v '^\.(Dd |Os |\\")|^$' ${testname}.1 + echo +} > ${testname}-mdoc-res.1 + +${SED} "1,/^##* *BEGIN-MDOC/d + /^## END-MDOC/{;s/.*//;q;}" ${test_src} > ${testname}-mdoc-base.1 + +outfiles="${testname}-mdoc-base.1 ${testname}-mdoc-res.1" +cmp -s ${outfiles} || \ + failure "Differences: ${outfiles}${nl}`diff -u ${outfiles}`" + +# # # # # # # # # # POT CHECK # # # # # # # # # +run_ag pt -Tdef2pot ${testname}.def +test -s ${testname}.pot || \ + failure "${testname}.pot not built" + +{ + ${SED} -e '/^# *Copyright/s/).*/)/' \ + -e '/^$/d' \ + -e 's/>, 20[0-9][0-9]\./>./' \ + -e '/POT-Creation-Date:/s/ 2[0-9].*/\\n"/' \ + ${testname}.pot + echo +} > ${testname}-res.pot + +${SED} "1,/^##* *BEGIN-POT/d + /^$/d + /^## END-POT/{;s/.*//;q;}" ${test_src} > ${testname}-base.pot + +outfiles="${testname}-base.pot ${testname}-res.pot" +cmp -s ${outfiles} || \ + failure "Differences: ${outfiles}${nl}`diff -u ${outfiles}`" + +# # # # # # # # # # # FINISH # # # # # # # # # # # + +cleanup + +exit 0 + +# # # # # # # # # # # OPTION DEFS + +cat <<_End_Of_Definitions_ +## BEGIN-DEFS +AutoGen Definitions options; +prog-name = gnutls-cli; +prog-title = "GnuTLS client"; +prog-desc = "Simple client program to set up a TLS connection."; +short-usage = <<- _EOUsage_ + Usage: gnutls-cli [options] hostname + gnutls-cli --help for usage instructions. + _EOUsage_; +prog-group = "GnuTLS"; +detail = <<- _EODetail_ + Simple client program to set up a TLS connection to some other computer. + It sets up a TLS connection and forwards data from the standard input + to the secured socket and vice versa. + _EODetail_; + +gnu-usage; +no-misuse-usage; +disable-save; +reorder-args; +no-xlate = opt; +argument = "[hostname]"; +long-opts; + +copyright = { + date = "2000-2018"; + owner = "Free Software Foundation"; + author = "Nikos Mavrogiannopoulos, Simon Josefsson and others; " + "see /usr/share/doc/gnutls-bin/AUTHORS for a complete list."; + eaddr = "bug-gnutls@gnu.org"; + type = gpl; +}; +version = "3.0.12"; +help-value = h; +more-help-value = M; +option-format = texi; + +flag = { + name = debug; + value = d; + arg-type = number; + arg-range = "0->9999"; + descrip = "Enable @code{debugging}"; + doc = 'really enable debugging'; +}; + +flag = { + name = mtu; + arg-type = number; + arg-range = "0->17000"; + descrip = "Set MTU for datagram TLS"; + doc = "Really set MTU for datagram TLS"; +}; + +flag = { + name = group-2; + descrip = "second group of options"; + documentation; +}; + +flag = { + name = crlf; + descrip = "Send CR LF instead of LF"; + doc = "Really send CR LF instead of LF"; +}; + +flag = { + name = x509fmtder; + descrip = "Use DER format for certificates to read from"; + doc = "Really use DER format for certificates to read from"; +}; + +flag = { + name = group-3; + descrip = "third group of options"; + documentation; +}; + +flag = { + name = recordsize; + arg-type = number; + arg-range = "0->4096"; + descrip = "The maximum record size to advertize"; + doc = "Really the maximum record size to advertize"; +}; + +flag = { + name = priority; + arg-type = string; + descrip = "Priorities string"; + doc = <<- _EODoc_ + TLS algorithms and protocols to enable. You can + use predefined sets of ciphersuites such as PERFORMANCE, + NORMAL, SECURE128, SECURE256. + + Check the GnuTLS manual on section ``Priority strings'' for more + information on allowed keywords + _EODoc_; +}; + + +doc-section = { + ds-type = 'SEE ALSO'; + ds-format = texi; + omit-texi; + ds-text = 'gnutls-cli-debug(1), gnutls-serv(1)'; +}; + +doc-section = { + ds-type = EXAMPLES; + ds-format = texi; + ds-text = <<- _EOT_ + To connect to a server using PSK authentication, you need to enable + the choice of PSK by using a cipher priority parameter such as in the + example below. + @example + $ ./gnutls-cli -p 5556 localhost --pskusername psk_identity \\ + --pskkey 88f3824b3e5659f52d00e959bacab954b6540344 \\ + --priority NORMAL:-KX-ALL:+ECDHE-PSK:+DHE-PSK:+PSK + Resolving 'localhost'... + Connecting to '127.0.0.1:5556'... + - PSK authentication. + - Version: TLS1.1 + - Key Exchange: PSK + - Cipher: AES-128-CBC + - MAC: SHA1 + - Compression: NULL + - Handshake was completed + + - Simple Client Mode: + @end example + By keeping the --pskusername parameter and removing the --pskkey + parameter, it will query only for the password during the handshake. + + To list the ciphersuites in a priority string: + @example + $ ./gnutls-cli --priority SECURE192 -l + Cipher suites for SECURE192 + TLS_ECDHE_ECDSA_AES_256_CBC_SHA384 0xc0, 0x24 TLS1.2 + TLS_ECDHE_ECDSA_AES_256_GCM_SHA384 0xc0, 0x2e TLS1.2 + TLS_ECDHE_RSA_AES_256_GCM_SHA384 0xc0, 0x30 TLS1.2 + TLS_DHE_RSA_AES_256_CBC_SHA256 0x00, 0x6b TLS1.2 + TLS_DHE_DSS_AES_256_CBC_SHA256 0x00, 0x6a TLS1.2 + TLS_RSA_AES_256_CBC_SHA256 0x00, 0x3d TLS1.2 + @end example + _EOT_; +}; +// END-DEFS +_End_Of_Definitions_ + +# # # # # # # # # # # TEXI TEXT + +cat <<_End_Of_TexInfo_ +## BEGIN-TEXI +@node doc Invocation +@section Invoking doc +@pindex doc +@cindex GnuTLS client +Simple client program to set up a TLS connection to some other computer. +It sets up a TLS connection and forwards data from the standard input +to the secured socket and vice versa. + +This section was generated by @strong{AutoGen}, +using the @code{agtexi-cmd} template and the option descriptions for the @code{doc} program. +This software is released under the GNU General Public License, version 3 or later. + +@menu +* doc usage:: doc help/usage (@option{--help}) +* doc base-options:: Base options +* doc group-2:: group-2 options +* doc group-3:: group-3 options +* doc exit status:: exit status +* doc Examples:: Examples +@end menu + +@node doc usage +@subsection doc help/usage (@option{--help}) +@cindex doc help + +This is the automatically generated usage text for doc. + +The text printed is the same whether selected with the @code{help} option +(@option{--help}) or the @code{more-help} option (@option{--more-help}). @code{more-help} will print +the usage text by passing it through a pager program. +@code{more-help} is disabled on platforms without a working +@code{fork(2)} function. The @code{PAGER} environment variable is +used to select the program, defaulting to @file{more}. Both will exit +with a status code of 0. + +@exampleindent 0 +@example +doc is unavailable - no --help +@end example +@exampleindent 4 + +@node doc +@subsection Base options +@subsubheading debug option (-d). +@anchor{doc debug} +@cindex doc-debug + +This is the ``enable @code{debugging}'' option. +This option takes a number argument. +really enable debugging +@subsubheading mtu option. +@anchor{doc mtu} +@cindex doc-mtu + +This is the ``set mtu for datagram tls'' option. +This option takes a number argument. +Really set MTU for datagram TLS +@node doc group-2 +@subsection group-2 options +second group of options. +@subsubheading crlf option. +@anchor{doc crlf} +@cindex doc-crlf + +This is the ``send cr lf instead of lf'' option. +Really send CR LF instead of LF +@subsubheading x509fmtder option. +@anchor{doc x509fmtder} +@cindex doc-x509fmtder + +This is the ``use der format for certificates to read from'' option. +Really use DER format for certificates to read from +@node doc group-3 +@subsection group-3 options +third group of options. +@subsubheading recordsize option. +@anchor{doc recordsize} +@cindex doc-recordsize + +This is the ``the maximum record size to advertize'' option. +This option takes a number argument. +Really the maximum record size to advertize +@subsubheading priority option. +@anchor{doc priority} +@cindex doc-priority + +This is the ``priorities string'' option. +This option takes a string argument. +TLS algorithms and protocols to enable. You can +use predefined sets of ciphersuites such as PERFORMANCE, +NORMAL, SECURE128, SECURE256. + +Check the GnuTLS manual on section ``Priority strings'' for more +information on allowed keywords +@node doc exit status +@subsection doc exit status + +One of the following exit values will be returned: +@table @samp +@item 0 (EXIT_SUCCESS) +Successful program execution. +@item 1 (EXIT_FAILURE) +The operation failed or the command syntax was not valid. +@end table +@node doc Examples +@subsection doc Examples +To connect to a server using PSK authentication, you need to enable +the choice of PSK by using a cipher priority parameter such as in the +example below. +@example +$ ./gnutls-cli -p 5556 localhost --pskusername psk_identity \\ + --pskkey 88f3824b3e5659f52d00e959bacab954b6540344 \\ + --priority NORMAL:-KX-ALL:+ECDHE-PSK:+DHE-PSK:+PSK +Resolving 'localhost'... +Connecting to '127.0.0.1:5556'... +- PSK authentication. +- Version: TLS1.1 +- Key Exchange: PSK +- Cipher: AES-128-CBC +- MAC: SHA1 +- Compression: NULL +- Handshake was completed + +- Simple Client Mode: +@end example +By keeping the --pskusername parameter and removing the --pskkey +parameter, it will query only for the password during the handshake. + +To list the ciphersuites in a priority string: +@example +$ ./gnutls-cli --priority SECURE192 -l +Cipher suites for SECURE192 +TLS_ECDHE_ECDSA_AES_256_CBC_SHA384 0xc0, 0x24 TLS1.2 +TLS_ECDHE_ECDSA_AES_256_GCM_SHA384 0xc0, 0x2e TLS1.2 +TLS_ECDHE_RSA_AES_256_GCM_SHA384 0xc0, 0x30 TLS1.2 +TLS_DHE_RSA_AES_256_CBC_SHA256 0x00, 0x6b TLS1.2 +TLS_DHE_DSS_AES_256_CBC_SHA256 0x00, 0x6a TLS1.2 +TLS_RSA_AES_256_CBC_SHA256 0x00, 0x3d TLS1.2 +@end example +## END-TEXI +_End_Of_TexInfo_ + +# # # # # # # # # # # MAN PAGE + +cat <<_End_Of_ManPage_ +## BEGIN-MAN +.de1 NOP +. it 1 an-trap +. if \\n[.$] \,\\$*\/ +.. +.ie t \ +.ds B-Font [CB] +.ds I-Font [CI] +.ds R-Font [CR] +.el \ +.ds B-Font B +.ds I-Font I +.ds R-Font R +.TH doc 1 +.SH NAME +\f\*[B-Font]doc\fP +\- GnuTLS client +.SH SYNOPSIS +\f\*[B-Font]doc\fP +[\f\*[B-Font]\-flags\f[]] +[\f\*[B-Font]\-flag\f[] [\f\*[I-Font]value\f[]]] +[\f\*[B-Font]\-\-option-name\f[][[=| ]\f\*[I-Font]value\f[]]] +[hostname] +.sp \n(Ppu +.ne 2 +Operands and options may be intermixed. They will be reordered. +.sp \n(Ppu +.ne 2 +.SH "DESCRIPTION" +Simple client program to set up a TLS connection to some other computer. +It sets up a TLS connection and forwards data from the standard input +to the secured socket and vice versa. +.SH "OPTIONS" +.TP +.NOP \f\*[B-Font]\-d\f[] \f\*[I-Font]number\f[], \f\*[B-Font]\-\-debug\f[]=\f\*[I-Font]number\f[] +Enable \fBdebugging\fP. +This option takes an integer number as its argument. +The value of +\f\*[I-Font]number\f[] +is constrained to being: +.in +4 +.nf +.na +in the range 0 through 9999 +.fi +.in -4 +.sp +really enable debugging +.TP +.NOP \f\*[B-Font]\-\-mtu\f[]=\f\*[I-Font]number\f[] +Set MTU for datagram TLS. +This option takes an integer number as its argument. +The value of +\f\*[I-Font]number\f[] +is constrained to being: +.in +4 +.nf +.na +in the range 0 through 17000 +.fi +.in -4 +.sp +Really set MTU for datagram TLS +.SS "second group of options" +.TP +.NOP \f\*[B-Font]\-\-crlf\f[] +Send CR LF instead of LF. +.sp +Really send CR LF instead of LF +.TP +.NOP \f\*[B-Font]\-\-x509fmtder\f[] +Use DER format for certificates to read from. +.sp +Really use DER format for certificates to read from +.SS "third group of options" +.TP +.NOP \f\*[B-Font]\-\-recordsize\f[]=\f\*[I-Font]number\f[] +The maximum record size to advertize. +This option takes an integer number as its argument. +The value of +\f\*[I-Font]number\f[] +is constrained to being: +.in +4 +.nf +.na +in the range 0 through 4096 +.fi +.in -4 +.sp +Really the maximum record size to advertize +.TP +.NOP \f\*[B-Font]\-\-priority\f[]=\f\*[I-Font]string\f[] +Priorities string. +.sp +TLS algorithms and protocols to enable. You can +use predefined sets of ciphersuites such as PERFORMANCE, +NORMAL, SECURE128, SECURE256. +.sp +Check the GnuTLS manual on section \(lqPriority strings\(rq for more +information on allowed keywords +.TP +.NOP \f\*[B-Font]\-h\f[], \f\*[B-Font]\-\-help\f[] +Display usage information and exit. +.TP +.NOP \f\*[B-Font]\-M\f[], \f\*[B-Font]\-\-more\-help\f[] +Pass the extended usage information through a pager. +.TP +.NOP \f\*[B-Font]\-v\f[] [{\f\*[I-Font]v|c|n\f[] \f\*[B-Font]\-\-version\f[] [{\f\*[I-Font]v|c|n\f[]}]}] +Output version of program and exit. The default mode is `v', a simple +version. The `c' mode will print copyright information and `n' will +print the full copyright notice. +.PP +.sp +.SH EXAMPLES +To connect to a server using PSK authentication, you need to enable +the choice of PSK by using a cipher priority parameter such as in the +example below. +.br +.in +4 +.nf +$ ./gnutls\-cli \-p 5556 localhost \-\-pskusername psk_identity \\ + \-\-pskkey 88f3824b3e5659f52d00e959bacab954b6540344 \\ + \-\-priority NORMAL:\-KX\-ALL:+ECDHE\-PSK:+DHE\-PSK:+PSK +Resolving 'localhost'... +Connecting to '127.0.0.1:5556'... +- PSK authentication. +- Version: TLS1.1 +- Key Exchange: PSK +- Cipher: AES\-128\-CBC +- MAC: SHA1 +- Compression: NULL +- Handshake was completed +.sp +- Simple Client Mode: +.in -4 +.fi +By keeping the \-\-pskusername parameter and removing the \-\-pskkey +parameter, it will query only for the password during the handshake. +.sp +To list the ciphersuites in a priority string: +.br +.in +4 +.nf +$ ./gnutls\-cli \-\-priority SECURE192 \-l +Cipher suites for SECURE192 +TLS_ECDHE_ECDSA_AES_256_CBC_SHA384 0xc0, 0x24 TLS1.2 +TLS_ECDHE_ECDSA_AES_256_GCM_SHA384 0xc0, 0x2e TLS1.2 +TLS_ECDHE_RSA_AES_256_GCM_SHA384 0xc0, 0x30 TLS1.2 +TLS_DHE_RSA_AES_256_CBC_SHA256 0x00, 0x6b TLS1.2 +TLS_DHE_DSS_AES_256_CBC_SHA256 0x00, 0x6a TLS1.2 +TLS_RSA_AES_256_CBC_SHA256 0x00, 0x3d TLS1.2 +.in -4 +.fi +.SH "EXIT STATUS" +One of the following exit values will be returned: +.TP +.NOP 0 " (EXIT_SUCCESS)" +Successful program execution. +.TP +.NOP 1 " (EXIT_FAILURE)" +The operation failed or the command syntax was not valid. +.TP +.NOP 70 " (EX_SOFTWARE)" +libopts had an internal operational error. Please report +it to autogen-users@lists.sourceforge.net. Thank you. +.PP +.SH "SEE ALSO" +gnutls\-cli\-debug(1), gnutls\-serv(1) +.SH "AUTHORS" +Nikos Mavrogiannopoulos, Simon Josefsson and others; see /usr/share/doc/gnutls-bin/AUTHORS for a complete list. +.SH "COPYRIGHT" +Copyright (C) 2000-2018 Free Software Foundation all rights reserved. +This program is released under the terms of the GNU General Public License, version 3 or later. +.SH "BUGS" +Please send bug reports to: bug-gnutls@gnu.org +.SH "NOTES" +This manual page was \fIAutoGen\fP-erated from the \fBdoc\fP +option definitions. +## END-MAN +_End_Of_ManPage_ + +# # # # # # # # # # # MDOC PAGE + +cat <<_End_Of_MdocPage_ +## BEGIN-MDOC +.Dt DOC 1 User Commands +.Os +.Sh NAME +.Nm doc +.Nd GnuTLS client +.Sh SYNOPSIS +.Nm +.Op Fl flags +.Op Fl flag Op Ar value +.Op Fl \-option\-name Ns Oo Oo Ns "=| " Oc Ns Ar value Oc +[hostname] +.Pp +Operands and options may be intermixed. They will be reordered. +.Pp +.Sh "DESCRIPTION" +Simple client program to set up a TLS connection to some other computer. +It sets up a TLS connection and forwards data from the standard input +to the secured socket and vice versa. +.Sh "OPTIONS" +.Bl -tag +.It Fl d Ar number , Fl \-debug Ns = Ns Ar number +Enable \fBdebugging\fP. +This option takes an integer number as its argument. +The value of +.Ar number +is constrained to being: +.in +4 +.nf +.na +in the range 0 through 9999 +.fi +.in -4 +.sp +really enable debugging +.It Fl \-mtu Ns = Ns Ar number +Set MTU for datagram TLS. +This option takes an integer number as its argument. +The value of +.Ar number +is constrained to being: +.in +4 +.nf +.na +in the range 0 through 17000 +.fi +.in -4 +.sp +Really set MTU for datagram TLS +.Ss "second group of options" +.It Fl \-crlf +Send CR LF instead of LF. +.sp +Really send CR LF instead of LF +.It Fl \-x509fmtder +Use DER format for certificates to read from. +.sp +Really use DER format for certificates to read from +.Ss "third group of options" +.It Fl \-recordsize Ns = Ns Ar number +The maximum record size to advertize. +This option takes an integer number as its argument. +The value of +.Ar number +is constrained to being: +.in +4 +.nf +.na +in the range 0 through 4096 +.fi +.in -4 +.sp +Really the maximum record size to advertize +.It Fl \-priority Ns = Ns Ar string +Priorities string. +.sp +TLS algorithms and protocols to enable. You can +use predefined sets of ciphersuites such as PERFORMANCE, +NORMAL, SECURE128, SECURE256. +.sp +Check the GnuTLS manual on section \(lqPriority strings\(rq for more +information on allowed keywords +.It Fl h , Fl \-help +Display usage information and exit. +.It Fl M , Fl \-more\-help +Pass the extended usage information through a pager. +.It Fl v Op Brq Ar v|c|n Fl \-version Op Brq Ar v|c|n +Output version of program and exit. The default mode is `v', a simple +version. The `c' mode will print copyright information and `n' will +print the full copyright notice. +.El +.sp +.Sh EXAMPLES +To connect to a server using PSK authentication, you need to enable +the choice of PSK by using a cipher priority parameter such as in the +example below. +.Bd -literal -offset indent +$ ./gnutls\-cli \-p 5556 localhost \-\-pskusername psk_identity \\ + \-\-pskkey 88f3824b3e5659f52d00e959bacab954b6540344 \\ + \-\-priority NORMAL:\-KX\-ALL:+ECDHE\-PSK:+DHE\-PSK:+PSK +Resolving 'localhost'... +Connecting to '127.0.0.1:5556'... +- PSK authentication. +- Version: TLS1.1 +- Key Exchange: PSK +- Cipher: AES\-128\-CBC +- MAC: SHA1 +- Compression: NULL +- Handshake was completed +.sp +- Simple Client Mode: +.Ed +By keeping the \-\-pskusername parameter and removing the \-\-pskkey +parameter, it will query only for the password during the handshake. +.sp +To list the ciphersuites in a priority string: +.Bd -literal -offset indent +$ ./gnutls\-cli \-\-priority SECURE192 \-l +Cipher suites for SECURE192 +TLS_ECDHE_ECDSA_AES_256_CBC_SHA384 0xc0, 0x24 TLS1.2 +TLS_ECDHE_ECDSA_AES_256_GCM_SHA384 0xc0, 0x2e TLS1.2 +TLS_ECDHE_RSA_AES_256_GCM_SHA384 0xc0, 0x30 TLS1.2 +TLS_DHE_RSA_AES_256_CBC_SHA256 0x00, 0x6b TLS1.2 +TLS_DHE_DSS_AES_256_CBC_SHA256 0x00, 0x6a TLS1.2 +TLS_RSA_AES_256_CBC_SHA256 0x00, 0x3d TLS1.2 +.Ed +.Sh "EXIT STATUS" +One of the following exit values will be returned: +.Bl -tag +.It 0 " (EXIT_SUCCESS)" +Successful program execution. +.It 1 " (EXIT_FAILURE)" +The operation failed or the command syntax was not valid. +.It 70 " (EX_SOFTWARE)" +libopts had an internal operational error. Please report +it to autogen\-users@lists.sourceforge.net. Thank you. +.El +.Sh "SEE ALSO" +gnutls\-cli\-debug(1), gnutls\-serv(1) +.Sh "AUTHORS" +Nikos Mavrogiannopoulos, Simon Josefsson and others; see /usr/share/doc/gnutls\-bin/AUTHORS for a complete list. +.Sh "COPYRIGHT" +Copyright (C) 2000\-2018 Free Software Foundation all rights reserved. +This program is released under the terms of the GNU General Public License, version 3 or later. +.Sh "BUGS" +Please send bug reports to: bug\-gnutls@gnu.org +.Sh "NOTES" +This manual page was \fIAutoGen\fP\-erated from the \fBdoc\fP +option definitions. +## END-MDOC +_End_Of_MdocPage_ + +# # # # # # # # # # # POT PAGE + +cat <<_End_Of_PotPage_ +## BEGIN-POT +# localization template (.pot) for doc.def of doc, +# this file is used to generate localized manual for doc. +# Copyright (C) +# This file is distributed under the terms of the +# the GNU General Public License, version 3 or later +# The program owners may be reached via: +# Free Software Foundation . +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: doc 3.0.12\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date:\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" +#: doc.def:3 +msgid "GnuTLS client" +msgstr "" +#: doc.def:42 +msgid "Enable debugging" +msgstr "" +#: doc.def:43 +msgid "really enable debugging" +msgstr "" +#: doc.def:50 +msgid "Set MTU for datagram TLS" +msgstr "" +#: doc.def:51 +msgid "Really set MTU for datagram TLS" +msgstr "" +#: doc.def:56 +msgid "second group of options" +msgstr "" +#: doc.def:62 +msgid "Send CR LF instead of LF" +msgstr "" +#: doc.def:63 +msgid "Really send CR LF instead of LF" +msgstr "" +#: doc.def:68 +msgid "Use DER format for certificates to read from" +msgstr "" +#: doc.def:69 +msgid "Really use DER format for certificates to read from" +msgstr "" +#: doc.def:74 +msgid "third group of options" +msgstr "" +#: doc.def:82 +msgid "The maximum record size to advertize" +msgstr "" +#: doc.def:83 +msgid "Really the maximum record size to advertize" +msgstr "" +#: doc.def:89 +msgid "Priorities string" +msgstr "" +#: doc.def:91 +msgid "TLS algorithms and protocols to enable. You can use predefined sets of\n" + "ciphersuites such as PERFORMANCE, NORMAL, SECURE128, SECURE256.\n\n" + "Check the GnuTLS manual on section ``Priority strings'' for more\n" + "information on allowed keywords" +msgstr "" +#: doc.def:6 +msgid "Usage: gnutls-cli [options] hostname gnutls-cli --help for usage\n" + "instructions." +msgstr "" +#: doc.def:11 +msgid "Simple client program to set up a TLS connection to some other computer.\n" + "It sets up a TLS connection and forwards data from the standard input to\n" + "the secured socket and vice versa." +msgstr "" + +#: +msgid "This program is released under the terms of the GNU General Public License, version 3 or later." +msgstr "" + +#: doc.def:21 +msgid "[hostname]" +msgstr "" +## END-POT +_End_Of_PotPage_ + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## End: + +# end of doc.test diff --git a/autoopts/test/enums.test b/autoopts/test/enums.test new file mode 100755 index 0000000..c909a96 --- /dev/null +++ b/autoopts/test/enums.test @@ -0,0 +1,309 @@ +#! /bin/sh +# -*- Mode: shell-script -*- +# ---------------------------------------------------------------------- +# enums.test --- test enums program attribute +# make sure that when it is not specified +# then option processing consumes all args. +# +# Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +cat > ${testname}.def <<- _EOF_ + autogen definitions options; + + prog-name = ${testname}-test; + prog-title = 'test complex main procedure'; + config-header = config.h; + + argument = '[ ]'; + long-opts; + + flag = { + name = print; + value = p; + descrip = 'Print operational info'; + arg-type = keyword; + arg-name = type; + min = 1; + equivalence = print; + keyword = one, two, three, four, five, six, seven, eight, nine, ten; + }; + + flag = { + name = dump-log; + value = D; + descrip = 'Dump the program log'; + equivalence = print; + }; + + flag = { + name = all-dump; + value = A; + equivalence = print; + descrip = 'Dump everything we\'ve got'; + }; + + flag = { + name = set; + value = s; + descrip = 'set options'; + arg-type = set; + arg-name = 'opt[, ...]'; + arg-default = first,fifth,ninth,thirteenth; + equivalence = print; + keyword = first, second, third, fourth, fifth, sixth, seventh, + eighth, ninth, tenth, eleventh, twelfth, thirteenth, + fourteenth, fifteenth, sixteenth; + }; + + flag = { + name = unset; + value = u; + descrip = 'unset debug options'; + arg-type = string; + arg-name = 'opt[, ...]'; + equivalence = print; + flag-proc = set; + }; + + flag = { + name = msg-num; + value = m; + descrip = 'message number'; + no-preset; + arg-type = string; + arg-name = id; + max = NOLIMIT; + + flag-code = <<- _EndOfFlagCode_ + /* + * 'set' and 'unset' must be acted upon immediately + * -- we may get more of them. + */ + switch (WHICH_IDX_PRINT) { + case NO_EQUIVALENT: + case INDEX_OPT_PRINT: + case INDEX_OPT_DUMP_LOG: + case INDEX_OPT_ALL_DUMP: + if (COUNT_OPT( MSG_NUM ) > 1) { + fputs("Except for 'set' and 'unset' functions, " + "only one 'msg-num' is allowed\n", stderr); + USAGE(EXIT_FAILURE); + } + break; + case INDEX_OPT_SET: + set_options(1, pOptDesc->pzLastArg); + break; + case INDEX_OPT_UNSET: + set_options(0, pOptDesc->pzLastArg); + break; + }; + _EndOfFlagCode_; + }; + /* + cat <<_EOF_ + * for emacs */ + + export = "#include \n" + "#include \n" + "#include \n" + "#include \n" + "#include \n" + "#include \"config.h\"\n" + "#include \"compat/compat.h\""; + + include = 'void set_options(int mode, char const* pzArg);'; + + main = { + main-type = include; + tpl = ${testname}.tpl; + }; + _EOF_ + +# # # # # # # # # # TEMPLATE FILE # # # # # # # # # +# +# In one case we must not use built in echo. +# +cat > ${testname}.tpl <<- \__EOF + [= AutoGen5 Template -*- Mode: C -*- =] + [=(define proc-list "")=] + typedef int (do_proc_t)(void); + extern do_proc_t + [= (set! proc-list (string-append "do_print_undefined,\ndo_print_" + (join ",\ndo_print_" (stack "flag[0].keyword")) )) + (set! proc-list + (shell (string-append "${CLexe} -I4 --spread=1 <<_EOF_\n" + proc-list "\n_EOF_")) ) + proc-list =]; + do_proc_t* do_proc[] = { + [= (. proc-list) =] }; + + [=(shellf "procs='%s' ; ix=0 ; for p in ${procs} + do + p=`echo $p | sed s/,//` + echo int ${p}'(void) {' + printf ' fputs(\"'${p}'\\\\n\", stdout);\n' + echo \" return ${ix}; }\" + ix=`expr $ix + 1` + done" proc-list) =] + + int + do_dump_log(void) + { + return WHICH_IDX_PRINT != INDEX_OPT_DUMP_LOG; + } + + int + do_all_dump(void) + { + return WHICH_IDX_PRINT != INDEX_OPT_ALL_DUMP; + } + + int + do_set(int which_way) + { + printf("PRINT = 0x%lX\n", (unsigned long)DESC(PRINT).optCookie); + printf("SET = 0x%lX\n", (unsigned long)DESC(SET).optCookie); + if (which_way) + printf("0x%lX\n", OPT_VALUE_SET); + else + printf("0x%lX\n", (~ OPT_VALUE_SET) & SET_MEMBERSHIP_MASK); + return 0; + } + + void + set_options(int mode, char const* pzArg) + { + exit(atoi(pzArg)); + } + __EOF + +cat >> ${testname}.tpl <<- __EOF + int + main( int argc, char** argv ) + { + { + int ct = optionProcess(&${testname}_testOptions, argc, argv); + argc -= ct; + argv += ct; + } + + if (argc > 1) + return EXIT_FAILURE; + + /* + * Invoke the proper operational procedure. + */ + { + int res = 0; + switch (WHICH_IDX_PRINT) { + case INDEX_OPT_PRINT: res = do_proc[OPT_VALUE_PRINT](); break; + case INDEX_OPT_DUMP_LOG: res = do_dump_log(); break; + case INDEX_OPT_ALL_DUMP: res = do_all_dump(); break; + case INDEX_OPT_SET: res = do_set(1); break; + case INDEX_OPT_UNSET: res = do_set(0); break; + } + return res; + } + } + __EOF + +# # # # # # # # # # CREATE PROGRAM # # # # # # # # # + +echo ${AG_L} ${testname}.def +${AG_L} ${testname}.def || \ + failure AutoGen could not process + +compile "-?" + +# # # # # # # # # # HELP OUTPUT FILE # # # # # # # # # + +basehlp=${testname}.hlp +echo creating ${basehlp} +clean_help > ${basehlp} <<_EOF_ +${testname}-test - test complex main procedure +Usage: ${testname} { - [] | --[{=| }] }... [ ] + Flg Arg Option-Name Req? Description + -p KWd print YES Print operational info + -D no dump-log opt Dump the program log + - an alternate for 'print' + -A no all-dump opt Dump everything we've got + - an alternate for 'print' + -s Mbr set opt set options + - an alternate for 'print' + -u Str unset opt unset debug options + - an alternate for 'print' + -m Str msg-num opt message number + - may not be preset + - may appear multiple times + -? no help opt display extended usage information and exit + -! no more-help opt extended usage information passed thru pager + +Options are specified by doubled hyphens and their name or by a single +hyphen and the flag character. + +The valid "print" option keywords are: + one two three four five six seven eight nine ten + or an integer from 1 through 10 +The valid "set" option keywords are: + first second third fourth fifth sixth seventh + eighth ninth tenth eleventh twelfth thirteenth fourteenth + fifteenth sixteenth + or an integer mask with any of the lower 16 bits set +or you may use a numeric representation. Preceding these with a '!' +will clear the bits, specifying 'none' will clear all bits, and 'all' +will set them all. Multiple entries may be passed as an option +argument list. +_EOF_ + +cmp -s ${testname}.h*lp || \ + failure "`diff ${basehlp} ${testname}.help`" + +# # # # # # # # # # TEST OPERATION # # # # # # # # # # + +ix=0 +for f in one two three four five six seven eight nine ten +do + ix=`expr $ix + 1` + txt=`./${testname} -p $f` + test $? -eq $ix || \ + failure "'./${testname} -p $f' did not yield $ix" + test "${txt}" = "do_print_${f}" || \ + failure "'./${testname} -p $f' did not print 'do_print_${f}'" +done + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of enums.test diff --git a/autoopts/test/equiv.test b/autoopts/test/equiv.test new file mode 100755 index 0000000..4759b7c --- /dev/null +++ b/autoopts/test/equiv.test @@ -0,0 +1,273 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# +# equiv.test --- test option equivivalence classes +# +# Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +. ./defs + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +echo "creating ${testname}.def in `pwd`" +CFLAGS="-g -static" \ +testname="${testname}" test_main="${test_main}" \ +argument="${argument}" long_opts="${long_opts}" \ +${SHELLX} ${stdopts} option:'opt init' second=020 || \ + failure "Could not run stdopts.def" +cat >> ${testname}.def <<'_EOF_' +long-opts; + +flag = { + name = alpha; + descrip = "alpha opt"; + equivalence = alpha; + doc = 'alpha mumbling'; + arg-type = str; + arg-optional; +}; + +flag = { + name = beta; + descrip = "beta opt"; + equivalence = alpha; + doc = 'beta mumbling'; + arg-type = num; +}; + +flag = { + name = gamma; + descrip = "gamma opt"; + equivalence = alpha; + doc = 'gamma mumbling'; + arg-type = bool; +}; + +flag = { + name = omega; + descrip = "omega opt"; + equivalence = alpha; + doc = 'omega mumbling'; + arg-type = key; + keyword = uno, dos, tres, mucho; + arg-optional; + arg-default = mucho; +}; +_EOF_ +echo ${AG_L} ${testname}.def +${AG_L} ${testname}.def || \ + failure "AutoGen could not process - exited $?" + +compile "-?" + +# # # # # # # # # # HELP OUTPUT FILE # # # # # # # # # + +echo creating ${testname}-base.help +clean_help > ${testname}-base.help <<_EOF_ +test_${testname} - Test AutoOpts for ${testname} +Usage: equiv [ - [] | --[{=| }] ]... + Flg Arg Option-Name Description + -o Str option The option option descrip + -s Num second The second option descrip + opt alpha alpha opt + Num beta beta opt + - an alternate for 'alpha' + T/F gamma gamma opt + - an alternate for 'alpha' + opt omega omega opt + - an alternate for 'alpha' + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + +Options are specified by doubled hyphens and their name or by a single +hyphen and the flag character. + +The valid "omega" option keywords are: + uno dos tres mucho + or an integer from 0 through 3 +_EOF_ + +cmp -s ${testname}*.help || \ + failure "`diff ${testname}-base.help ${testname}.help`" + +cat > ${testname}-base.out <<_EOF_ +OPTION_CT=3 +export OPTION_CT +TEST_EQUIV_SECOND=2 # 0x2 +export TEST_EQUIV_SECOND +TEST_EQUIV_ALPHA=1 # 0x1 +export TEST_EQUIV_ALPHA +=== --beta 5 -o opt === +OPTION_CT=4 +export OPTION_CT +TEST_EQUIV_OPTION='opt' +export TEST_EQUIV_OPTION +TEST_EQUIV_ALPHA_MODE='BETA' +export TEST_EQUIV_ALPHA_MODE +TEST_EQUIV_BETA=5 # 0x5 +export TEST_EQUIV_BETA +=== --gamma Yes! === +OPTION_CT=2 +export OPTION_CT +TEST_EQUIV_ALPHA_MODE='GAMMA' +export TEST_EQUIV_ALPHA_MODE +TEST_EQUIV_GAMMA='true' +export TEST_EQUIV_GAMMA +=== --gamma false === +OPTION_CT=2 +export OPTION_CT +TEST_EQUIV_ALPHA_MODE='GAMMA' +export TEST_EQUIV_ALPHA_MODE +TEST_EQUIV_GAMMA='false' +export TEST_EQUIV_GAMMA +=== --omega tres === +OPTION_CT=2 +export OPTION_CT +TEST_EQUIV_ALPHA_MODE='OMEGA' +export TEST_EQUIV_ALPHA_MODE +TEST_EQUIV_OMEGA='tres' +export TEST_EQUIV_OMEGA +_EOF_ + +( set -e +x + ./${testname} --alpha -s 2 + echo === --beta 5 -o opt === + ./${testname} --beta 5 -o opt + echo === --gamma Yes! === + ./${testname} --gamma Yes! + echo === --gamma false === + ./${testname} --gamma false + echo === --omega tres === + ./${testname} --omega tres ) > ${testname}.out + +cmp -s ${testname}-base.out ${testname}.out || \ + failure "` + diff -c ${testname}-base.out ${testname}.out`" + +# # # # # # # # # # HELP OUTPUT FILE # # # # # # # # # + +echo creating ${testname}-base2.help +clean_help > ${testname}-base2.help <<_EOF_ +test_${testname} - Test AutoOpts for ${testname} +Usage: equiv [ - [] | --[{=| }] ]... + Flg Arg Option-Name Description + -o Str option The option option descrip + -s Num second The second option descrip + opt alpha alpha opt + Num beta beta opt + - an alternate for 'alpha' + T/F gamma gamma opt + - an alternate for 'alpha' + opt omega omega opt + - an alternate for 'alpha' + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + -> opt save-opts save the option state to a config file + -< Str load-opts load options from a config file + - disabled as '--no-load-opts' + - may appear multiple times + +Options are specified by doubled hyphens and their name or by a single +hyphen and the flag character. + +The following option preset mechanisms are supported: + - reading file ..../TD/.test_equivrc + +The valid "omega" option keywords are: + uno dos tres mucho + or an integer from 0 through 3 +_EOF_ + +echo 'homerc = "$$";' >> ${testname}.def + +echo ${AG_L} ${testname}.def +${AG_L} ${testname}.def || \ + failure AutoGen could not process + +compile "-?" +${SED} '/^ - reading file/s, file .*-testd/, file ..../TD/,' \ + ${testname}.help > ${testname}-test2.help +cmp -s ${testname}-base2.help ${testname}-test2.help || \ + failure "`diff ${testname}-base2.help ${testname}-test2.help`" + +echo 'gamma Yes' > .test_equivrc + +cat > ${testname}-base.out2 <<_EOF_ +=== -o opt === +OPTION_CT=2 +export OPTION_CT +TEST_EQUIV_OPTION='opt' +export TEST_EQUIV_OPTION +TEST_EQUIV_ALPHA_MODE='GAMMA' +export TEST_EQUIV_ALPHA_MODE +TEST_EQUIV_GAMMA='true' +export TEST_EQUIV_GAMMA +=== --gamma Yes! === +OPTION_CT=2 +export OPTION_CT +TEST_EQUIV_ALPHA_MODE='GAMMA' +export TEST_EQUIV_ALPHA_MODE +TEST_EQUIV_GAMMA='true' +export TEST_EQUIV_GAMMA +=== --gamma false === +OPTION_CT=2 +export OPTION_CT +TEST_EQUIV_ALPHA_MODE='GAMMA' +export TEST_EQUIV_ALPHA_MODE +TEST_EQUIV_GAMMA='false' +export TEST_EQUIV_GAMMA +=== --omega tres === +OPTION_CT=2 +export OPTION_CT +TEST_EQUIV_ALPHA_MODE='OMEGA' +export TEST_EQUIV_ALPHA_MODE +TEST_EQUIV_OMEGA='tres' +export TEST_EQUIV_OMEGA +_EOF_ + +( set -e + echo === -o opt === + ./${testname} -o opt + echo === --gamma Yes! === + ./${testname} --gamma Yes! + echo === --gamma false === + ./${testname} --gamma false + echo === --omega tres === + ./${testname} --omega tres ) > ${testname}.out2 + +cmp -s ${testname}-base.out2 ${testname}.out2 || \ + failure "` + diff -c ${testname}-base.out2 ${testname}.out2`" + +./${testname} --omega tres --beta 12 2>/dev/null && \ + failure "${testname}-2 ERROR: conflicting options accepted" + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## End: + +# end of equiv.test diff --git a/autoopts/test/errors.test b/autoopts/test/errors.test new file mode 100755 index 0000000..527df26 --- /dev/null +++ b/autoopts/test/errors.test @@ -0,0 +1,231 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# ---------------------------------------------------------------------- +# errors.test --- test argument program attribute +# make sure that when it is not specified +# then option processing consumes all args. +# +# Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd +${VERBOSE} && kill_delay=10 || kill_delay=5 +. ./defs + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +echo "creating ${testname}.def in `pwd`" + +testname="${testname}" \ +test_main="${test_main}" \ +argument="arg ..." \ +long_opts="yes" \ +${SHELLX} ${stdopts} option second:fumble ignored || \ + failure "Could not run stdopts.def" + +echo 'reorder-args;' >> ${testname}.def +${SED} -e '/"second"/a\ + must-set;' \ + -e '/"ignored"/a\ + omitted-usage = "we have dumped this"; ifdef = IGNORE_THIS;' \ + ${testname}.def > ${testname}.tmp +mv -f ${testname}.tmp ${testname}.def +echo "homerc = ${testname}RC;" >> ${testname}.def + +echo ${AG_L} ${testname}.def +${AG_L} ${testname}.def || \ + failure AutoGen could not process + +mkdir ${testname}RC +compile "--help" + +# # # # # # # # # # HELP OUTPUT FILE # # # # # # # # # + +echo creating ${testname}.res-help +clean_help > ${testname}.res-help <<'_EOF_' +test_errors - Test AutoOpts for errors +Usage: errors [ - [] | --[{=| }] ]... arg ... + Flg Arg Option-Name Description + -o no option The option option descrip + -s Str second The second option descrip + -i --- ignored we have dumped this + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + -> opt save-opts save the option state to a config file + -< Str load-opts load options from a config file + - disabled as '--no-load-opts' + - may appear multiple times + +Options are specified by doubled hyphens and their name or by a single +hyphen and the flag character. +Operands and options may be intermixed. They will be reordered. + +The following option preset mechanisms are supported: + - reading file errorsRC/.test_errorsrc +_EOF_ + +clean_help > ${testname}.ignored-expected <<\_EOF_ +errors: The 'ignored' option has been disabled. -- we have dumped this +test_errors - Test AutoOpts for errors +Usage: errors [ - [] | --[{=| }] ]... arg ... + Flg Arg Option-Name Description + -o no option The option option descrip + -s Str second The second option descrip + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + -> opt save-opts save the option state to a config file + -< Str load-opts load options from a config file + +Options are specified by doubled hyphens and their name or by a single +hyphen and the flag character. +Operands and options may be intermixed. They will be reordered. +_EOF_ + +dir=`pwd -P` || dir=`pwd` +${SED} "s#${dir}/##" ${testname}.help > ${testname}.bas-help +cmp -s ${testname}.*-help || \ + failure "help output: `diff ${testname}.*-help`" + +./${testname} -s foo -o -s bar 2> /dev/null && \ + failure ${testname} should not accept multiple options + +./${testname} -o -s foo > /dev/null 2>&1 && \ + failure ${testname} must have arguments + +./${testname} -o -s foo mumble > /dev/null || \ + failure ${testname} stumbled somehow + +./${testname} -o > /dev/null 2>&1 && \ + failure ${testname} "'option'" must have argument + +./${testname} -o mumble > /dev/null 2>&1 && \ + failure ${testname} must have second argument + +echo "second bumble" > ${testname}RC/.test_errorsrc +./${testname} -o mumble > /dev/null || \ + failure ${testname} did not see errorsRC/.test_errorsrc + +./${testname} --ignored > ${testname}.ignored 2>&1 && \ + failure "${testname} accepted --ignored" + +clean_help < ${testname}.ignored > ${testname}.ignored-result +cmp -s ${testname}.ignored-* || \ + failure "${testname}.ignored error: `diff ${testname}.ignored-*`" + +mv ${testname}RC/.test_errorsrc ${testname}RC/test_errors.rc +./${testname} --load=${testname}RC/test_errors.rc -o mumble > /dev/null || \ + failure ${testname} did not see errorsRC/test_errors.rc + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +echo "allow_errors;" >> ${testname}.def + +echo ${AG_L} ${testname}.def +${AG_L} ${testname}.def || \ + failure AutoGen could not process allow-errors + +compile "--help" + +${SED} "s#${dir}/##" ${testname}.help > ${testname}.bas-help +cmp -s ${testname}.*-help || \ + failure "help output: `diff ${testname}.*-help`" + +# This time, having a duplicate should be ignored... +# +./${testname} -s foo -o -s bar mumble 2> /dev/null 1>&2 || \ + failure ${testname} should not object to multiple options + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +${SED} '/second option/a\ + max = "10";' ${testname}.def > XX +mv -f XX ${testname}.def +cat >> ${testname}.def << '_EOF_' +flag = { + name = "another"; + max = '5'; + descrip = "Another option descrip"; + value = 'X'; +}; + +_EOF_ + +echo ${AG_L} ${testname}.def +${AG_L} ${testname}.def || \ + failure AutoGen could not process gnu-usage + +compile "--help" + +# # # # # # # # # # SORTED ARGS OUTPUT FILE # # # # # # # # # +test -n "${POSIXLY_CORRECT}" && { + POSIXLY_CORRECT='' + unset POSIXLY_CORRECT +} + +echo creating ${testname}-sh.samp +cat > ${testname}-sh.samp <<'_EOF_' +OPTION_CT=4 +export OPTION_CT +TEST_ERRORS_OPTION=1 # 0x1 +export TEST_ERRORS_OPTION +TEST_ERRORS_SECOND='foo' +export TEST_ERRORS_SECOND +TEST_ERRORS_ANOTHER=1 # 0x1 +export TEST_ERRORS_ANOTHER +set -- 'mum'\''ble' '-X' 'stumble' +OPTION_CT=0 +_EOF_ + +./${testname} "mum'ble" -os foo -X -- -X stumble > ${testname}-sh.out + +cmp -s ${testname}-sh.out ${testname}-sh.samp || \ + failure "`diff ${testname}-sh.samp ${testname}-sh.out`" + +cat >> ${testname}.def << '_EOF_' +flag = { + name = "still-another"; + ifdef = true ; ifndef = false; + descrip = "Another option descrip"; + value = 'Y'; +}; +_EOF_ + +case "${BASH_VERSION}" in +not-good-enough ) + echo "You are running Solaris without bash available." + echo "duplicate option flags cannot be tested." + ;; + +* ) + ${SED} '/ value /s/Y/X/;s/ ifndef =.*//' ${testname}.def > ${testname}-2.def + ${AG_L} ${testname}-2.def && \ + failure AutoGen processed conflicting flag values + ;; +esac + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## End: + +# end of errors.test diff --git a/autoopts/test/getopt.test b/autoopts/test/getopt.test new file mode 100755 index 0000000..7fa56d8 --- /dev/null +++ b/autoopts/test/getopt.test @@ -0,0 +1,674 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# +# getopt.test --- test getopt_long argument processing +# +# Author: Bruce Korb +# +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +. ./defs + +compile_getopt() { + run_ag opts -b${testname}-bn ${testname}.def || \ + failure "AutoGen could not process ${testname}.def #${1}" + + # Remove the variable comments so we can test against the expected result + # + ${SED} '/Last template edit:/d' getopt-test_${testname}.c \ + > ${testname}${1}-getopt.c + + # Finally, compile this thing: + # + ${CC} ${CFLAGS} -c ${testname}${1}-getopt.c || \ + failure "could not compile ${testname}1-getopt.c" + + ${SED} "${sed_omit_license}"' + /Packaged by /d + s@^Report .* bugs to.*"@\\n"@ + s@^Please send bug.*"@\\n"@ + s@\\n\\n\\n\\$@\\n\\n\\@ + s@\(and the flag character\.\\n.\)n\\$@\1@' ${testname}${1}-getopt.c \ + > ${testname}${1}-res.c + cmp -s ${testname}${1}-base.c ${testname}${1}-res.c || { set +x ; \ + failure "`diff -c ${testname}${1}-base.c ${testname}${1}-res.c`" ; } +} + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# Fix up a test-specific include directory: +# +# The getopt template presumes that everything has been installed. +# However, we have to work with the local stuff. So, remove the +# "autoopts-config" probing and replace with local stuff: +# +go_init() +{ + mkdir -p ${TMPDIR}/autoopts + test -d ${TMPDIR}/autoopts || exit 1 + CC="${CC} ${CFLAGS} ${INC}" + INC='' + AUTOGEN_TEMPL_DIRS=${TMPDIR} + CFLAGS="-I${TMPDIR}" + LDFLAGS="${LDFLAGS} ${LIB}" + export CFLAGS LDFLAGS TMPDIR AUTOGEN_TEMPL_DIRS INC CC + aolib=`find ${top_builddir}/autoopts -type f -name libopts.a` + case " ${LDFLAGS} " in + *' -lgen '* ) aolib=${aolib}\ -lgen ;; + esac + + cp ${top_srcdir}/autoopts/tpl/* ${TMPDIR}/. + test "X${top_srcdir}" = "X${top_builddir}" || \ + cp ${top_builddir}/autoopts/tpl/* ${TMPDIR}/. + chmod u+w ${TMPDIR}/* + + ${SED} -e "/^cflags=/s@=.*@='-I${TMPDIR}/autoopts -I${top_builddir}'@" \ + -e "/^ldflags=/s@=.*@='${aolib}'@" \ + ${TMPDIR}/usage.tlib > ${TMPDIR}/usage.tlib-XX + mv -f ${TMPDIR}/usage.tlib-XX ${TMPDIR}/usage.tlib + + # In order to compile correctly, we have to temporarily install the options.h + # header in our TMPDIR. We also must find that header first. Tweak CFLAGS: + # + DESTdestdir=${TMPDIR}/autoopts \ + top_builddir=${top_builddir} \ + CONFIG_SHELL="${SHELL}" \ + POSIX_SHELL="${SHELL}" \ + PS4='>ih-$FUNCNAME> ' \ + ${SHELLX} ${top_srcdir}/autoopts/install-hook.sh + + export AUTOGEN_TEMPL_DIRS=${TMPDIR} +} 1>&8 + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # +go_samples() { + + echo "creating ${testname}.def in `pwd`" + ${SED} -e '1,/^## *START-DEFS/d' \ + -e '/^## *END-DEFS/{;s/.*//;q;}' \ + ${srcdir}/getopt.test > ${testname}.def + + # # # # # # # # # # BASE-1 OUTPUT FILE # # # # # # # # # + + echo creating ${testname}1-base.c + ${SED} -e '1,/^## *START-SOURCE1/d' \ + -e '/## *[E]ND-SOURCE1/{;s/ *#* *END-SOURCE1.*//;q;}' \ + ${srcdir}/getopt.test > ${testname}1-base.c + + # # # # # # # # # # BASE-2 OUTPUT FILE # # # # # # # # # + + echo creating ${testname}2-base.c + ${SED} -e '1,/^## *START-SOURCE2/d' \ + -e '/## *[E]ND-SOURCE2/{;s/ *#* *END-SOURCE2.*//;q;}' \ + ${srcdir}/getopt.test > ${testname}2-base.c +} + +# # # # # # # # # # RESULTS TESTING # # # # # # # # # + +go_init +go_samples +compile_getopt 1 + +${GREP} 'getopt_long' /usr/include/getopt.h >/dev/null && { + CFLAGS="${CFLAGS} -D_GNU_SOURCE=1" + ${SED} '/REMOVE/d;$a\ +long-opts;\ +version-value; +' ${testname}.def > ${testname}2.def + mv -f ${testname}.def ${testname}1.def + mv -f ${testname}2.def ${testname}.def + + compile_getopt 2 +} + +cleanup +exit 0 + +# # # # # # # # # # ==== DATA ==== # # # # # # # # # + +cat <<- _EODefs_ +## START-DEFS +AutoGen definitions getopt; + +prog-name = "test_getopt"; +prog-title = "Test AutoOpts for getopt"; +main = { main-type = shell-process; main-text = "";}; +config-header = 'config.h'; + +settable; +version = '1.2.3'; +help-value = 'h'; +gnu-usage; +no-libopts; + +copyright = { + date = "2003-2018"; + owner = "Odyssey Computing Concepts, Inc."; + author= "Bruce Korb"; + eaddr = "bkorb@gnu.org"; + type = lgpl; +}; + +flag = { + name = "option"; + descrip = "The option option descrip"; + value = 'o'; + arg_type = string; arg_default = 'opt init'; +}; + +flag = { + name = "second"; + descrip = "The second option descrip"; + value = 's'; + arg_type = string; arg_default = '020'; +}; + +flag = { + name = no_val; + descrip = 'option with no flag'; + value = 'F'; /* REMOVE */ + flags-must = max_val; +}; + +flag = { + name = max_val; + descrip = 'option with max ct'; + value = 'X'; /* REMOVE */ + max = '5'; +}; + +flag = { + name = min2_val; + descrip = 'option with min ct'; + value = 'M'; /* REMOVE */ + max = '50'; + flags-cant = max_val; + min = '5'; +}; + +flag = { + name = min_val; + descrip = 'option with min ct'; + value = '2'; /* REMOVE */ + max = '50'; + min = '5'; +}; +## END-DEFS +_EODefs_ + +# # # # # # # # # + +cat <<- _EOSource1_ +## START-SOURCE1 +#include "getopt-test_getopt.h" + +#include + +#include +#include +#include +#include +#include "getopt-bn.h" + +#ifndef DIRCH +# if defined(_WIN32) && !defined(__CYGWIN__) +# define DIRCH '\\' +# else +# define DIRCH '/' +# endif +#endif +/* + * Option flag character list + */ +static char z_opts[] = "o:s:FXM2hv"; + +/* + * AutoOpts library replacement routines: + */ +noreturn void +optionUsage (tOptions * pOptions, int status) +{ + if (status != 0) + fprintf (stderr, _("Try `%s -h' for more information.\n"), + test_getoptOptions.pzProgName); + else + { + fputs (_("test_getopt - Test AutoOpts for getopt\n\ +Usage: test_getopt { - [] }...\n\n\ + -o str The option option descrip\n\ + -s str The second option descrip\n\ + -F option with no flag\n\ + -X option with max ct\n\ + -M option with min ct\n\ + -2 option with min ct\n\ + -v output version information and exit\n\ + -h display extended usage information and exit\n\n\ +\n"), stdout); + } + + exit (status); +} + +noreturn void +optionPrintVersion (tOptions * pOptions, tOptDesc * pOptDesc) +{ + char const * pz_by = + _("test_getopt 1.2.3\n\ +Written by Bruce Korb.\n\n\ +Copyright (C) 2003-2018 Odyssey Computing Concepts, Inc.\n\ +This is free software; see the source for copying conditions. There is NO\n\ +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"); + + fputs (pz_by, stdout); + exit (EXIT_SUCCESS); +} + +/* + * If an option appears more often than is allowed, ... + */ +static void +usage_too_many (tOptDesc* pOptDesc) +{ + char const * pz = + _("test_getopt error: the '%s' option appears more than %d times\n"); + fprintf (stderr, pz, pOptDesc->pz_Name, pOptDesc->optMaxCt); + USAGE(EXIT_FAILURE); +} + +/* + * There is at least one option that must appear. + */ +static void +usage_too_few (tOptDesc* pOptDesc) +{ + char const * pz = + _("test_getopt error: the '%s' option must appear %d times\n"); + fprintf (stderr, pz, pOptDesc->pz_Name, pOptDesc->optMinCt); + USAGE(EXIT_FAILURE); +} + +/* + * There is at least one pair of options that may not appear together + * on the command line. + */ +static void +usage_cannot (char const* pz_what, char const* pz_cant) +{ + char const * pz = + _("test_getopt error: the `%s' option conflicts with the `%s' option.\n"); + fprintf (stderr, pz, pz_what, pz_cant); + USAGE(EXIT_FAILURE); +} + +/* + * There is at least one pair of options that are required to appear + * together on the command line. + */ +static void +usage_must (char const* pz_what, char const* pz_must) +{ + char const * pz = + _("test_getopt error: the `%s' option requires the `%s' option.\n"); + fprintf (stderr, pz, pz_what, pz_must); + USAGE(EXIT_FAILURE); +} + +/* + * Process the options for the "test_getopt" program. + * This function was generated to use the getopt(3posix) function. + * There are 8 options for this program, + * including "help (usage)" and "version". + */ +int +process_test_getopt_opts (int argc, char** argv) +{ + { + char * pz_prog = strrchr (argv[0], DIRCH); + /* + * This violates the const-ness of the pzProgName field. + * The const-ness is to prevent accidents. This is not accidental. + */ + char ** pp = VOIDP(&(test_getoptOptions.pzProgName)); + + if (pz_prog != NULL) + pz_prog++; + else + pz_prog = argv[0]; + *pp = pz_prog; + } + + for (;;) { + switch (getopt (argc, argv, z_opts)) { + case -1: goto leave_processing; + case 0: break; + + case VALUE_OPT_OPTION: + if (HAVE_OPT(OPTION)) + usage_too_many (&DESC(OPTION)); + SET_OPT_OPTION(optarg); + break; + + case VALUE_OPT_SECOND: + if (HAVE_OPT(SECOND)) + usage_too_many (&DESC(SECOND)); + SET_OPT_SECOND(optarg); + break; + + case VALUE_OPT_NO_VAL: + if (HAVE_OPT(NO_VAL)) + usage_too_many (&DESC(NO_VAL)); + SET_OPT_NO_VAL; + break; + + case VALUE_OPT_MAX_VAL: + if (DESC(MAX_VAL).optOccCt++ >= DESC(MAX_VAL).optMaxCt) + usage_too_many (&DESC(MAX_VAL)); + SET_OPT_MAX_VAL; + break; + + case VALUE_OPT_MIN2_VAL: + if (DESC(MIN2_VAL).optOccCt++ >= DESC(MIN2_VAL).optMaxCt) + usage_too_many (&DESC(MIN2_VAL)); + SET_OPT_MIN2_VAL; + break; + + case VALUE_OPT_MIN_VAL: + if (DESC(MIN_VAL).optOccCt++ >= DESC(MIN_VAL).optMaxCt) + usage_too_many (&DESC(MIN_VAL)); + SET_OPT_MIN_VAL; + break; + + case VALUE_OPT_HELP: + USAGE(EXIT_SUCCESS); + /* NOTREACHED */ + + case VALUE_OPT_VERSION: + optionPrintVersion (&test_getoptOptions, &DESC(VERSION)); + /* NOTREACHED */ + + default: + USAGE(EXIT_FAILURE); + } + } leave_processing:; + + if (HAVE_OPT(NO_VAL)) { + if (! HAVE_OPT(MAX_VAL)) + usage_must (DESC(NO_VAL).pz_Name, DESC(MAX_VAL).pz_Name); + } + + if (HAVE_OPT(MIN2_VAL)) { + if (HAVE_OPT(MAX_VAL)) + usage_cannot (DESC(MIN2_VAL).pz_Name, DESC(MAX_VAL).pz_Name); + if (DESC(MIN2_VAL).optOccCt < DESC(MIN2_VAL).optMinCt) + usage_too_few (&DESC(MIN2_VAL)); + } + else + usage_too_few (&DESC(MIN2_VAL)); + + if (DESC(MIN_VAL).optOccCt < DESC(MIN_VAL).optMinCt) + usage_too_few (&DESC(MIN_VAL)); + + return 0; +} ## END-SOURCE1 +_EOSource1_ + +# # # # # # # # # + +cat <<- _EOSource2_ +## START-SOURCE2 +#include "getopt-test_getopt.h" + +#include + +#include +#include +#include +#include +#include "getopt-bn.h" + +#ifndef DIRCH +# if defined(_WIN32) && !defined(__CYGWIN__) +# define DIRCH '\\' +# else +# define DIRCH '/' +# endif +#endif + +/* + * getopt_long option descriptor + */ +static struct option a_long_opts[] = { + { "option", 1, NULL, VALUE_OPT_OPTION }, + { "second", 1, NULL, VALUE_OPT_SECOND }, + { "no_val", 0, NULL, VALUE_OPT_NO_VAL }, + { "max_val", 0, NULL, VALUE_OPT_MAX_VAL }, + { "min2_val", 0, NULL, VALUE_OPT_MIN2_VAL }, + { "min_val", 0, NULL, VALUE_OPT_MIN_VAL }, + { "help", 0, NULL, VALUE_OPT_HELP }, + { "version", 0, NULL, VALUE_OPT_VERSION }, + { NULL, 0, NULL, 0 } +}; + +/* + * Option flag character list + */ +static char z_opts[] = "o:s:h"; + +/* + * AutoOpts library replacement routines: + */ +noreturn void +optionUsage (tOptions * pOptions, int status) +{ + if (status != 0) + fprintf (stderr, _("Try `%s --help' for more information.\n"), + test_getoptOptions.pzProgName); + else + { + fputs (_("test_getopt - Test AutoOpts for getopt\n\ +Usage: test_getopt { - [] | --[{=| }] }...\n\n\ + -o, --option=str The option option descrip\n\ + -s, --second=str The second option descrip\n\ + --no-val option with no flag\n\ + --max-val option with max ct\n\ + --min2-val option with min ct\n\ + --min-val option with min ct\n\ + --version output version information and exit\n\ + -h, --help display extended usage information and exit\n\n\ +Options are specified by doubled hyphens and their name or by a single\n\ +hyphen and the flag character.\n\ +\n"), stdout); + } + + exit (status); +} + +noreturn void +optionPrintVersion (tOptions * pOptions, tOptDesc * pOptDesc) +{ + char const * pz_by = + _("test_getopt 1.2.3\n\ +Written by Bruce Korb.\n\n\ +Copyright (C) 2003-2018 Odyssey Computing Concepts, Inc.\n\ +This is free software; see the source for copying conditions. There is NO\n\ +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"); + + fputs (pz_by, stdout); + exit (EXIT_SUCCESS); +} + +/* + * If an option appears more often than is allowed, ... + */ +static void +usage_too_many (tOptDesc* pOptDesc) +{ + char const * pz = + _("test_getopt error: the '%s' option appears more than %d times\n"); + fprintf (stderr, pz, pOptDesc->pz_Name, pOptDesc->optMaxCt); + USAGE(EXIT_FAILURE); +} + +/* + * There is at least one option that must appear. + */ +static void +usage_too_few (tOptDesc* pOptDesc) +{ + char const * pz = + _("test_getopt error: the '%s' option must appear %d times\n"); + fprintf (stderr, pz, pOptDesc->pz_Name, pOptDesc->optMinCt); + USAGE(EXIT_FAILURE); +} + +/* + * There is at least one pair of options that may not appear together + * on the command line. + */ +static void +usage_cannot (char const* pz_what, char const* pz_cant) +{ + char const * pz = + _("test_getopt error: the `%s' option conflicts with the `%s' option.\n"); + fprintf (stderr, pz, pz_what, pz_cant); + USAGE(EXIT_FAILURE); +} + +/* + * There is at least one pair of options that are required to appear + * together on the command line. + */ +static void +usage_must (char const* pz_what, char const* pz_must) +{ + char const * pz = + _("test_getopt error: the `%s' option requires the `%s' option.\n"); + fprintf (stderr, pz, pz_what, pz_must); + USAGE(EXIT_FAILURE); +} + +/* + * Process the options for the "test_getopt" program. + * This function was generated to use the getopt_long(3GNU) function. + * There are 8 options for this program, + * including "help (usage)" and "version". + */ +int +process_test_getopt_opts (int argc, char** argv) +{ + { + char * pz_prog = strrchr (argv[0], DIRCH); + /* + * This violates the const-ness of the pzProgName field. + * The const-ness is to prevent accidents. This is not accidental. + */ + char ** pp = VOIDP(&(test_getoptOptions.pzProgName)); + + if (pz_prog != NULL) + pz_prog++; + else + pz_prog = argv[0]; + *pp = pz_prog; + } + + for (;;) { + switch (getopt_long (argc, argv, z_opts, a_long_opts, NULL)) { + case -1: goto leave_processing; + case 0: break; + + case VALUE_OPT_OPTION: + if (HAVE_OPT(OPTION)) + usage_too_many (&DESC(OPTION)); + SET_OPT_OPTION(optarg); + break; + + case VALUE_OPT_SECOND: + if (HAVE_OPT(SECOND)) + usage_too_many (&DESC(SECOND)); + SET_OPT_SECOND(optarg); + break; + + case VALUE_OPT_NO_VAL: + if (HAVE_OPT(NO_VAL)) + usage_too_many (&DESC(NO_VAL)); + SET_OPT_NO_VAL; + break; + + case VALUE_OPT_MAX_VAL: + if (DESC(MAX_VAL).optOccCt++ >= DESC(MAX_VAL).optMaxCt) + usage_too_many (&DESC(MAX_VAL)); + SET_OPT_MAX_VAL; + break; + + case VALUE_OPT_MIN2_VAL: + if (DESC(MIN2_VAL).optOccCt++ >= DESC(MIN2_VAL).optMaxCt) + usage_too_many (&DESC(MIN2_VAL)); + SET_OPT_MIN2_VAL; + break; + + case VALUE_OPT_MIN_VAL: + if (DESC(MIN_VAL).optOccCt++ >= DESC(MIN_VAL).optMaxCt) + usage_too_many (&DESC(MIN_VAL)); + SET_OPT_MIN_VAL; + break; + + case VALUE_OPT_HELP: + USAGE(EXIT_SUCCESS); + /* NOTREACHED */ + + case VALUE_OPT_VERSION: + optionPrintVersion (&test_getoptOptions, &DESC(VERSION)); + /* NOTREACHED */ + + default: + USAGE(EXIT_FAILURE); + } + } leave_processing:; + + if (HAVE_OPT(NO_VAL)) { + if (! HAVE_OPT(MAX_VAL)) + usage_must (DESC(NO_VAL).pz_Name, DESC(MAX_VAL).pz_Name); + } + + if (HAVE_OPT(MIN2_VAL)) { + if (HAVE_OPT(MAX_VAL)) + usage_cannot (DESC(MIN2_VAL).pz_Name, DESC(MAX_VAL).pz_Name); + if (DESC(MIN2_VAL).optOccCt < DESC(MIN2_VAL).optMinCt) + usage_too_few (&DESC(MIN2_VAL)); + } + else + usage_too_few (&DESC(MIN2_VAL)); + + if (DESC(MIN_VAL).optOccCt < DESC(MIN_VAL).optMinCt) + usage_too_few (&DESC(MIN_VAL)); + + return 0; +} ## END-SOURCE2 +_EOSource2_ + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# end of getopt.test diff --git a/autoopts/test/handler.test b/autoopts/test/handler.test new file mode 100755 index 0000000..01cfccc --- /dev/null +++ b/autoopts/test/handler.test @@ -0,0 +1,261 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# ---------------------------------------------------------------------- +# handler.test --- test option handling +# make sure that when it is not specified +# then option processing consumes all args. +# +# Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +echo "creating ${testname}.def in `pwd`" +cat > ${testname}.def <<_EOF_ +AutoGen Definitions options; +prog-name = ${testname}; +prog-title = "Testing ${testname}"; + +flag = { + name = first; + descrip = "first description"; + extract_code; +}; + +flag = { + name = second; + descrip = "second description"; + arg-type = keyword; + keyword = alpha, beta, gamma, omega; +}; + +flag = { + name = third; + descrip = "third description"; + flag_code = " SomeCodeOrOther();"; +}; + +flag = { + name = fourth; + descrip = "fourth description"; + arg-type = keyword; + keyword = alpha, beta, gamma, omega; + arg-default = gamma; + arg-optional; +}; + +flag = { + name = fifth; + descrip = "fifth description"; + flag_proc = first; +}; + +flag = { + name = sixth; + descrip = "sixth description"; + arg-type = set-member; + keyword = alpha, beta, gamma, omega; + arg-default = gamma, beta; +}; +_EOF_ + +echo ${AG_L} ${testname}.def +${AG_L} ${testname}.def || \ + failure AutoGen could not process + +${SED} '/START =/a\ +SampleCode();\ +XXX-REMOVE-XXX' ${testname}.c > ${testname}.tmp +chmod 644 ${testname}.c +${SED} -e '/^XXX-REMOVE-XXX$/d;s/XXX-REMOVE-XXX//' \ + ${testname}.tmp > ${testname}.c + +${AG_L} ${testname}.def || \ + failure AutoGen could not process + +# We are testing to ensure the procedures are created correctly. +# The template line numbers and time stamps and all that cruft +# vary too much, so sed them away. +# +${SED} -e '1,/Create the static procedure(s) declared above/d' \ + -e '/extracted from.*near line/d' \ + -e '/^#line/d' \ + -e 's@handler_opt_strs+[0-9]*@handler_opt_strs+NNN@g' \ + -e 's@+NNN, *@+NNN, @g' \ + -e '/^#ifndef *PKGDATADIR/,$d' \ + ${testname}.c > ${testname}.test + +# # # # # # # # # # SAMPLE OUTPUT FILE # # # # # # # # # + +echo creating ${testname}.sample +cat > ${testname}.sample <<\_EOF_ + */ +/** + * The callout function that invokes the optionUsage function. + * + * @param[in] opts the AutoOpts option description structure + * @param[in] od the descriptor for the "help" (usage) option. + * @noreturn + */ +static void +doUsageOpt(tOptions * opts, tOptDesc * od) +{ + int ex_code; + ex_code = HANDLER_EXIT_SUCCESS; + optionUsage(&handlerOptions, ex_code); + /* NOTREACHED */ + exit(HANDLER_EXIT_FAILURE); + (void)opts; + (void)od; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Code to handle the first option. + * + * @param[in] pOptions the handler options data structure + * @param[in,out] pOptDesc the option descriptor for this option. + */ +static void +doOptFirst(tOptions* pOptions, tOptDesc* pOptDesc) +{ +/* START =-= First Opt Code =-= DO NOT CHANGE THIS COMMENT */ +SampleCode(); +/* END =-= First Opt Code =-= DO NOT CHANGE THIS COMMENT */ + (void)pOptDesc; + (void)pOptions; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Code to handle the second option. + * + * @param[in] pOptions the handler options data structure + * @param[in,out] pOptDesc the option descriptor for this option. + */ +static void +doOptSecond(tOptions* pOptions, tOptDesc* pOptDesc) +{ + + static char const zDef[2] = { 0x7F, 0 }; + static char const * const names[5] = { zDef, + handler_opt_strs+NNN, handler_opt_strs+NNN, handler_opt_strs+NNN, + handler_opt_strs+NNN }; + + if (pOptions <= OPTPROC_EMIT_LIMIT) { + (void) optionEnumerationVal(pOptions, pOptDesc, names, 5); + return; /* protect AutoOpts client code from internal callbacks */ + } + + pOptDesc->optArg.argEnum = + optionEnumerationVal(pOptions, pOptDesc, names, 5); +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Code to handle the third option. + * + * @param[in] pOptions the handler options data structure + * @param[in,out] pOptDesc the option descriptor for this option. + */ +static void +doOptThird(tOptions* pOptions, tOptDesc* pOptDesc) +{ + /* + * Be sure the flag-code[0] handles special values for the options pointer + * viz. (poptions <= OPTPROC_EMIT_LIMIT) *and also* the special flag bit + * ((poptdesc->fOptState & OPTST_RESET) != 0) telling the option to + * reset its state. + */ + /* extracted from handler.def, line 21 */ + SomeCodeOrOther(); + (void)pOptDesc; + (void)pOptions; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Code to handle the fourth option. + * + * @param[in] pOptions the handler options data structure + * @param[in,out] pOptDesc the option descriptor for this option. + */ +static void +doOptFourth(tOptions* pOptions, tOptDesc* pOptDesc) +{ + + static char const * const names[4] = { + handler_opt_strs+NNN, handler_opt_strs+NNN, handler_opt_strs+NNN, + handler_opt_strs+NNN }; + + if (pOptions <= OPTPROC_EMIT_LIMIT) { + (void) optionEnumerationVal(pOptions, pOptDesc, names, 4); + return; /* protect AutoOpts client code from internal callbacks */ + } + + if (pOptDesc->optArg.argString == NULL) + pOptDesc->optArg.argEnum = FOURTH_GAMMA; + else + pOptDesc->optArg.argEnum = + optionEnumerationVal(pOptions, pOptDesc, names, 4); +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Code to handle the sixth option. + * + * @param[in] pOptions the handler options data structure + * @param[in,out] pOptDesc the option descriptor for this option. + */ +static void +doOptSixth(tOptions* pOptions, tOptDesc* pOptDesc) +{ + + static char const * const names[4] = { + "alpha", "beta", "gamma", "omega" + }; + /* + * This function handles special invalid values for "pOptions" + */ + optionSetMembers(pOptions, pOptDesc, names, 4); +} + +/** + * The directory containing the data associated with handler. + */ +_EOF_ +pair="${testname}.test ${testname}.sample" +cmp -s ${pair} || failure "`diff -c ${pair}`" + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## End: + +# end of handler.test diff --git a/autoopts/test/immediate.test b/autoopts/test/immediate.test new file mode 100755 index 0000000..8967fd5 --- /dev/null +++ b/autoopts/test/immediate.test @@ -0,0 +1,122 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# ---------------------------------------------------------------------- +# immediate.test --- test immediate option handling +# +# Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2017 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd +#--copyright-mark "(copyright \\(c\\)[ \t]+|" \ +# "date[ \t]*=[ \t]*\")([12][90][0-9][0-9])" +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +echo "creating ${testname}.def in `pwd`" + +cat > ${testname}.def << _EOF_ +AutoGen definitions options; + +prog-name = "test_${testname}"; +prog-title = "Test AutoOpts for ${testname}"; +include = "#include \nint invocation_ct = 0;"; +config-header = 'config.h'; +version = '1.0'; +omit-nls-code; +copyright = { + date = "1992-2017"; + owner = "Bruce Korb"; + eaddr = "autogen-users@lists.sourceforge.net"; + type = gpl; +}; + +flag = { + name = "second"; + descrip = "The second option descrip"; + immediate = also; + immed-disable = also; + disable = not; + arg-type = string; + flag-code = " invocation_ct++;"; +}; + +main = { + main-type = main; + main-text = ' printf( "invocation_ct = %d\\n", invocation_ct );'; +}; + +_EOF_ + +INC=`echo ${INC} | ${SED} 's/-lguile//;s/-lqthreads//'` +CFLAGS="-g`echo ' '${CFLAGS}' ' | \ + ${SED} 's, -O2 , -O0 ,;s/ -g[^ ]* / /'`" + +echo ${AG_L} ${testname}.def +${AG_L} ${testname}.def || \ + failure AutoGen could not process + +sedcmd="/All arguments are named options./q" +compile "help" + +# # # # # # # # # # HELP OUTPUT FILE # # # # # # # # # + +echo creating ${testname}.hlp +clean_help > ${testname}.hlp << '_EOF_' +test_immediate - Test AutoOpts for immediate - Ver. 1.0 +Usage: immediate [ [{=| }] ]... + Arg Option-Name Description + Str second The second option descrip + - disabled as '--not-second' + opt version output version information and exit + no help display extended usage information and exit + no more-help extended usage information passed thru pager + +All arguments are named options. +_EOF_ + +cmp -s ${testname}.help ${testname}.hlp || { set +x ; \ + failure "`diff -c ${testname}.hlp ${testname}.help`" ; } + +f=`./${testname} second=hand` +test "$f" = "invocation_ct = 2" || \ + failure "enabled option not processed twice" + +f=`./${testname} not-second` +test "$f" = "invocation_ct = 2" || \ + failure "DIS-abled option not processed twice" + +f=`./${testname} help version=c | ${FGREP} 'Usage:'` +test -z "${f}" && failure "no Usage: in help text" + +f=`./${testname} version=c help | ${FGREP} -i 'Copyright (C)'` +test -z "${f}" && failure "no 'Copyright (C)' in version text" + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## End: + +# end of immediate.test diff --git a/autoopts/test/keyword.test b/autoopts/test/keyword.test new file mode 100755 index 0000000..1a3f459 --- /dev/null +++ b/autoopts/test/keyword.test @@ -0,0 +1,506 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# ---------------------------------------------------------------------- +# keyword.test --- keyword option processing +# +# Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +echo "creating ${testname}.def in `pwd`" +testname="${testname}" test_main="" \ +argument="${argument}" long_opts="yes" \ +${SHELLX} ${stdopts} option:'opt init' || failure "Could not run stdopts.def" +cat >> ${testname}.def <<- _EndOfDef_ + help_value = X; + homerc = '.'; + rcfile = ${testname}.cfg; + + flag = { + name = trace; + arg-type = keyword; + arg-default = nothing; + arg-name = level; + descrip = "tracing level of detail"; + keyword = nothing, templates, block-macros, expressions, + explanations; + }; + + flag = { + name = sets; + arg-type = set-members; + arg-default = second, fourth; + arg-name = member-list; + descrip = "set membership testing"; + keyword = first, second, third, fourth, fifth, + sixth, seventh, eighth, ninth, tenth, + eleventh, twelfth, thirteenth, fourteenth, fifteenth, + sixteenth, seventeenth, eighteenth; + }; + main = { main-type = shell-process; }; + _EndOfDef_ + +echo ${AG_L} ${testname}.def +${AG_L} ${testname}.def || \ + failure AutoGen could not process + +compile "-X" + +# # # # # # # # # # HELP OUTPUT FILE # # # # # # # # # + +echo creating ${testname}.bas-help +clean_help > ${testname}.bas-help <<\_EOF_ +test_keyword - Test AutoOpts for keyword +Usage: keyword [ - [] | --[{=| }] ]... + Flg Arg Option-Name Description + -o Str option The option option descrip + KWd trace tracing level of detail + Mbr sets set membership testing + - is a set membership option + -X no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + -> opt save-opts save the option state to a config file + -< Str load-opts load options from a config file + - disabled as '--no-load-opts' + - may appear multiple times + +Options are specified by doubled hyphens and their name or by a single +hyphen and the flag character. + +The following option preset mechanisms are supported: + - reading file ./keyword.cfg + +The valid "trace" option keywords are: + nothing templates block-macros expressions explanations + or an integer from 0 through 4 +The valid "sets" option keywords are: + first second third fourth fifth sixth + seventh eighth ninth tenth eleventh twelfth + thirteenth fourteenth fifteenth sixteenth seventeenth eighteenth + or an integer mask with any of the lower 18 bits set +or you may use a numeric representation. Preceding these with a '!' +will clear the bits, specifying 'none' will clear all bits, and 'all' +will set them all. Multiple entries may be passed as an option +argument list. +_EOF_ + +dir=`pwd -P` || dir=`pwd` +${SED} "s#${dir}/##" ${testname}.help > ${testname}.res-help +pair="${testname}.bas-help ${testname}.res-help" +cmp -s ${pair} || \ + failure "help output:$nl`diff -u ${pair}`" + +./${testname} --trace=exp > /dev/null 2>&1 && \ + failure "${testname} accepted ambiguous keyword" + +./${testname} --trace=999 > /dev/null 2>&1 && \ + failure "${testname} accepted too much tracing" + +./${testname} --trace=~0 > /dev/null 2>&1 || \ + failure "${testname} would not accept max tracing" + +./${testname} --trace=expr --set=thirteen,ninth,third > ${testname}.t1-s || \ + failure "${testname} did not handle its options" + +cat > ${testname}.t1-b <<- \_EndTst_ + OPTION_CT=2 + export OPTION_CT + TEST_KEYWORD_TRACE='expressions' + export TEST_KEYWORD_TRACE + TEST_KEYWORD_SETS=4366 # 0x110E + export TEST_KEYWORD_SETS + readonly SETS_FIRST=1 # 0x1 + readonly SETS_SECOND=2 # 0x2 + readonly SETS_THIRD=4 # 0x4 + readonly SETS_FOURTH=8 # 0x8 + readonly SETS_FIFTH=16 # 0x10 + readonly SETS_SIXTH=32 # 0x20 + readonly SETS_SEVENTH=64 # 0x40 + readonly SETS_EIGHTH=128 # 0x80 + readonly SETS_NINTH=256 # 0x100 + readonly SETS_TENTH=512 # 0x200 + readonly SETS_ELEVENTH=1024 # 0x400 + readonly SETS_TWELFTH=2048 # 0x800 + readonly SETS_THIRTEENTH=4096 # 0x1000 + readonly SETS_FOURTEENTH=8192 # 0x2000 + readonly SETS_FIFTEENTH=16384 # 0x4000 + readonly SETS_SIXTEENTH=32768 # 0x8000 + readonly SETS_SEVENTEENTH=65536 # 0x10000 + readonly SETS_EIGHTEENTH=131072 # 0x20000 + _EndTst_ + +pair="${testname}.t1-b ${testname}.t1-s" +cmp -s ${pair} || \ + failure "miscompare${nl}`diff -u ${pair}`" + +rm -f ${testname}.cfg +./${testname} --trace=expr --set=+thirteen,ninth,third --save=${testname}.cfg || \ + failure "${testname} could not save its options" + +${EGREP} -v '^#' ${testname}.cfg > ${testname}res.cfg || \ + failure "${testname} could not create ${testname}.cfg" + +cat > ${testname}base.cfg <<- \_EndIni_ + trace = expressions + sets = =second + third + fourth + ninth + thirteenth + _EndIni_ + +pair="${testname}base.cfg ${testname}res.cfg" +cmp -s $pair || \ + failure "miscompare${nl}`diff -u $pair`" + +${AG_L} -T agman-cmd.tpl ${testname}.def +test -f test_${testname}.1 || \ + failure "'test_${testname}.1' was not produced" +mv test_${testname}.1 ${testname}.1 + +${SED} '1,/^## BEGIN-MAN/d + /^## *END-MAN/,$d' ${test_src} > ${testname}-base.1 + +${SED} '1,/^\.SH NAME/d' ${testname}.1 > ${testname}-res.1 +pair="${testname}-base.1 ${testname}-res.1" +cmp -s $pair || \ + failure "mismatched:${nl}`diff -u $pair`" + +# # # # # # # # # # CHECK OUT MDOC # # # # # # # # # # # + +${AG_L} -T agmdoc-cmd.tpl ${testname}.def +test -f test_${testname}.1 || \ + failure "'test_${testname}.1' was not produced" +mv test_${testname}.1 ${testname}.mdoc + +${SED} '1,/^## *BEGIN-MDOC/d + /^## *END-MDOC/,$d' ${test_src} > ${testname}-base.mdoc + +${SED} '/DO NOT EDIT/,/and the template file/d + /^\.Os /d + /^\.Dd /d + /^$/d' \ + ${testname}.mdoc > ${testname}-res.mdoc +cmp -s ${testname}-base.mdoc ${testname}-res.mdoc || \ + failure "`diff -u ${testname}-base.mdoc ${testname}-res.mdoc`" + +# # # # # # # # # # CHECK OUT VAL2STR # # # # # # # # # # # + +exec 3> ${testname}_2.def +${SED} '/^prog-name/s/";/_2";/;/^main *=/,$d' ${testname}.def >&3 +cat >&3 <<- \_EOF_ + include = '#include '; + main = { + main-type = main; + main-text = + ' printf( "%s\n", OPT_TRACE_VAL2STR( OPT_VALUE_TRACE ));'; + }; + _EOF_ +exec 3>&- + +echo ${AG_L} ${testname}_2.def +${AG_L} ${testname}_2.def || \ + failure AutoGen could not process + +Csrc=${testname}_2 +Dnam=${Csrc} +compile "-X" || failure "cannot compile ${testname}_2" + +val=`./${testname}_2 --trace=expr 2>&1` || \ + failure "cannot run ${testname}_2" + +case "${val}" in +expressions) : ;; +* ) failure "${testname}_2 returned '${val}', not 'expressions': + ${testname}_2 --trace=expr" ;; +esac + +cleanup + +exit 0 + +# # # # # # # # # # # MAN PAGE + +cat <<_End_Of_ManPage_ +## BEGIN-MAN +\f\*[B-Font]test_keyword\fP +\- Test AutoOpts for keyword +.SH SYNOPSIS +\f\*[B-Font]test_keyword\fP +.\" Mixture of short (flag) options and long options +[\f\*[B-Font]\-flags\f[]] +[\f\*[B-Font]\-flag\f[] [\f\*[I-Font]value\f[]]] +[\f\*[B-Font]\-\-option-name\f[][[=| ]\f\*[I-Font]value\f[]]] +.sp \n(Ppu +.ne 2 + +All arguments must be options. +.sp \n(Ppu +.ne 2 + +This program will emit text that is expected to be evaluated by +a Bourne-compatible shell, thus digesting the options for the script. +.sp \n(Ppu +.ne 2 + +.SH "DESCRIPTION" +There is no description for this command. +.SH "OPTIONS" +.TP +.NOP \f\*[B-Font]\-o\f[] \f\*[I-Font]string\f[], \f\*[B-Font]\-\-option\f[]=\f\*[I-Font]string\f[] +The option option descrip. +The default +\f\*[I-Font]string\f[] +for this option is: +.ti +4 + opt init +.sp +This option has not been fully documented. +.TP +.NOP \f\*[B-Font]\-\-trace\f[]=\f\*[I-Font]level\f[] +tracing level of detail. +This option takes a keyword as its argument. The argument sets an enumeration value that can +be tested by comparing them against the option value macro. +The available keywords are: +.in +4 +.nf +.na +nothing templates block-macros +expressions explanations +.fi +or their numeric equivalent. +.in -4 +.sp +The default +\f\*[I-Font]level\f[] +for this option is: +.ti +4 + nothing +.sp +This option has not been fully documented. +.TP +.NOP \f\*[B-Font]\-\-sets\f[]=\f\*[I-Font]member\-list\f[] +set membership testing. +This option takes a keyword as its argument list. Each entry turns on or off +membership bits. The bits are set by name or numeric value and cleared +by preceding the name or number with an exclamation character ('!'). +They can all be cleared with the magic name \fInone\fR and they can all be set +with +.IR all . +A single option will process a list of these values. +The available keywords are: +.in +4 +.nf +.na +first second third fourth +fifth sixth seventh eighth +ninth tenth eleventh twelfth +thirteenth fourteenth fifteenth sixteenth +seventeenth eighteenth +.fi +or their numeric equivalent. +.in -4 +.sp +The default +\f\*[I-Font]member\-list\f[] +for this option is: +.ti +4 + second + fourth +.sp +This option has not been fully documented. +.TP +.NOP \f\*[B-Font]\-X\f[], \f\*[B-Font]\-\-help\f[] +Display usage information and exit. +.TP +.NOP \f\*[B-Font]\-\&!\f[], \f\*[B-Font]\-\-more-help\f[] +Pass the extended usage information through a pager. +.TP +.NOP \f\*[B-Font]\->\f[] [\f\*[I-Font]cfgfile\f[]], \f\*[B-Font]\-\-save-opts\f[] [=\f\*[I-Font]cfgfile\f[]] +Save the option state to \fIcfgfile\fP. The default is the \fIlast\fP +configuration file listed in the \fBOPTION PRESETS\fP section, below. +The command will exit after updating the config file. +.TP +.NOP \f\*[B-Font]\-<\f[] \f\*[I-Font]cfgfile\f[], \f\*[B-Font]\-\-load-opts\f[]=\f\*[I-Font]cfgfile\f[], \f\*[B-Font]\-\-no-load-opts\f[] +Load options from \fIcfgfile\fP. +The \fIno-load-opts\fP form will disable the loading +of earlier config/rc/ini files. \fI\-\-no-load-opts\fP is handled early, +out of order. +.PP +.SH "OPTION PRESETS" +Any option that is not marked as \fInot presettable\fP may be preset +by loading values from configuration ("RC" or ".INI") file(s). +The file "\fI./keyword.cfg\fP" will be used, if present. +.SH "FILES" +See \fBOPTION PRESETS\fP for configuration files. +.SH "EXIT STATUS" +One of the following exit values will be returned: +.TP +.NOP 0 " (EXIT_SUCCESS)" +Successful program execution. +.TP +.NOP 1 " (EXIT_FAILURE)" +The operation failed or the command syntax was not valid. +.TP +.NOP 66 " (EX_NOINPUT)" +A specified configuration file could not be loaded. +.TP +.NOP 70 " (EX_SOFTWARE)" +libopts had an internal operational error. Please report +it to autogen-users@lists.sourceforge.net. Thank you. +.PP +.SH "NOTES" +This manual page was \fIAutoGen\fP-erated from the \fBtest_keyword\fP +option definitions. +## END-MAN +_End_Of_ManPage_ + +# # # # # # # # # # # MDOC PAGE + +cat <<_End_Of_MdocPage_ +## BEGIN-MDOC +.Dt TEST_KEYWORD 1 User Commands +.Os +.Sh NAME +.Nm test_keyword +.Nd Test AutoOpts for keyword +.Sh SYNOPSIS +.Nm +.\" Mixture of short (flag) options and long options +.Op Fl flags +.Op Fl flag Op Ar value +.Op Fl \-option\-name Ns Oo Oo Ns "=| " Oc Ns Ar value Oc +.Pp +All arguments must be options. +.Pp +This program will emit text that is expected to be evaluated by +a Bourne\-compatible shell, thus digesting the options for the script. +.Pp +.Sh "DESCRIPTION" +There is no description for this command. +.Sh "OPTIONS" +.Bl -tag +.It Fl o Ar string , Fl \-option Ns = Ns Ar string +The option option descrip. +The default +.Ar string +for this option is: +.ti +4 + opt init +.sp +This option has not been fully documented. +.It Fl \-trace Ns = Ns Ar level +tracing level of detail. +This option takes a keyword as its argument. The argument sets an enumeration value that can +be tested by comparing them against the option value macro. +The available keywords are: +.in +4 +.nf +.na +nothing templates block\-macros +expressions explanations +.fi +or their numeric equivalent. +.in -4 +.sp +The default +.Ar level +for this option is: +.ti +4 + nothing +.sp +This option has not been fully documented. +.It Fl \-sets Ns = Ns Ar member\-list +set membership testing. +This option takes a keyword as its argument list. Each entry turns on or off +membership bits. The bits are set by name or numeric value and cleared +by preceding the name or number with an exclamation character ('!'). +They can all be cleared with the magic name \fInone\fR and they can all be set +with +.IR all . +A single option will process a list of these values. +The available keywords are: +.in +4 +.nf +.na +first second third fourth +fifth sixth seventh eighth +ninth tenth eleventh twelfth +thirteenth fourteenth fifteenth sixteenth +seventeenth eighteenth +.fi +or their numeric equivalent. +.in -4 +.sp +The default +.Ar member\-list +for this option is: +.ti +4 + second + fourth +.sp +This option has not been fully documented. +.It Fl X , Fl \-help +Display usage information and exit. +.It Fl \&! , Fl \-more\-help +Pass the extended usage information through a pager. +.It Fl > Oo Ar cfgfile Oc , Fl \-save\-opts Oo Ns = Ns Ar cfgfile Oc +Save the option state to \fIcfgfile\fP. The default is the \fIlast\fP +configuration file listed in the \fBOPTION PRESETS\fP section, below. +The command will exit after updating the config file. +.It Fl < Ar cfgfile , Fl \-load\-opts Ns = Ns Ar cfgfile , Fl \-no\-load\-opts +Load options from \fIcfgfile\fP. +The \fIno\-load\-opts\fP form will disable the loading +of earlier config/rc/ini files. \fI\-\-no\-load\-opts\fP is handled early, +out of order. +.El +.Sh "OPTION PRESETS" +Any option that is not marked as \fInot presettable\fP may be preset +by loading values from configuration ("RC" or ".INI") file(s). +The file "\fI./keyword.cfg\fP" will be used, if present. +.Sh "FILES" +See \fBOPTION PRESETS\fP for configuration files. +.Sh "EXIT STATUS" +One of the following exit values will be returned: +.Bl -tag +.It 0 " (EXIT_SUCCESS)" +Successful program execution. +.It 1 " (EXIT_FAILURE)" +The operation failed or the command syntax was not valid. +.It 66 " (EX_NOINPUT)" +A specified configuration file could not be loaded. +.It 70 " (EX_SOFTWARE)" +libopts had an internal operational error. Please report +it to autogen\-users@lists.sourceforge.net. Thank you. +.El +.Sh "NOTES" +This manual page was \fIAutoGen\fP\-erated from the \fBtest_keyword\fP +option definitions. +## END-MDOC +_End_Of_MdocPage_ + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## End: + +# end of keyword.test diff --git a/autoopts/test/library.test b/autoopts/test/library.test new file mode 100755 index 0000000..0514721 --- /dev/null +++ b/autoopts/test/library.test @@ -0,0 +1,169 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# ---------------------------------------------------------------------- +# library.test --- test library options +# +# Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +DEND=\<\<'- _DESC_END_' + +cat > ${testname}-libopts.def <<- _EODefs_ + flag = { name = zzyzx-opts; + documentation; + lib-name = zzyzx; + descrip = ${DEND} + This option introduces the options for the + zzyzx library + _DESC_END_; + }; + flag = { + name = library; + value = c; + ifdef = LIBOPTS; + descrip = "library test"; + doc = mumble; + }; + _EODefs_ + +cat > ${testname}-lib.def <<- _EODefs_ + + AutoGen definitions options; + + prog-name = ${testname}; + prog-title = lib-${testname}; + config-header = 'config.h'; + + library; + #include ${testname}-libopts.def + _EODefs_ + +cat > ${testname}-prog.def <<- _EOF_ + + AutoGen definitions options; + + prog-name = test-lib-prog; + prog-title = 'Test ${testname} Program'; + config-header = 'config.h'; + + flag = { + name = program; + value = p; + descrip = "${testname} program test"; + doc = stumble; + }; + + #include ${testname}-libopts.def + _EOF_ + +echo ${AG_L} ${testname}-lib.def +${AG_L} ${testname}-lib.def || \ + failure AutoGen could not process ${testname}-lib.def + +echo ${AG_L} ${testname}-prog.def +${AG_L} ${testname}-prog.def || \ + failure AutoGen could not process ${testname}-prog.def + +for f in lib prog +do + ${SED} -e '1,/include /d' \ + -e '/endif .* AUTOOPTS_.*_H_GUARD/,$d' \ + -e 's/near line [0-9]*/near line XXX/' \ + ${testname}-${f}.h > ${testname}-${f}.h-res || \ + failure could not sed ${testname}-${f}.h +done + +# # # # # # # # # # TEST PROGRAM # # # # # # # # # # + +cat > ${testname}-lib.c <<- _EOCode_ + #include + #define LIBOPTS + #include "${testname}-lib.h" + void check_library_opt( void ); + void check_library_opt( void ) { + if (HAVE_OPT(LIBRARY)) return; + exit( EXIT_FAILURE ); } + _EOCode_ +test $? -eq 0 || failure cannot create ${testname}-lib.c + +${CC} ${CFLAGS} ${INC} -o ${testname}-lib.o -c ${testname}-lib.c +test $? -eq 0 || failure cannot compile ${testname}-lib.c + +cat > ${testname}-main.c <<- _EOCode_ + #include + #include + #define LIBOPTS + #include "${testname}-prog.c" + extern void check_library_opt( void ); + int main( int argc, char** argv ) { + (void)optionProcess( &test_lib_progOptions, argc, argv ); + check_library_opt(); + return EXIT_SUCCESS; } + _EOCode_ + +${CC} ${CFLAGS} ${INC} -o ${testname} ${testname}-main.c ${testname}-lib.o ${LIB} +test $? -eq 0 || failure cannot compile ${testname}-main.c + +./${testname} -c || failure library option not detected + +# # # # # # # # # # HELP OUTPUT # # # # # # # # # # + +./${testname} -? | clean_help > ${testname}.help-sample + +clean_help > ${testname}.help-base <<- _EOHelp_ +test-lib-prog - Test library Program +Usage: library [ - ]... + Flg Arg Option-Name Description + -p no program library program test + +This option introduces the options for the zzyzx library: + + Flg Arg Option-Name Description + -c no library library test + +Version, usage and configuration options: + + Flg Arg Option-Name Description + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + + _EOHelp_ + +cmp ${testname}.help-* || \ + failure "help output mismatch: +`diff ${testname}.help-*`" + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## End: + +# end of library.test diff --git a/autoopts/test/main.test b/autoopts/test/main.test new file mode 100755 index 0000000..63659ff --- /dev/null +++ b/autoopts/test/main.test @@ -0,0 +1,123 @@ +#! /bin/sh +# -*- Mode: Shell-Script -*- +# ---------------------------------------------------------------------- +# main.test --- test main program attribute +# make sure that when it is not specified +# then option processing consumes all args. +# +# Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +echo "creating ${testname}.def in `pwd`" +testname="${testname}" \ +argument="${argument}" long_opts="${long_opts}" \ +${SHELLX} ${stdopts} option:'opt init' second=020 || \ + failure "Could not run stdopts.def" + +exec 4> ${testname}.def2 +${SED} '/test_main=/d' ${testname}.def >&4 +unset test_main +cat >&4 <<- _EOF_ + explain = 'This is some explanatory text.'; + argument = '[ ... ]'; + main = { + handler-proc = fumble; + fumble-code = ' printf("%s\n", pz_entry);'; + main-type = for-each; + interleaved; + }; + _EOF_ +exec 4>&- +mv -f ${testname}.def2 ${testname}.def + +echo ${AG_L} ${testname}.def +${AG_L} ${testname}.def || \ + failure AutoGen could not process + +compile "-?" + +# # # # # # # # # # HELP OUTPUT FILE # # # # # # # # # + +basehlp=${testname}.hlp +echo creating ${basehlp} +clean_help > ${basehlp} <<'_EOF_' +test_main - Test AutoOpts for main +Usage: main [ - [] ]... [ ... ] + Flg Arg Option-Name Description + -o Str option The option option descrip + -s Num second The second option descrip + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + +This is some explanatory text. + +If no arguments are provided, input arguments are read from stdin, +one per line; blank and '#'-prefixed lines are comments. +Options may appear in the input interspersed with the 'normal' input. +'stdin' may not be a terminal (tty). +_EOF_ + +pair=`echo ${testname}.h*lp` +cmp -s $pair || \ + failure "DIFFER: $pair +`diff $pair`" + +# # # # # # # # # # TEST OPERATION # # # # # # # # # # +sedcmd='/illegal option /d' +echo '--help' | ./${testname} 2>&1 | clean_help > ${testname}.out + +pair="${testname}.hlp ${testname}.out" +cmp -s $pair || \ + failure "DIFFER: $pair +`diff ${testname}.hlp ${testname}.out`" + +./${testname} > ${testname}.out2 < ${testname}.base2 <<\_EOF_ +the +quick +brown fox +_EOF_ + +cmp -s ${testname}.base2 ${testname}.out2 || \ + failure "`diff ${testname}.base2 ${testname}.out2`" + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## End: + +# end of main.test diff --git a/autoopts/test/nested.test b/autoopts/test/nested.test new file mode 100755 index 0000000..a4d4755 --- /dev/null +++ b/autoopts/test/nested.test @@ -0,0 +1,265 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# ---------------------------------------------------------------------- +# nested.test --- test nested option values +# +# Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +exec 5> ${testname}.def +cat >&5 <<- _EOF_ + + AutoGen definitions options; + + config-header = 'config.h'; + prog-name = "test_${testname}"; + prog-title = "Test AutoOpts for ${testname}"; + homerc = ${testname}.d/${testname}.cfg; + + flag = { + name = struct; + value = s; + max = NOLIMIT; + descrip = 'structured argument val'; + arg-type = nested; + }; + main = { + main-type = main; + _EOF_ + +test -d ${testname}.d || mkdir -p ${testname}.d + +echo ' main-text = <''<- _EOCode_' >&5 +cat >&5 <<- _EOF_ + { + int ix = 0; + const tOptionValue* pOV = + optionFindValue(&DESC(STRUCT), NULL, NULL); + do { + printf("\nstruct opt #%d:\n", ++ix); + res |= print_entry( pOV ); + pOV = optionFindNextValue(&DESC(STRUCT), pOV, NULL, NULL); + } while (pOV != NULL); + } + _EOF_ + +echo "_EOCode_; };" >&5 + +echo 'include = <''<- _EOSubr_' >&5 +cat >&5 <<- _EOF_ + #include + + int print_nested( const tOptionValue* pGV ); + int print_entry( const tOptionValue* pGV ); + int print_entry( const tOptionValue* pGV ) { + if (pGV == NULL) { + fprintf( stderr, "ENTRY NOT FOUND\n" ); + return 1; + } + printf( "%-8s -- ", pGV->pzName ); + switch (pGV->valType) { + case OPARG_TYPE_NONE: + fputs( "no value\n", stdout ); break; + + case OPARG_TYPE_STRING: + printf( "string: %s\n", pGV->v.strVal ); break; + + case OPARG_TYPE_ENUMERATION: + printf( "enum: %d\n", pGV->v.enumVal ); break; + + case OPARG_TYPE_BOOLEAN: + printf( "bool: %s\n", + pGV->v.boolVal ? "TRUE" : "false" ); break; + + case OPARG_TYPE_MEMBERSHIP: + printf("members: 0x%08lX\n", (unsigned long)pGV->v.setVal); break; + + case OPARG_TYPE_NUMERIC: + printf( "integer: %ld\n", pGV->v.longVal ); break; + + case OPARG_TYPE_HIERARCHY: + printf( "nested: 0x%08lX\n", (unsigned long)pGV->v.nestVal ); + return print_nested( pGV ); + break; + + default: + printf( "bad type: %d\n", pGV->valType ); + return 1; + } + return 0; + } + + int print_nested( const tOptionValue* pGV ) { + int res = 0; + const tOptionValue* pOV = optionGetValue( pGV, NULL ); + while (pOV != NULL) { + res |= print_entry( pOV ); + pOV = optionNextValue( pGV, pOV ); + } + return res; + } + _EOF_ +echo "_EOSubr_;" >&5 + +exec 5>&- + +# # # # # # # # # # CREATE PROGRAM # # # # # # # # # + +echo ${AG_L} ${testname}.def +${AG_L} ${testname}.def || \ + failure AutoGen could not process + +compile "-?" + +# # # # # # # # # # HELP OUTPUT FILE # # # # # # # # # + +basehelp=${testname}-base.help +echo creating ${basehelp} +clean_help > ${basehelp} <<_EOF_ +test_${testname} - Test AutoOpts for ${testname} +Usage: ${testname} [ - [] ]... + Flg Arg Option-Name Description + -s Cpx struct structured argument val + - may appear multiple times + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + -> opt save-opts save the option state to a config file + -< Str load-opts load options from a config file + - disabled as '--no-load-opts' + - may appear multiple times + + +The following option preset mechanisms are supported: + - reading file ${testname}.cfg +_EOF_ + +${SED} "/ - reading file/s/ file .*/ file ${testname}.cfg/" \ + ${testname}.help > X$$ +mv -f X$$ ${testname}.help + +cmp -s ${basehelp} ${testname}.help || \ + failure "`diff ${basehelp} ${testname}.help`" + +# # # # # # # # # # SINGLE ARG TEST # # # # # # # # # + +cat > ${testname}-res1.base <<- _EOF_ + + struct opt #1: + struct -- nested: 0xXXXXXXXX + able -- no value + bar -- integer: 1234 + foo -- no value + stumble -- no value + _EOF_ + +./${testname} -s 'stumble, foo, 1234 able' | \ +${SED} '/ nested:/s/ 0x.*/ 0xXXXXXXXX/' > ${testname}-res1.out || \ + failure "FAILED: \ +./${testname} -s 'stumble, foo, 1234 baz'" + +cmp -s ${testname}-res1.* || \ + failure "`diff ${testname}-res1.*`" + +# # # # # # # # # # DOUBLE ARG TEST # # # # # # # # # + +arg1="stumble, foo${ht}lish, 1234, able" +arg2='foo, 4321 one, two=2, three' +(./${testname} -s "${arg1}" -s "${arg2}" \ + | ${SED} '/ nested:/s/ 0x.*/ 0xXXXXXXXX/' ) > ${testname}-res2.out || \ + failure "FAILED: ./${testname} ${arg1} ${arg2}" + +cat > ${testname}-res2.base <<- _EOF_ + + struct opt #1: + struct -- nested: 0xXXXXXXXX + able -- no value + bar -- integer: 1234 + foo -- string: foo lish + stumble -- no value + + struct opt #2: + struct -- nested: 0xXXXXXXXX + bar -- integer: 4321 + foo -- no value + gr -- nested: 0xXXXXXXXX + one -- no value + three -- no value + two -- string: 2 + _EOF_ + +cmp -s ${testname}-res2.* || \ + failure "`diff ${testname}-res2.*`" + +./${testname} -s "${arg1}" -s "${arg2}" '->' +${SED} -e '3s/.*/# ***DATE***/' ${testname}.d/${testname}.cfg > ${testname}.XX +mv -f ${testname}.XX ${testname}.d/${testname}.cfg +cat > ${testname}-res3.base <<- _EOF_ + # test_nested - Test AutoOpts for nested + # preset/initialization file + # ***DATE*** + # + + + 0x4D2 + foo lish + + + + 0x10E1 + + + + + 2 + + + _EOF_ +files=${testname}-res3.base\ ${testname}.d/${testname}.cfg +cmp -s ${files} || \ + failure "saved config${nl}`diff ${files}`" + +# Copy the config file and verify that the contents are the same. +# +./${testname} "->${testname}.d/${testname}.cfg2" +${SED} -e '3s/.*/# ***DATE***/' ${testname}.d/${testname}.cfg2 > ${testname}.XX +mv -f ${testname}.XX ${testname}.d/${testname}.cfg2 +files=${testname}.d/${testname}.cfg\ ${testname}.d/${testname}.cfg2 +cmp -s ${files} || \ + failure "re-saved config${nl}`diff ${files}`" + +# # # # # # # # # # TEST OPERATION # # # # # # # # # # + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## End: + +# end of nested.test diff --git a/autoopts/test/nls.test b/autoopts/test/nls.test new file mode 100755 index 0000000..681ad5e --- /dev/null +++ b/autoopts/test/nls.test @@ -0,0 +1,164 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# ---------------------------------------------------------------------- +# nls.test --- test NLS, sort-of +# +# Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd +# +# ---------------------------------------------------------------------- + +. ./defs +for f in HAVE_LIBINTL_H DEBUG_ENABLED +do + grep "#define.*$f" ${top_builddir}/config.h >/dev/null || { + echo "$f is not defined -- skiping $0" + exit 0 + } +done +AUTOGEN_TEMPL_DIRS=`cd ${srcdir}/..;pwd` +export AUTOGEN_TEMPL_DIRS + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +echo "creating ${testname}.def in `pwd`" +testname="${testname}" test_main="YES" \ +argument="${argument}" long_opts="YES" \ +${SHELLX} ${stdopts} option:'opt init' second=020 || \ + failure "Could not run stdopts.def" + +echo 'export = "extern char* gettext( char const* );";' >> ${testname}.def +CC="${CC} ${CFLAGS} -DENABLE_NLS=1 ${INC}" +CFLAGS='' +INC='' + +compile_with_nls() { + + echo ${AG_L} ${testname}.def + ${AG_L} ${testname}.def || \ + failure AutoGen could not process + + chmod u+w ${testname}.[ch] + # a "gettext" that reverses the text lines and characters. + # Leading white space is stripped from each line so that + # output lines do not have trailing white space. + # + cat >> ${testname}.c <<'_EOF_' +#include +char* +gettext(char const* pzS) +{ + static char z[4096]; + char* pzD = z + sizeof(z) - 1; + int ct = 0; + int found_nl = 0; + if (pzS == NULL) + return NULL; + if (strchr(pzS, '%') != NULL) + return VOIDP(pzS); + *--pzD = '\0'; + while ((*pzS == ' ') || (*pzS == '\t')) pzS++; + for (;;) { + char ch = *(pzS++); + if (ch == '\0') + break; + *(--pzD) = ch; + ct++; + if (ch != '\n') + continue; + found_nl = 1; + while ((*pzS == ' ') || (*pzS == '\t')) pzS++; + } + if (found_nl) + strcpy(z + sizeof(z) - 2, "\n"); + while (*pzD == '\n') + pzD++; + return pzD; +} +_EOF_ + + sedcmd='/ot sgub .* tropeR$/d;/ yb degakcaP/d' + compile "--help" + mv ${testname}.help ${testname}-${1}.help + cmp -s ${testname}-${1}.help ${testname}-${1}.hlp || { set +x ; \ + failure "`diff -c ${testname}-${1}.hlp ${testname}-${1}.help`" ; } +} + +# # # # # # # # # # HELP OUTPUT FILE # # # # # # # # # + +echo creating ${testname}.hlp +clean_help > ${testname}-1.hlp <<'_EOF_' +test_nls - Test AutoOpts for nls +Usage: nls [ - [] | --[{=| }] ]... +noitpircseD emaN-noitpO grA glF + -o Str option pircsed noitpo noitpo ehT + -s Num second pircsed noitpo dnoces ehT + -? no help tixe dna noitamrofni egasu dednetxe yalpsid + -! no more-help regap urht dessap noitamrofni egasu dednetxe +.retcarahc galf eht dna nehpyh +elgnis a yb ro eman rieht dna snehpyh delbuod yb deificeps era snoitpO +_EOF_ + +compile_with_nls 1 + +mv ${testname}.def ${testname}-1.def + +exec 3> ${testname}.def +cat ${testname}-1.def >&3 +echo 'full-usage = <''<''- _EOF_' >&3 +clean_help >&3 <<'_EOF_' +test_nls - Test AutoOpts for nls +Usage: nls [ - [] | --[{=| }] ]... + Flg Arg Option-Name Description + -o Str option The option descrip + -s Num second The second descrip + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + +Options are specified by doubled hyphens and their name or by a single +hyphen and the flag character. +_EOF_ +echo '_EOF_;' >&3 +exec 3>&- + +clean_help > ${testname}-2.hlp <<'_EOF_' +...] ]>lav<} |={[>eman<-- | ]>lav<[ >galf<- [ sln :egasU +sln rof stpOotuA tseT - sln_tset +pircsed noitpo ehT noitpo rtS o- +noitpircseD emaN-noitpO grA glF +pircsed dnoces ehT dnoces muN s- +.retcarahc galf eht dna nehpyh +elgnis a yb ro eman rieht dna snehpyh delbuod yb deificeps era snoitpO +regap urht dessap noitamrofni egasu dednetxe pleh-erom on !- +tixe dna noitamrofni egasu dednetxe yalpsid pleh on ?- +_EOF_ + +compile_with_nls 2 +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## End: + +# end of nls.test diff --git a/autoopts/test/rc.test b/autoopts/test/rc.test new file mode 100755 index 0000000..3c5ec54 --- /dev/null +++ b/autoopts/test/rc.test @@ -0,0 +1,261 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- + +# rc.test --- test loading and saving of rc files +# +# Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +. ./defs + +AUTOOPTS_TRACE=every +AUTOOPTS_TRACE_OUT=">>`pwd`/${testname}-ag-trace.txt" +export AUTOOPTS_TRACE AUTOOPTS_TRACE_OUT + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # +startdir=`pwd` +: "creating ${testname}.def in $startdir" + +TESTNAME=RC +export TESTNAME + +test_main="yes" \ +argument="mumble" long_opts="yes" \ +${SHELLX} ${stdopts} option second:init third: || \ + failure "Could not run stdopts.def" + +cat >> ${testname}.def <<_EOF_ +homerc = "\$\$/${testname}.rc"; +rcfile = ${testname}.file; +environrc; +_EOF_ + +${AG_L} ${testname}.def || \ + failure AutoGen could not process A + +# # # # # # # # # # VALIDATE HELP # # # # # # # # # + +clean_help > ${testname}-base1.help <<_EOF_ +test_rc - Test AutoOpts for rc +Usage: rc [ - [] | --[{=| }] ]... mumble + Flg Arg Option-Name Description + -o no option The option option descrip + -s Str second The second option descrip + -t Str third The third option descrip + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + -> opt save-opts save the option state to a config file + -< Str load-opts load options from a config file + - disabled as '--no-load-opts' + - may appear multiple times + +Options are specified by doubled hyphens and their name or by a single +hyphen and the flag character. + +The following option preset mechanisms are supported: + - reading file ..../${testname}.rc/rc.file + - examining environment variables named TEST_RC_* +_EOF_ + +mkdir ${testname}.rc ${testname}.run +compile "--help" +${SED} 's@\( - reading file \).*\(/'${testname}.rc/rc.file'\)@\1....\2@' \ + ${testname}.help > ${testname}-res1.help +cmp ${testname}-*1.help || \ + failure "`diff ${testname}-*.help`" + +# # # # # # # # # # DO THE REAL TEST # # # # # # # # # + +# Install an initialization for the "second" option. +# That goes into the ${testname}.rc directory. +# We change into the ${testname}.run directory and run the program. +# It should pick up the value saved into the ${testname}.rc dir. +# +./${testname} --second=third '->'${testname}.rc/${testname}.file + +cd ${testname}.run +../${testname} -t xxx MUMBLE > ${testname}.cmds + +# This is what the output should be: +# +cat > ${testname}.test <<'_EOF_' +OPTION_CT=2 +export OPTION_CT +TEST_RC_SECOND='third' +export TEST_RC_SECOND +TEST_RC_THIRD='xxx' +export TEST_RC_THIRD +_EOF_ + + +cmp ${testname}.cmds ${testname}.test || { + df="`diff -c ${testname}.test ${testname}.cmds`" + cd .. + failure "${df}" +} + +# # # # # + +TEST_RC=--no-load ../${testname} -t xxx MUMBLE > ${testname}-2.cmds + +# This is what the output should be: +# +cat > ${testname}-2.test <<'_EOF_' +OPTION_CT=2 +export OPTION_CT +TEST_RC_THIRD='xxx' +export TEST_RC_THIRD +_EOF_ + +cmp ${testname}-2.cmds ${testname}-2.test || { + df="`diff -c ${testname}-2.test ${testname}-2.cmds`" + cd .. + failure "${df}" +} + +# # # # # # # # # # SECOND TEST OUTPUT FILE # # # # # # # # # + +cat >> ../${testname}.rc/${testname}.file <<_EOF_ +[TEST_MUMBLE] +second fourth + +[TEST_${TESTNAME}] +second = fifth + +# this is another comment +# +[TEST_STUMBLE] +second : sixth +_EOF_ + +../${testname} -t yyy MUMBLE > ${testname}.cmds + +# This is what the output should be: +# +cat > ${testname}.test <<'_EOF_' +OPTION_CT=2 +export OPTION_CT +TEST_RC_SECOND='fifth' +export TEST_RC_SECOND +TEST_RC_THIRD='yyy' +export TEST_RC_THIRD +_EOF_ + +cmp ${testname}.cmds ${testname}.test || { + df="`diff -c ${testname}.test ${testname}.cmds`" + cd .. + failure "${df}" +} + +mv ../${testname}.rc/${testname}.file ../${testname}.rc/${testname}.save +( ${SED} '/^[TEST_MUMBLE]/,$d' ../${testname}.rc/${testname}.save + cat <<- _EOF_ + + second fourth + + + + fifth + + # this is another comment + # + + second : sixth + _EOF_ +) > ../${testname}.rc/${testname}.file + +../${testname} -t yyy MUMBLE > ${testname}.cmds + +cmp ${testname}.cmds ${testname}.test || { + df="USING : `diff -c ${testname}.test ${testname}.cmds`" + cd .. + failure "${df}" +} + +# # # # # # # # # # SECOND TEST, pt 2 UPDATE FILE # # # # # + +cp ../${testname}.rc/${testname}.file ../${testname}.rc/${testname}.more-save +../${testname} -t yyy '->>>' + +pair="../${testname}.rc/${testname}.file ../${testname}.rc/${testname}.more-save" +cmp $pair && { + df="USING : `diff -c $pair`" + cd .. + failure "UNCHANGED: $pair`echo;cat ../${testname}.rc/${testname}.file`" +} +{ + ${SED} "/^/,/^#\$/d" \ + ../${testname}.rc/${testname}.more-save + cat <<- _EOF + + second = fifth + third = yyy + _EOF +} > ../${testname}.rc/${testname}.expect +pair="../${testname}.rc/${testname}.file ../${testname}.rc/${testname}.expect" +cmp $pair || failure "BAD UPDATE: $pair`echo;cat ../${testname}.rc/${testname}.file`" + +# # # # # # # # # # THIRD TEST OUTPUT FILE # # # # # # # # # + +cd ${startdir} + +echo 'disable-save;' >> ${testname}.def + +${AG_L} ${testname}.def || \ + failure AutoGen could not process B + +compile "--help" +${SED} 's@\( - reading file \).*\(/'${testname}.rc/rc.file'\)@\1....\2@' \ + ${testname}.help > ${testname}-res2.help +egrep -v ' save-opts +save ' ${testname}-base1.help > ${testname}-base2.help + +cmp ${testname}-*2.help || \ + failure "`diff ${testname}-*2.help`" + +echo 'disable-load;' >> ${testname}.def + +${AG_L} ${testname}.def || \ + failure AutoGen could not process B + +compile "--help" +${SED} 's@\( - reading file \).*\(/'${testname}.rc/rc.file'\)@\1....\2@' \ + ${testname}.help > ${testname}-res3.help + +${SED} -e '/ load-opts *load /,/multiple times$/d' \ + ${testname}-base2.help > ${testname}-base3.help + +cmp ${testname}-*3.help || \ + failure "`diff ${testname}-*3.help`" + +# # # # # # # # # # HELP OUTPUT FILE # # # # # # # # # + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## End: + +# end of rc.test diff --git a/autoopts/test/shell.test b/autoopts/test/shell.test new file mode 100755 index 0000000..527c7f7 --- /dev/null +++ b/autoopts/test/shell.test @@ -0,0 +1,502 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# ---------------------------------------------------------------------- +# shell.test --- test shell program attribute +# make sure that when it is not specified +# then option processing consumes all args. +# +# Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +echo "creating ${testname}.def in `pwd`" + + testname="${testname}" \ +test_main="${test_main}" \ + argument="reg-arg [ ... ]" \ +long_opts=true \ +${SHELLX} ${stdopts} option: second || failure "Could not run stdopts.def" +mv ${testname}.def ${testname}.def-ori +{ + ${SED} '/^test-main/d;/value = .s/i\ + min = 1; max = 2; + ' ${testname}.def-ori + cat <<- _EOF_ + detail = "exit 99 ; oops."; + no-xlate = anything; + main = { main-type = shell-process; }; + _EOF_ +} > ${testname}.def + +${AG_L} ${testname}.def || \ + failure AutoGen could not process + +compile "-?" 2> ${testname}.hlp + +# # # # # # # # # # HELP OUTPUT FILE # # # # # # # # # + +echo creating ${testname}.hlp +cat > ${testname}.hlp <<'_EOF_' +test_shell - Test AutoOpts for shell +Usage: shell { - [] | --[{=| }] }... \ + reg-arg [ ... ] + Flg Arg Option-Name Req? Description + -o Str option opt The option option descrip + -s no second YES The second option descrip + - may appear up to 2 times + -? no help opt display extended usage information and exit + -! no more-help opt extended usage information passed thru pager +Options are specified by doubled hyphens and their name or by a single +hyphen and the flag character. +_EOF_ + +pair="${testname}.hlp ${testname}.help" +cmp -s ${pair} || \ + failure "HELP mismatch +`diff $pair`" + +./${testname} -X 2> /dev/null && \ + failure ${testname} should not accept bogus options + +./${testname} -o 2> /dev/null && \ + failure ${testname} should not accept missing options argument + +./${testname} 2> /dev/null && \ + failure ${testname} must have an argument + +( + PS4='>st> ' + set -- --help + eval "`exec 2>/dev/null ; ./${testname} \"$@\"`" + exit 1 +) || failure "improper --help exit" + +# # # # # # # # # # SHELL OUTPUT FILE # # # # # # # # # + +echo creating ${testname}.out +cat > ${testname}.out <<_EOF_ +OPTION_CT=3 +export OPTION_CT +TEST_SHELL_OPTION='opt-arg' +export TEST_SHELL_OPTION +TEST_SHELL_SECOND=1 # 0x1 +export TEST_SHELL_SECOND +_EOF_ + +./${testname} -o opt-arg -s a1 a2 > ${testname}.test || \ + failure ${testname} did not handle its options + +pair="${testname}.out ${testname}.test" +cmp -s $pair || \ + failure "SHELL PARSE OUTPUT CHANGED +`diff ${pair}`" + +${SED} '/main-type/s/process/parser/' ${testname}.def > XX +mv -f XX ${testname}.def + +echo ${AG_L} ${testname}.def +${AG_L} ${testname}.def || \ + failure 'AutoGen could not process' + +sedcmd='/Note that.*is only useful/,/will be regenerated/d' +compile "-?" + +# # # # # # # # # # HELP OUTPUT FILE # # # # # # # # # + +echo creating second ${testname}.hlp +clean_help > ${testname}.hlp <<'_EOF_' +genshellopt - Generate Shell Option Processing Script - Ver. 1 +Usage: shell [ - [] | --[{=| }] ]... + Flg Arg Option-Name Description + -o Str script Output Script File + -s Str shell Shell name (follows "#!" magic) + - disabled as '--no-shell' + - enabled by default + -v opt version output version information and exit + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + +Options are specified by doubled hyphens and their name or by a single +hyphen and the flag character. + +Note that ``shell'' is only useful if the output file does not already +exist. If it does, then the shell name and optional first argument will +be extracted from the script file. + +If the script file already exists and contains Automated Option Processing +text, the second line of the file through the ending tag will be replaced +by the newly generated text. The first ``#!'' line will be regenerated. + += = = = = = = = + +This incarnation of genshell will produce +a shell script to parse the options for test_shell: + +test_shell - Test AutoOpts for shell +Usage: test_shell { - [] | --[{=| }] }... \ + reg-arg [ ... ] + Flg Arg Option-Name Req? Description + -o Str option opt The option option descrip + -s no second YES The second option descrip + -? no help opt display extended usage information and exit + -! no more-help opt extended usage information passed thru pager + +Options are specified by doubled hyphens and their name or by a single +hyphen and the flag character. +_EOF_ + +pair=${testname}.hlp\ ${testname}.help +cmp -s ${pair} || \ + failure "script generator help output mismatch: +`diff -c ${pair}`" + +# # # # # # # # # # SCRIPT OUTPUT FILE # # # # # # # # # + +echo creating ${testname}.sht +exec 3> ${testname}.sht +echo "#! ${SHELL}" >&3 +cat >&3 <<'_EOF_' +# +TEST_SHELL_LONGUSAGE_TEXT='test_shell - Test AutoOpts for shell +Usage: test_shell { - [] | --[{=| }] }... \ + reg-arg [ ... ] + Flg Arg Option-Name Req? Description + -o Str option opt The option option descrip + -s no second YES The second option descrip + - may appear up to 2 times + -? no help opt display extended usage information and exit + -! no more-help opt extended usage information passed thru pager + +Options are specified by doubled hyphens and their name or by a single +hyphen and the flag character.' + +TEST_SHELL_USAGE_TEXT='test_shell - Test AutoOpts for shell +Usage: test_shell { - [] | --[{=| }] }... \ + reg-arg [ ... ] + Flg Arg Option-Name Req? Description + -o Str option opt The option option descrip + -s no second YES The second option descrip + -? no help opt display extended usage information and exit + -! no more-help opt extended usage information passed thru pager + +Options are specified by doubled hyphens and their name or by a single +hyphen and the flag character.' + + +TEST_SHELL_OPTION=${TEST_SHELL_OPTION} +TEST_SHELL_OPTION_set=false +export TEST_SHELL_OPTION + +if test -z "${TEST_SHELL_SECOND}" +then + TEST_SHELL_SECOND_CT=0 + export TEST_SHELL_SECOND_CT +else + TEST_SHELL_SECOND_CT=1 + TEST_SHELL_SECOND_1=${TEST_SHELL_SECOND} + export TEST_SHELL_SECOND_CT TEST_SHELL_SECOND_1 +fi + +ARG_COUNT=$# +OPT_PROCESS=true +OPT_ARG=$1 +while ${OPT_PROCESS} && [ $# -gt 0 ] +do + OPT_ELEMENT='' + OPT_ARG_VAL='' + + case "${OPT_ARG}" in + -- ) + OPT_PROCESS=false + shift + ;; + --* ) + OPT_CODE=`echo "X${OPT_ARG}"|sed 's/^X-*//'` + shift + OPT_ARG=$1 + case "${OPT_CODE}" in *=* ) + OPT_ARG_VAL=`echo "${OPT_CODE}"|sed 's/^[^=]*=//'` + OPT_CODE=`echo "${OPT_CODE}"|sed 's/=.*$//'` ;; esac + case "${OPT_CODE}" in + 'op' | \ + 'opt' | \ + 'opti' | \ + 'optio' | \ + 'option' ) + if [ -n "${TEST_SHELL_OPTION}" ] && ${TEST_SHELL_OPTION_set} ; then + echo 'Error: duplicate OPTION option' + echo "$TEST_SHELL_USAGE_TEXT" + exit 1 + fi >&2 + TEST_SHELL_OPTION_set=true + OPT_NAME='OPTION' + OPT_ARG_NEEDED=YES + ;; + + 'se' | \ + 'sec' | \ + 'seco' | \ + 'secon' | \ + 'second' ) + if [ $TEST_SHELL_SECOND_CT -gt 2 ] ; then + echo 'Error: more than 2 SECOND options' + echo "$TEST_SHELL_USAGE_TEXT" + exit 1 + fi >&2 + TEST_SHELL_SECOND_CT=`expr ${TEST_SHELL_SECOND_CT} + 1` + OPT_ELEMENT="_${TEST_SHELL_SECOND_CT}" + OPT_NAME='SECOND' + eval TEST_SHELL_SECOND${OPT_ELEMENT}=true + export TEST_SHELL_SECOND${OPT_ELEMENT} + OPT_ARG_NEEDED=NO + ;; + + 'he' | \ + 'hel' | \ + 'help' ) + echo "$TEST_SHELL_LONGUSAGE_TEXT" + exit 0 + ;; + + 'mo' | \ + 'mor' | \ + 'more' | \ + 'more-' | \ + 'more-h' | \ + 'more-he' | \ + 'more-hel' | \ + 'more-help' ) + echo "$TEST_SHELL_LONGUSAGE_TEXT" | ${PAGER-more} + exit 0 + ;; + + * ) + echo Unknown option: "${OPT_CODE}" >&2 + echo "$TEST_SHELL_USAGE_TEXT" >&2 + exit 1 + ;; + esac + case "${OPT_ARG_NEEDED}" in + NO ) + OPT_ARG_VAL='' + ;; + YES ) + if [ -z "${OPT_ARG_VAL}" ] + then + if [ $# -eq 0 ] + then + echo No argument provided for ${OPT_NAME} option + echo "$TEST_SHELL_USAGE_TEXT" + exit 1 + fi >&2 + OPT_ARG_VAL=${OPT_ARG} + shift + OPT_ARG=$1 + fi + ;; + OK ) + if [ -z "${OPT_ARG_VAL}" ] && [ $# -gt 0 ] + then + case "${OPT_ARG}" in -* ) ;; * ) + OPT_ARG_VAL=${OPT_ARG} + shift + OPT_ARG=$1 ;; esac + fi + ;; + esac + ;; + + -* ) + OPT_CODE=`echo "X${OPT_ARG}" | sed 's/X-\(.\).*/\1/'` + OPT_ARG=` echo "X${OPT_ARG}" | sed 's/X-.//'` + case "${OPT_CODE}" in + 'o' ) + if [ -n "${TEST_SHELL_OPTION}" ] && ${TEST_SHELL_OPTION_set} ; then + echo 'Error: duplicate OPTION option' + echo "$TEST_SHELL_USAGE_TEXT" + exit 1 + fi >&2 + TEST_SHELL_OPTION_set=true + OPT_NAME='OPTION' + OPT_ARG_NEEDED=YES + ;; + + 's' ) + if [ $TEST_SHELL_SECOND_CT -gt 2 ] ; then + echo 'Error: more than 2 SECOND options' + echo "$TEST_SHELL_USAGE_TEXT" + exit 1 + fi >&2 + TEST_SHELL_SECOND_CT=`expr ${TEST_SHELL_SECOND_CT} + 1` + OPT_ELEMENT="_${TEST_SHELL_SECOND_CT}" + OPT_NAME='SECOND' + eval TEST_SHELL_SECOND${OPT_ELEMENT}=true + export TEST_SHELL_SECOND${OPT_ELEMENT} + OPT_ARG_NEEDED=NO + ;; + + '?' ) + echo "$TEST_SHELL_LONGUSAGE_TEXT" + exit 0 + ;; + + '!' ) + echo "$TEST_SHELL_LONGUSAGE_TEXT" | ${PAGER-more} + exit 0 + ;; + + * ) + echo Unknown flag: "${OPT_CODE}" >&2 + echo "$TEST_SHELL_USAGE_TEXT" >&2 + exit 1 + ;; + esac + case "${OPT_ARG_NEEDED}" in + NO ) + if [ -n "${OPT_ARG}" ] + then + OPT_ARG=-${OPT_ARG} + else + shift + OPT_ARG=$1 + fi + ;; + YES ) + if [ -n "${OPT_ARG}" ] + then + OPT_ARG_VAL=${OPT_ARG} + else + if [ $# -eq 0 ] + then + echo No argument provided for ${OPT_NAME} option + echo "$TEST_SHELL_USAGE_TEXT" + exit 1 + fi >&2 + shift + OPT_ARG_VAL=$1 + fi + shift + OPT_ARG=$1 + ;; + OK ) + if [ -n "${OPT_ARG}" ] + then + OPT_ARG_VAL=${OPT_ARG} + shift + OPT_ARG=$1 + else + shift + if [ $# -gt 0 ] + then + case "$1" in -* ) ;; * ) + OPT_ARG_VAL=$1 + shift ;; esac + OPT_ARG=$1 + fi + fi + ;; + esac + ;; + + * ) + OPT_PROCESS=false + ;; + esac + if [ -n "${OPT_ARG_VAL}" ] + then + eval TEST_SHELL_${OPT_NAME}${OPT_ELEMENT}="'${OPT_ARG_VAL}'" + export TEST_SHELL_${OPT_NAME}${OPT_ELEMENT} + fi +done +OPTION_COUNT=`expr $ARG_COUNT - $#` +OPERAND_COUNT=$# +unset OPT_PROCESS || : +unset OPT_ELEMENT || : +unset OPT_ARG || : +unset OPT_ARG_NEEDED || : +unset OPT_NAME || : +unset OPT_CODE || : +unset OPT_ARG_VAL || : +test ${TEST_SHELL_SECOND_CT-0} -ge 1 || { + echo TEST_SHELL_SECOND has not been set + exit 1 +} 1>&2 + +# # # # # # # # # # +# +# END OF AUTOMATED OPTION PROCESSING +# +# # # # # # # # # # -- do not modify this marker -- + +env | grep '^TEST_SHELL_' +_EOF_ +exec 3>&- + +# # # # # # # # # # SCRIPT OUTPUT TESTING # # # # # # # # # + +rm -f ${testname}.sh +./${testname} -o ${testname}.sh + +sedcmd='2,/From the.*option def/d;/^exit 99/d' +${FGREP} 'Packaged by ' ${testname}.sh >/dev/null && { + sedcmd=${sedcmd}${nl}'/^Packaged by /d + /^Report .* bugs to /d' +} +sedcmd=${sedcmd}${nl}'/and the flag character\.$/s/$/'"'/" + +${SED} "$sedcmd" ${testname}.sh > ${testname}.shx + +pair="${testname}.sht ${testname}.shx" +cmp -s ${pair} || \ + failure "PARSING SCRIPT CHANGE +`diff ${pair}`" + +# # # # # # # # # # SCRIPT PROCESSING TEST # # # # # # # # # + +./${testname}.sh --opt opt-arg -s a1 a2 | sort > ${testname}.test || \ + failure ${testname} did not handle its options + +sort > ${testname}.out <<_EOF_ +TEST_SHELL_OPTION=opt-arg +TEST_SHELL_SECOND_1=true +TEST_SHELL_SECOND_CT=1 +_EOF_ + +pair="${testname}.out ${testname}.test" +cmp -s $pair || \ + failure "Misprocessed options +`diff $pair`" + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## End: + +# end of shell.test diff --git a/autoopts/test/stdopts.def b/autoopts/test/stdopts.def new file mode 100644 index 0000000..59f3d8d --- /dev/null +++ b/autoopts/test/stdopts.def @@ -0,0 +1,107 @@ +#! /bin/sh + +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +# This is the standard set of options for testing option processing +# It is expected to be dot + +exec 5> $testname.def +cat >&5 <<- _EOF_ + + AutoGen definitions options; + + config-header = 'config.h'; + prog-name = "test_${testname}"; + prog-title = "Test AutoOpts for ${testname}"; + _EOF_ + +echo test_main $test_main +echo argument $argument +echo long_opts $long_opts + +{ + test -n "${test_main}" && echo "test-main = '${test_main}';" + test -n "${argument}" && echo "argument = '${argument}';" + test -n "${long_opts}" && echo "long-opts;" +} >&5 + +for flag +do + fname=`echo "${flag}" | ${SED} 's/[^a-zA-Z0-9_-].*//'` + flag=`echo "${flag}" | ${SED} "s/^${fname}//"` + + case "${flag}" in + :* ) + aval=`echo $flag | ${SED} 's/^://'` + arg=" arg-type = string;" + test -n "${aval}" && arg="${arg} arg_default = '${aval}';" + ;; + + =* ) + aval=`echo $flag | ${SED} 's/=//'` + arg=" arg-type = number;" + test -n "${aval}" && arg="${arg} arg_default = '${aval}';" + ;; + + @* ) + arg=`echo $flag | ${SED} 's/@//'` + case "${arg}" in + *=* ) default=`echo $flag | ${SED} 's/.*=//'` + arg=`echo $arg | ${SED} 's/=.*//'` + arg=" arg-type = '${arg}'; arg-default='${default}';" + ;; + + * ) + arg=" arg-type = '${arg}';" + ;; + esac + ;; + + * ) + unset arg + ;; + esac + + cat <<-_EOF_ + flag = { + name = "${fname}"; + descrip = "The ${fname} option descrip"; + _EOF_ + + ${use_flags} && { + fname=`echo ${fname} | ${SED} 's/\(.\).*/\1/'` + echo " value = '${fname}';" + } + test -n "${arg}" && echo "${arg}" + echo "};" + echo +done >&5 + +exec 5>&- +ls -l ${testname}.def + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## End: + +# end of stdopts.def diff --git a/autoopts/test/stdopts.test b/autoopts/test/stdopts.test new file mode 100755 index 0000000..c4b667e --- /dev/null +++ b/autoopts/test/stdopts.test @@ -0,0 +1,169 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# ---------------------------------------------------------------------- +# stdopts.test --- test standard options +# +# Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +echo "creating ${testname}.def in `pwd`" +cat > ${testname}.def <<- _EOF_ + + AutoGen Definitions options; + + prog-name = test_${testname}; + prog-title = "${testname} test"; + config-header = 'config.h'; + no-xlate = anything; + main = { + main-type = main; + main-text = <<- _EndMain_ + \ (void)optionProcess(&test_${testname}Options, argc, argv); + \ optionPutShell(&test_${testname}Options); + \ return ferror(stdout) ? 1 : 0; + _EndMain_; + }; + long-opts; + + #define VERBOSE_ENUM + #define VERBOSE_FLAG + + #include stdoptions + _EOF_ + +${AG_L} ${testname}.def || \ + failure AutoGen could not process + +compile "-?" + +# # # # # # # # # # HELP OUTPUT FILE # # # # # # # # # + +echo creating ${testname}.hlp +clean_help > ${testname}.hbase <<- _EOF_ + test_stdopts - stdopts test + Usage: stdopts [ - [] | --[{=| }] ]... + + The following options are commonly used and are provided and supported + by AutoOpts: + + Flg Arg Option-Name Description + -V KWd verbose run program with progress info + + Version, usage and configuration options: + + Flg Arg Option-Name Description + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + + Options are specified by doubled hyphens and their name or by a single + hyphen and the flag character. + + The valid "verbose" option keywords are: + silent quiet brief informative verbose + or an integer from 0 through 4 + _EOF_ + +# When building with DEBUG set, we get an unanticipated option: +# +${GREP} -v 'run program with debugging info' ${testname}.help > ${testname}.hres + +cmp -s ${testname}.h[br]* || \ + failure "MISCOMPARE: `diff ${testname}.h[br]*`" + +./${testname} --verbose=exp > /dev/null 2>&1 && \ + failure ${testname} accepted ambiguous keyword + +./${testname} --verbose=inf > ${testname}.out || \ + failure ${testname} did not handle its options + +cat > ${testname}.oex <<_EOF_ +OPTION_CT=1 +export OPTION_CT +TEST_STDOPTS_VERBOSE='informative' +export TEST_STDOPTS_VERBOSE +_EOF_ + +cmp -s ${testname}.o* || \ + failure "`diff ${testname}.o??`" + +# # # # # # # # # # USAGE OPTION # # # # # # # # # # # + +( ${SED} "s/${testname}/${testname}-2/g + s/-2Options/_2Options/g" ${testname}.def + echo 'usage-opt;' +) > ${testname}-2.def + +testname=${testname}-2 + +${AG_L} ${testname}.def || { + testname=${testname%-2} + failure AutoGen could not process +} + +compile "--usage" + +clean_help > ${testname}.hbase <<- _EOF_ + test_stdopts-2 - stdopts-2 test + Usage: stdopts-2 [ - [] | --[{=| }] ]... + Flg Arg Option-Name Description + -V KWd verbose run program with progress info + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + -u no usage abbreviated usage to stdout + + Options are specified by doubled hyphens and their name or by a single + hyphen and the flag character. + _EOF_ + +# When building with DEBUG set, we get an unanticipated option: +# +${GREP} -v 'run program with debugging info' ${testname}.help > ${testname}.hres + +cmp -s ${testname}.h[br]* || { + testname=${testname%-2} + failure "MISCOMPARE: `diff ${testname}-2.h[br]*`" +} + +use=` + set +x + exec 2>&1 + exec 1>/dev/null + ./${testname} --usage` +test $? -eq 0 || failure usage failure +test "X${use}" = X || failure misdirected usage + +testname=${testname%-2} +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## End: + +# end of stdopts.test diff --git a/autoopts/test/time.test b/autoopts/test/time.test new file mode 100755 index 0000000..4e85713 --- /dev/null +++ b/autoopts/test/time.test @@ -0,0 +1,100 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# ---------------------------------------------------------------------- +# time.test --- test time duration argument +# +# Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +echo "creating ${testname}.def in `pwd`" +unset test_main +export testname argument long_opts + +${SHELLX} ${stdopts} ${testname}@time='1d 2 h 15:10' +here='<<' +cat >> ${testname}.def <<- _EOF_ + main = { + main-type = main; + main-text = ${here}- CodeEnd + printf("arg %s represents %d seconds", argv[-1], + OPT_VALUE_TIME); + return 0; + CodeEnd; + }; + _EOF_ + +echo ${AG_L} ${testname}.def +${AG_L} ${testname}.def || \ + failure AutoGen could not process + +compile "-?" + +# # # # # # # # # # HELP OUTPUT FILE # # # # # # # # # + +basehlp=${testname}.hlp +echo creating ${basehlp} +clean_help > ${basehlp} <<'_EOF_' +test_time - Test AutoOpts for time +Usage: time [ - [] ]... + Flg Arg Option-Name Description + -t Tim time The time option descrip + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + +_EOF_ + +cmp -s ${testname}.h*lp || \ + failure "`diff ${basehlp} ${testname}.help`" + +time_val=213791 + +ck() { + tim=`./${testname} -t "$*" | \ + ${SED} -n 's/.* represents \([0-9]*\) seconds/\1/p'` + test -z "${tim}" && failure ${testname} could not parse "$*" + test ${tim} -eq ${time_val} || \ + failure ${testname} misevaluated "$*" +} + +ck 2 d 11h 23:11 +ck 2 d 11h 23m 11s + +tim=`./${testname} -t '2 d 10h 83:11'` && \ + failure ${testname} handled bad options + +# # # # # # # # # # T E S T E N D # # # # # # # # # # + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## End: + +# end of argument.test diff --git a/autoopts/test/usage.test b/autoopts/test/usage.test new file mode 100755 index 0000000..5b88a89 --- /dev/null +++ b/autoopts/test/usage.test @@ -0,0 +1,655 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# ---------------------------------------------------------------------- +# usage.test --- test all the ways usage text can be printed. +# +# Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd +# +# ---------------------------------------------------------------------- + +${VERBOSE} && kill_delay=15 || kill_delay=8 +. ./defs + +# # # # # # # # # # HELP OUTPUT FILE # # # # # # # # # + +# ============= usage_LGFRA.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_LGFRA.hlp' +test_usage_LGFRA - Checkout usage_LGFRA Options +Usage: usage_LGFRA { - [] | --[{=| }] }... \ + cmd-arg ... +X +X -L, --check-dirs=str Checkout directory list +X --show-defs[=arg] Show the definition tree +X -?, --help display extended usage information and exit +X -!, --more-help extended usage information passed thru pager +SHAR_EOF + +# ============= usage_LGFRp.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_LGFRp.hlp' +test_usage_LGFRp - Checkout usage_LGFRp Options +Usage: usage_LGFRp { - | -- }... cmd-arg ... +X +X -L, --check-dirs Checkout directory list +X --show-defs Show the definition tree +X -?, --help display extended usage information and exit +X -!, --more-help extended usage information passed thru pager +SHAR_EOF + +# ============= usage_LGFoA.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_LGFoA.hlp' +test_usage_LGFoA - Checkout usage_LGFoA Options +Usage: usage_LGFoA [ - [] | --[{=| }] ]... \ + cmd-arg ... +X +X -L, --check-dirs=str Checkout directory list +X --show-defs[=arg] Show the definition tree +X -?, --help display extended usage information and exit +X -!, --more-help extended usage information passed thru pager +SHAR_EOF + +# ============= usage_LGFop.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_LGFop.hlp' +test_usage_LGFop - Checkout usage_LGFop Options +Usage: usage_LGFop [ - | -- ]... cmd-arg ... +X +X -L, --check-dirs Checkout directory list +X --show-defs Show the definition tree +X -?, --help display extended usage information and exit +X -!, --more-help extended usage information passed thru pager +SHAR_EOF + +# ============= usage_LGsRA.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_LGsRA.hlp' +test_usage_LGsRA - Checkout usage_LGsRA Options +Usage: usage_LGsRA { --[{=| }] }... cmd-arg ... +X +X --check-dirs=str Checkout directory list +X --show-defs[=arg] Show the definition tree +X --help display extended usage information and exit +X --more-help extended usage information passed thru pager +SHAR_EOF + +# ============= usage_LGsRp.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_LGsRp.hlp' +test_usage_LGsRp - Checkout usage_LGsRp Options +Usage: usage_LGsRp { -- }... cmd-arg ... +X +X --check-dirs Checkout directory list +X --show-defs Show the definition tree +X --help display extended usage information and exit +X --more-help extended usage information passed thru pager +SHAR_EOF + +# ============= usage_LGsoA.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_LGsoA.hlp' +test_usage_LGsoA - Checkout usage_LGsoA Options +Usage: usage_LGsoA [ --[{=| }] ]... cmd-arg ... +X +X --check-dirs=str Checkout directory list +X --show-defs[=arg] Show the definition tree +X --help display extended usage information and exit +X --more-help extended usage information passed thru pager +SHAR_EOF + +# ============= usage_LGsop.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_LGsop.hlp' +test_usage_LGsop - Checkout usage_LGsop Options +Usage: usage_LGsop [ -- ]... cmd-arg ... +X +X --check-dirs Checkout directory list +X --show-defs Show the definition tree +X --help display extended usage information and exit +X --more-help extended usage information passed thru pager +SHAR_EOF + +# ============= usage_LaFRA.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_LaFRA.hlp' +test_usage_LaFRA - Checkout usage_LaFRA Options +Usage: usage_LaFRA { - [] | --[{=| }] }... \ + cmd-arg ... +X Flg Arg Option-Name Req? Description +X -L Str check-dirs YES Checkout directory list +X opt show-defs opt Show the definition tree +X -? no help opt display extended usage information and exit +X -! no more-help opt extended usage information passed thru pager +SHAR_EOF + +# ============= usage_LaFRp.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_LaFRp.hlp' +test_usage_LaFRp - Checkout usage_LaFRp Options +Usage: usage_LaFRp { - | -- }... cmd-arg ... +X Flg Arg Option-Name Req? Description +X -L no check-dirs YES Checkout directory list +X no show-defs opt Show the definition tree +X -? no help opt display extended usage information and exit +X -! no more-help opt extended usage information passed thru pager +SHAR_EOF + +# ============= usage_LaFoA.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_LaFoA.hlp' +test_usage_LaFoA - Checkout usage_LaFoA Options +Usage: usage_LaFoA [ - [] | --[{=| }] ]... \ + cmd-arg ... +X Flg Arg Option-Name Description +X -L Str check-dirs Checkout directory list +X opt show-defs Show the definition tree +X -? no help display extended usage information and exit +X -! no more-help extended usage information passed thru pager +SHAR_EOF + +# ============= usage_LaFop.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_LaFop.hlp' +test_usage_LaFop - Checkout usage_LaFop Options +Usage: usage_LaFop [ - | -- ]... cmd-arg ... +X Flg Arg Option-Name Description +X -L no check-dirs Checkout directory list +X no show-defs Show the definition tree +X -? no help display extended usage information and exit +X -! no more-help extended usage information passed thru pager +SHAR_EOF + +# ============= usage_LasRA.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_LasRA.hlp' +test_usage_LasRA - Checkout usage_LasRA Options +Usage: usage_LasRA { --[{=| }] }... cmd-arg ... +X Arg Option-Name Req? Description +X Str check-dirs YES Checkout directory list +X opt show-defs opt Show the definition tree +X no help opt display extended usage information and exit +X no more-help opt extended usage information passed thru pager +SHAR_EOF + +# ============= usage_LasRp.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_LasRp.hlp' +test_usage_LasRp - Checkout usage_LasRp Options +Usage: usage_LasRp { -- }... cmd-arg ... +X Arg Option-Name Req? Description +X no check-dirs YES Checkout directory list +X no show-defs opt Show the definition tree +X no help opt display extended usage information and exit +X no more-help opt extended usage information passed thru pager +SHAR_EOF + +# ============= usage_LasoA.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_LasoA.hlp' +test_usage_LasoA - Checkout usage_LasoA Options +Usage: usage_LasoA [ --[{=| }] ]... cmd-arg ... +X Arg Option-Name Description +X Str check-dirs Checkout directory list +X opt show-defs Show the definition tree +X no help display extended usage information and exit +X no more-help extended usage information passed thru pager +SHAR_EOF + +# ============= usage_Lasop.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_Lasop.hlp' +test_usage_Lasop - Checkout usage_Lasop Options +Usage: usage_Lasop [ -- ]... cmd-arg ... +X Arg Option-Name Description +X no check-dirs Checkout directory list +X no show-defs Show the definition tree +X no help display extended usage information and exit +X no more-help extended usage information passed thru pager +SHAR_EOF + +# ============= usage_sGFRA.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_sGFRA.hlp' +test_usage_sGFRA - Checkout usage_sGFRA Options +Usage: usage_sGFRA { - [] }... cmd-arg ... +X +X -L str Checkout directory list +X -s [arg] Show the definition tree +X -? display extended usage information and exit +X -! extended usage information passed thru pager +SHAR_EOF + +# ============= usage_sGFRp.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_sGFRp.hlp' +test_usage_sGFRp - Checkout usage_sGFRp Options +Usage: usage_sGFRp { - }... cmd-arg ... +X +X -L Checkout directory list +X -s Show the definition tree +X -? display extended usage information and exit +X -! extended usage information passed thru pager +SHAR_EOF + +# ============= usage_sGFoA.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_sGFoA.hlp' +test_usage_sGFoA - Checkout usage_sGFoA Options +Usage: usage_sGFoA [ - [] ]... cmd-arg ... +X +X -L str Checkout directory list +X -s [arg] Show the definition tree +X -? display extended usage information and exit +X -! extended usage information passed thru pager +SHAR_EOF + +# ============= usage_sGFop.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_sGFop.hlp' +test_usage_sGFop - Checkout usage_sGFop Options +Usage: usage_sGFop [ - ]... cmd-arg ... +X +X -L Checkout directory list +X -s Show the definition tree +X -? display extended usage information and exit +X -! extended usage information passed thru pager +SHAR_EOF + +# ============= usage_sGsRA.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_sGsRA.hlp' +test_usage_sGsRA - Checkout usage_sGsRA Options +Usage: usage_sGsRA { [{=| }] }... +X +X check-dirs=str Checkout directory list +X show-defs[=arg] Show the definition tree +X help display extended usage information and exit +X more-help extended usage information passed thru pager +SHAR_EOF + +# ============= usage_sGsRp.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_sGsRp.hlp' +test_usage_sGsRp - Checkout usage_sGsRp Options +Usage: usage_sGsRp { }... +X +X check-dirs Checkout directory list +X show-defs Show the definition tree +X help display extended usage information and exit +X more-help extended usage information passed thru pager +SHAR_EOF + +# ============= usage_sGsoA.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_sGsoA.hlp' +test_usage_sGsoA - Checkout usage_sGsoA Options +Usage: usage_sGsoA [ [{=| }] ]... +X +X check-dirs=str Checkout directory list +X show-defs[=arg] Show the definition tree +X help display extended usage information and exit +X more-help extended usage information passed thru pager +SHAR_EOF + +# ============= usage_sGsop.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_sGsop.hlp' +test_usage_sGsop - Checkout usage_sGsop Options +Usage: usage_sGsop [ ]... +X +X check-dirs Checkout directory list +X show-defs Show the definition tree +X help display extended usage information and exit +X more-help extended usage information passed thru pager +SHAR_EOF + +# ============= usage_saFRA.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_saFRA.hlp' +test_usage_saFRA - Checkout usage_saFRA Options +Usage: usage_saFRA { - [] }... cmd-arg ... +X Flg Arg Option-Name Req? Description +X -L Str check-dirs YES Checkout directory list +X -s opt show-defs opt Show the definition tree +X -? no help opt display extended usage information and exit +X -! no more-help opt extended usage information passed thru pager +SHAR_EOF + +# ============= usage_saFRp.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_saFRp.hlp' +test_usage_saFRp - Checkout usage_saFRp Options +Usage: usage_saFRp { - }... cmd-arg ... +X Flg Arg Option-Name Req? Description +X -L no check-dirs YES Checkout directory list +X -s no show-defs opt Show the definition tree +X -? no help opt display extended usage information and exit +X -! no more-help opt extended usage information passed thru pager +SHAR_EOF + +# ============= usage_saFoA.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_saFoA.hlp' +test_usage_saFoA - Checkout usage_saFoA Options +Usage: usage_saFoA [ - [] ]... cmd-arg ... +X Flg Arg Option-Name Description +X -L Str check-dirs Checkout directory list +X -s opt show-defs Show the definition tree +X -? no help display extended usage information and exit +X -! no more-help extended usage information passed thru pager +SHAR_EOF + +# ============= usage_saFop.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_saFop.hlp' +test_usage_saFop - Checkout usage_saFop Options +Usage: usage_saFop [ - ]... cmd-arg ... +X Flg Arg Option-Name Description +X -L no check-dirs Checkout directory list +X -s no show-defs Show the definition tree +X -? no help display extended usage information and exit +X -! no more-help extended usage information passed thru pager +SHAR_EOF + +# ============= usage_sasRA.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_sasRA.hlp' +test_usage_sasRA - Checkout usage_sasRA Options +Usage: usage_sasRA { [{=| }] }... +X Arg Option-Name Req? Description +X Str check-dirs YES Checkout directory list +X opt show-defs opt Show the definition tree +X no help opt display extended usage information and exit +X no more-help opt extended usage information passed thru pager +SHAR_EOF + +# ============= usage_sasRp.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_sasRp.hlp' +test_usage_sasRp - Checkout usage_sasRp Options +Usage: usage_sasRp { }... +X Arg Option-Name Req? Description +X no check-dirs YES Checkout directory list +X no show-defs opt Show the definition tree +X no help opt display extended usage information and exit +X no more-help opt extended usage information passed thru pager +SHAR_EOF + +# ============= usage_sasoA.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_sasoA.hlp' +test_usage_sasoA - Checkout usage_sasoA Options +Usage: usage_sasoA [ [{=| }] ]... +X Arg Option-Name Description +X Str check-dirs Checkout directory list +X opt show-defs Show the definition tree +X no help display extended usage information and exit +X no more-help extended usage information passed thru pager +SHAR_EOF + +# ============= usage_sasop.hlp ============== +${SED} 's/^X//;/^[ ]*$/d' << 'SHAR_EOF' > 'usage_sasop.hlp' +test_usage_sasop - Checkout usage_sasop Options +Usage: usage_sasop [ ]... +X Arg Option-Name Description +X no check-dirs Checkout directory list +X no show-defs Show the definition tree +X no help display extended usage information and exit +X no more-help extended usage information passed thru pager +SHAR_EOF + +# # # # # # # # # # DEFINITIONS FILES # # # # # # # # # + +emit_defs() +{ + exec 4> $1.def + cat >&4 <<- _EOF_ + AutoGen Definitions options; + prog-name = test_$1; + prog-title = "Checkout $1 Options"; + config-header = 'config.h'; + test-main; + _EOF_ + + cmd_arg="argument = 'cmd-arg ...';" + if ${long_opts} + then + echo "long-opts;" >&4 + if ${flag_opts} + then detail="Long and short (flag) options are accepted." + else detail="Only long options are accepted." ; fi + else + if ${flag_opts} + then detail="Only short (flag) options are accepted." + else detail="All command line arguments must be named options." + cmd_arg='' + fi + fi + + if ${gnu_usage} + then + echo "gnu-usage;" >&4 + detail="${detail}${nl}Usage should be in GNU style." + else + detail="${detail}${nl}Usage is in AutoOpts traditional style." + fi + + cat >&4 <<- _EOF_ + ${cmd_arg} + flag = { + name = check_dirs; + descrip = "Checkout directory list"; + _EOF_ + + if ${flag_opts} + then + echo " value = L;" >&4 + fi + + if ${req_opts} + then + echo " min = '1';" >&4 + detail="${detail}${nl}The check-dirs option is required." + else + detail="${detail}${nl}There are no required options." + fi + + if ${arg_opts} + then + echo " arg-type = string;" >&4 + echo " arg-name = dir;" >&4 + detail="${detail}${nl}Some options require arguments." + else + detail="${detail}${nl}No options require arguments." + fi + + cat >&4 <<- _EOF_ + }; + + flag = { + name = show_defs; + descrip = "Show the definition tree"; + _EOF_ + + if ${flag_opts} + then + ${long_opts} || echo " value = s;" >&4 + fi + + if ${arg_opts} + then + echo " arg-type = number;" >&4 + echo " arg-name = depth;" >&4 + echo " arg-optional;" >&4 + fi + + echo "};" >&4 + echo "detail = '${detail}';" >&4 + + exec 4>&- +} + +run_usage_test() { + ${arg_opts} && name="${rname}A" || name="${rname}p" + testname=${tname}_${name} + emit_defs ${testname} + test_list="${test_list} ${testname}" + echo firstline >> ${defnames_raw} + ${AG_L} ${testname}.def >> ${defnames_raw} || { + cat ${defnames_raw} + failure "AutoGen could not process $testname" + } + + ${SED} \ + -e '1,/definition names looked up/d' \ + -e '/end of looked up def/,$d' ${defnames_raw} \ + ${defnames_raw} >> ${defnames_file} + compile ${helpstr} + ${SED} -e '/extended usage information passed thru pager/q' \ + ${testname}.help > XXX + mv XXX ${testname}.help + cmp -s ${testname}.help ${testname}.hlp || \ + failure "FAILED ${testname} hlp -> help +`diff ${testname}.hlp ${testname}.help`" +} + +test_list="" +tname=${testname} +defnames_raw=${TMPDIR}/defnames.raw +defnames_file=${TMPDIR}/defnames.uniq +AG_L=${AG_L}\ --used-defines + +case "$-" in +*x* ) setx='set -x' ;; +* ) setx='' ;; +esac + +stime=$(date +%s) + +for long_opts in true false +do + ${long_opts} && lname=L || lname=s + + for gnu_usage in true false + do + ${gnu_usage} && uname="${lname}G" || uname="${lname}a" + + for flag_opts in true false + do + ${flag_opts} && fname="${uname}F" || fname="${uname}s" + + if ${long_opts} + then helpstr=--help + + elif ${flag_opts} + then helpstr='-?' + + else helpstr=help + fi + + for req_opts in true false + do + ${req_opts} && rname="${fname}R" || rname="${fname}o" + + for arg_opts in true false + do + run_usage_test + done + done + done + done +done + +test -z "${DEBUG_USAGE}" && cleanup && exit 0 + +sort -u -o ${defnames_file} ${defnames_file} +cat > ${defnames_raw} <<- _EOF_ + aliases + allow_errors + arg_default + arg_optional + arg_range + arg_type + argument + call_proc + code + config_header + copyright + default + deprecated + descrip + detail + disable + documentation + eaddr + enable + enabled + environrc + equivalence + exit_name + explain + export + extract_code + field + file_fail_code + flag + flag_code + flag_proc + flags_cant + flags_must + full_usage + gnu_usage + guard_option_names + help_value + homerc + ifdef + ifndef + immed_disable + immediate + include + lib_name + library + long_opts + main + main_text + main_type + max + min + more_help_value + must_set + name + no_command + no_libopts + no_misuse_usage + no_preset + no_xlate + nomem_fail_code + omitted_usage + package + prefix + prefix_enum + preserve_case + prog_name + prog_title + reorder_args + resettable + scaled + settable + short_usage + stack_arg + std_value + test_main + translators + unstack_arg + usage + usage_message + usage_opt + usage_type + val_name + val_upname + value + version + _EOF_ + +cmp ${defnames_raw} ${defnames_file} || \ + failure "${defnames_raw} and ${defnames_file} do not compare${nl}` + diff ${defnames_raw} ${defnames_file}`" +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## End: + +# end of usage.test diff --git a/autoopts/test/vendor.test b/autoopts/test/vendor.test new file mode 100755 index 0000000..9047e3f --- /dev/null +++ b/autoopts/test/vendor.test @@ -0,0 +1,170 @@ +#! /bin/sh +# -*- Mode: shell-script -*- +# ---------------------------------------------------------------------- +# vendor.test --- test the vendor-opt option +# +# Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd +# +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +{ + sedcmd=' +s/long-opts;/vendor-opt;/ +/#include "autogen.h"/d +/^prog-name/s/=.*/= '${testname}';/ +s/AutoGen/'${testname}'/g +/^include /s/= '${testname}'5 Temp/= AutoGen5 Temp/ +/^config-header/s/=.*/= '${testname}'-config.h;/ +/call-proc *=/d +/#ifndef XML/,/^#endif/ { + /^#else/,/^#endif/d + /^#/d +} +/flag-code =.*_EOCode_/,/_EOCode_;/d +/flag-code *=/d +' + + ${SED} "$sedcmd" ${top_srcdir}/agen5/opts.def + cat <<- _EOF_ + config-header = ${testname}-config.h; + help-value = h; + save-opts-value = S; + load-opts-value = P; + gnu-usage; + main = { main-type = shell-process; }; + include = '#undef DEBUG_ENABLED'; + _EOF_ +} > ${testname}.def + +{ + sed '/^#endif.*_CONFIG_H/d' ${top_builddir}/config.h + sed '1,/#define *COMPAT_H_GUARD/d + /^#endif .* COMPAT_H_GUARD/{ + s/COMPAT_H_GUARD/AUTOGEN_CONFIG_H/ + q + }' ${top_srcdir}/compat/compat.h +} > ./${testname}-config.h + +echo ${AG_L} ${testname}.def +${AG_L} ${testname}.def || \ + failure AutoGen could not process + +sedcmd='' +HOME=${TMPDIR} compile "-h" +${SED} 1d ${testname}.help > ${testname}.$$ +mv -f ${testname}.$$ ${testname}.help + +clean_help > ${testname}.hlp <<_EOF_ +Usage: ${testname} [ - [] ]... [ ] +The following options select definitions, templates and scheme functions +to use: + -L str Search for templates in DIR + - may appear multiple times + -T str Use TPL-FILE for the template + - may not be preset + -m Do not use in-mem streams +The following options modify how output is handled: + -b str Specify NAME as the base name for output + - may not be preset +The following options are often useful while debugging new templates: + -t num Limit server shell operations to SECONDS + - it must be in the range: + 0 to 3600 + --- show-defs This option has been disabled + -C Leave a core dump on a failure exit +These options can be used to control what gets processed in the +definitions files and template files: + -s str Skip the file with this SUFFIX + - prohibits the option 'select-suffix' + - may not be preset + - may appear multiple times + -o str specify this output suffix + - may not be preset + - may appear multiple times + -D str name to add to definition list + - may appear multiple times + -U str definition list removal pattern + - an alternate for 'define' +This option is used to automate dependency tracking: + -M [arg] emit make dependency file + - may not be preset + - may appear multiple times +help, version, option and error handling: +Version, usage and configuration options: + -R str reset an option's state + -v [arg] output version information and exit + -h display extended usage information and exit + -! extended usage information passed thru pager + -u abbreviated usage to stdout + -S [arg] save the option state to a config file + -P str load options from a config file + - disabled as '--no-load-opts' + - may appear multiple times +The next option supports vendor supported extra options: + -W str vendor supported additional options + These additional options are: + definitions=str Read definitions from FILE + - disabled as '--no-definitions' + - enabled by default + - may not be preset + shell=str name or path name of shell to use + equate=str characters considered equivalent + source-time set mod times to latest source + - disabled as '--no-source-time' + writable Allow output files to be writable + - disabled as '--not-writable' + loop-limit=num Limit on increment loops + - is scalable with a suffix: k/K/m/M/g/G/t/T + - it must lie in one of the ranges: + -1 exactly, or + 1 to 16777216 + trace=KWd tracing level of detail + trace-out=str tracing output file or filter + used-defines Show the definitions used + - may not be preset + no-abort Do not abort on errors +${testname} creates text files from templates using external definitions. + +The following option preset mechanisms are supported: + - reading file \$HOME/.${testname}rc + - reading file ./.${testname}rc + - examining environment variables named VENDOR_* + +The valid "trace" option keywords are: + nothing debug-message server-shell templates block-macros + expressions everything + or an integer from 0 through 6 + +${testname} is a tool designed for generating program files that contain +repetitive text with varied substitutions. +_EOF_ + +pair="${testname}.hlp ${testname}.help" +cmp -s ${pair} || \ + failure "vendor help mismatch$nl`diff $pair`" + +cleanup diff --git a/autoopts/test/vers.test b/autoopts/test/vers.test new file mode 100755 index 0000000..d498de8 --- /dev/null +++ b/autoopts/test/vers.test @@ -0,0 +1,106 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# ---------------------------------------------------------------------- +# vers.test --- test vers program attribute +# make sure that when it is not specified +# then option processing consumes all args. +# +# Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd +## +# ---------------------------------------------------------------------- + +. ./defs + +# # # # # # # # # # DEFINITIONS FILE # # # # # # # # # + +echo "creating $testname.def in `pwd`" +testname="$testname" test_main="${test_main}" \ +argument="${argument}" long_opts="${long_opts}" \ +${SHELLX} ${stdopts} option second || failure "Could not construct stdopts" +echo 'help-value = h;' >> $testname.def +echo 'version-value = V;' >> $testname.def + +echo ${AG_L} $testname.def +${AG_L} $testname.def || \ + failure AutoGen could not process + +compile "-h" + + +# # # # # # # # # # HELP OUTPUT FILE # # # # # # # # # + +echo creating $testname.hlp +clean_help > $testname.hlp <<'_EOF_' +test_vers - Test AutoOpts for vers +Usage: vers [ - ]... + Flg Arg Option-Name Description + -o no option The option option descrip + -s no second The second option descrip + -h no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + +_EOF_ + +cmp -s $testname.h*lp || \ + failure help output mismatch + +./$testname -v 2> /dev/null && \ + failure $testname should not accept version option + +ver="`echo '$Revision: 4.8 $'|${SED} 's/.*: *\([0-9.a-z]*\).*/\1/'`" +echo "version = '$ver';" >> $testname.def + +echo ${AG_L} $testname.def +${AG_L} $testname.def || \ + failure AutoGen could not process + +compile "-h" + +./$testname -V 2> /dev/null || \ + failure "$testname '*SHOULD*' accept version option" + +echo recreating $testname.hlp +clean_help > $testname.hlp <<_EOF_ +test_vers - Test AutoOpts for vers - Ver. ${ver} +Usage: vers [ - ]... + Flg Arg Option-Name Description + -o no option The option option descrip + -s no second The second option descrip + -V opt version output version information and exit + -h no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + +_EOF_ + +cmp -s $testname.h*lp || \ + failure versioned help output mismatch + +cleanup + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## End: + +# end of vers.test diff --git a/autoopts/text_mmap.c b/autoopts/text_mmap.c new file mode 100644 index 0000000..1109308 --- /dev/null +++ b/autoopts/text_mmap.c @@ -0,0 +1,382 @@ +/** + * @file text_mmap.c + * + * Map a text file, ensuring the text always has an ending NUL byte. + * + * @addtogroup autoopts + * @{ + */ +/* + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ +#if defined(HAVE_MMAP) +# ifndef MAP_ANONYMOUS +# ifdef MAP_ANON +# define MAP_ANONYMOUS MAP_ANON +# endif +# endif + +# if ! defined(MAP_ANONYMOUS) && ! defined(HAVE_DEV_ZERO) + /* + * We must have either /dev/zero or anonymous mapping for + * this to work. + */ +# undef HAVE_MMAP + +# else +# ifdef _SC_PAGESIZE +# define GETPAGESIZE() sysconf(_SC_PAGESIZE) +# else +# define GETPAGESIZE() getpagesize() +# endif +# endif +#endif + +/* + * Some weird systems require that a specifically invalid FD number + * get passed in as an argument value. Which value is that? Well, + * as everybody knows, if open(2) fails, it returns -1, so that must + * be the value. :) + */ +#define AO_INVALID_FD -1 + +#define FILE_WRITABLE(_prt,_flg) \ + ( (_prt & PROT_WRITE) \ + && ((_flg & (MAP_SHARED|MAP_PRIVATE)) == MAP_SHARED)) +#define MAP_FAILED_PTR (VOIDP(MAP_FAILED)) + +/** + * Load the contents of a text file. There are two separate implementations, + * depending up on whether mmap(3) is available. + * + * If not available, malloc the file length plus one byte. Read it in + * and NUL terminate. + * + * If available, first check to see if the text file size is a multiple of a + * page size. If it is, map the file size plus an extra page from either + * anonymous memory or from /dev/zero. Then map the file text on top of the + * first pages of the anonymous/zero pages. Otherwise, just map the file + * because there will be NUL bytes provided at the end. + * + * @param mapinfo a structure holding everything we need to know + * about the mapping. + * + * @param pzFile name of the file, for error reporting. + */ +static void +load_text_file(tmap_info_t * mapinfo, char const * pzFile) +{ +#if ! defined(HAVE_MMAP) + mapinfo->txt_data = AGALOC(mapinfo->txt_size+1, "file text"); + if (mapinfo->txt_data == NULL) { + mapinfo->txt_errno = ENOMEM; + return; + } + + { + size_t sz = mapinfo->txt_size; + char * pz = mapinfo->txt_data; + + while (sz > 0) { + ssize_t rdct = read(mapinfo->txt_fd, pz, sz); + if (rdct <= 0) { + mapinfo->txt_errno = errno; + fserr_warn("libopts", "read", pzFile); + free(mapinfo->txt_data); + return; + } + + pz += rdct; + sz -= rdct; + } + + *pz = NUL; + } + + mapinfo->txt_errno = 0; + +#else /* HAVE mmap */ + size_t const pgsz = (size_t)GETPAGESIZE(); + void * map_addr = NULL; + + (void)pzFile; + + mapinfo->txt_full_size = (mapinfo->txt_size + pgsz) & ~(pgsz - 1); + if (mapinfo->txt_full_size == (mapinfo->txt_size + pgsz)) { + /* + * The text is a multiple of a page boundary. We must map an + * extra page so the text ends with a NUL. + */ +#if defined(MAP_ANONYMOUS) + map_addr = mmap(NULL, mapinfo->txt_full_size, PROT_READ|PROT_WRITE, + MAP_ANONYMOUS|MAP_PRIVATE, AO_INVALID_FD, 0); +#else + mapinfo->txt_zero_fd = open("/dev/zero", O_RDONLY); + + if (mapinfo->txt_zero_fd == AO_INVALID_FD) { + mapinfo->txt_errno = errno; + return; + } + map_addr = mmap(NULL, mapinfo->txt_full_size, PROT_READ|PROT_WRITE, + MAP_PRIVATE, mapinfo->txt_zero_fd, 0); +#endif + if (map_addr == MAP_FAILED_PTR) { + mapinfo->txt_errno = errno; + return; + } + mapinfo->txt_flags |= MAP_FIXED; + } + + mapinfo->txt_data = + mmap(map_addr, mapinfo->txt_size, mapinfo->txt_prot, + mapinfo->txt_flags, mapinfo->txt_fd, 0); + + if (mapinfo->txt_data == MAP_FAILED_PTR) + mapinfo->txt_errno = errno; +#endif /* HAVE_MMAP */ +} + +/** + * Make sure all the parameters are correct: we have a file name that + * is a text file that we can read. + * + * @param fname the text file to map + * @param prot the memory protections requested (read/write/etc.) + * @param flags mmap flags + * @param mapinfo a structure holding everything we need to know + * about the mapping. + */ +static void +validate_mmap(char const * fname, int prot, int flags, tmap_info_t * mapinfo) +{ + memset(mapinfo, 0, sizeof(*mapinfo)); +#if defined(HAVE_MMAP) && ! defined(MAP_ANONYMOUS) + mapinfo->txt_zero_fd = AO_INVALID_FD; +#endif + mapinfo->txt_fd = AO_INVALID_FD; + mapinfo->txt_prot = prot; + mapinfo->txt_flags = flags; + + /* + * Map mmap flags and protections into open flags and do the open. + */ + { + /* + * See if we will be updating the file. If we can alter the memory + * and if we share the data and we are *not* copy-on-writing the data, + * then our updates will show in the file, so we must open with + * write access. + */ + int o_flag = +#ifdef _WIN32 + O_BINARY | +#endif + FILE_WRITABLE(prot, flags) ? O_RDWR : O_RDONLY; + + /* + * If you're not sharing the file and you are writing to it, + * then don't let anyone else have access to the file. + */ + if (((flags & MAP_SHARED) == 0) && (prot & PROT_WRITE)) + o_flag |= O_EXCL; + + mapinfo->txt_fd = open(fname, o_flag); + if (mapinfo->txt_fd < 0) { + mapinfo->txt_errno = errno; + mapinfo->txt_fd = AO_INVALID_FD; + return; + } + } + + /* + * Make sure we can stat the regular file. Save the file size. + */ + { + struct stat sb; + if (fstat(mapinfo->txt_fd, &sb) != 0) { + mapinfo->txt_errno = errno; + close(mapinfo->txt_fd); + return; + } + + if (! S_ISREG(sb.st_mode)) { + mapinfo->txt_errno = errno = EINVAL; + close(mapinfo->txt_fd); + return; + } + + mapinfo->txt_size = (size_t)sb.st_size; + } + + if (mapinfo->txt_fd == AO_INVALID_FD) + mapinfo->txt_errno = errno; +} + +/** + * Close any files opened by the mapping. + * + * @param mi a structure holding everything we need to know about the map. + */ +static void +close_mmap_files(tmap_info_t * mi) +{ + if (mi->txt_fd == AO_INVALID_FD) + return; + + close(mi->txt_fd); + mi->txt_fd = AO_INVALID_FD; + +#if defined(HAVE_MMAP) && ! defined(MAP_ANONYMOUS) + if (mi->txt_zero_fd == AO_INVALID_FD) + return; + + close(mi->txt_zero_fd); + mi->txt_zero_fd = AO_INVALID_FD; +#endif +} + +/*=export_func text_mmap + * private: + * + * what: map a text file with terminating NUL + * + * arg: char const *, pzFile, name of the file to map + * arg: int, prot, mmap protections (see mmap(2)) + * arg: int, flags, mmap flags (see mmap(2)) + * arg: tmap_info_t *, mapinfo, returned info about the mapping + * + * ret-type: void * + * ret-desc: The mmaped data address + * + * doc: + * + * This routine will mmap a file into memory ensuring that there is at least + * one @file{NUL} character following the file data. It will return the + * address where the file contents have been mapped into memory. If there is a + * problem, then it will return @code{MAP_FAILED} and set @code{errno} + * appropriately. + * + * The named file does not exist, @code{stat(2)} will set @code{errno} as it + * will. If the file is not a regular file, @code{errno} will be + * @code{EINVAL}. At that point, @code{open(2)} is attempted with the access + * bits set appropriately for the requested @code{mmap(2)} protections and flag + * bits. On failure, @code{errno} will be set according to the documentation + * for @code{open(2)}. If @code{mmap(2)} fails, @code{errno} will be set as + * that routine sets it. If @code{text_mmap} works to this point, a valid + * address will be returned, but there may still be ``issues''. + * + * If the file size is not an even multiple of the system page size, then + * @code{text_map} will return at this point and @code{errno} will be zero. + * Otherwise, an anonymous map is attempted. If not available, then an attempt + * is made to @code{mmap(2)} @file{/dev/zero}. If any of these fail, the + * address of the file's data is returned, bug @code{no} @file{NUL} characters + * are mapped after the end of the data. + * + * see: mmap(2), open(2), stat(2) + * + * err: Any error code issued by mmap(2), open(2), stat(2) is possible. + * Additionally, if the specified file is not a regular file, then + * errno will be set to @code{EINVAL}. + * + * example: + * #include + * tmap_info_t mi; + * int no_nul; + * void * data = text_mmap("file", PROT_WRITE, MAP_PRIVATE, &mi); + * if (data == MAP_FAILED) return; + * no_nul = (mi.txt_size == mi.txt_full_size); + * << use the data >> + * text_munmap(&mi); +=*/ +void * +text_mmap(char const * pzFile, int prot, int flags, tmap_info_t * mi) +{ + validate_mmap(pzFile, prot, flags, mi); + if (mi->txt_errno != 0) + return MAP_FAILED_PTR; + + load_text_file(mi, pzFile); + + if (mi->txt_errno == 0) + return mi->txt_data; + + close_mmap_files(mi); + + errno = mi->txt_errno; + mi->txt_data = MAP_FAILED_PTR; + return mi->txt_data; +} + + +/*=export_func text_munmap + * private: + * + * what: unmap the data mapped in by text_mmap + * + * arg: tmap_info_t *, mapinfo, info about the mapping + * + * ret-type: int + * ret-desc: -1 or 0. @code{errno} will have the error code. + * + * doc: + * + * This routine will unmap the data mapped in with @code{text_mmap} and close + * the associated file descriptors opened by that function. + * + * see: munmap(2), close(2) + * + * err: Any error code issued by munmap(2) or close(2) is possible. +=*/ +int +text_munmap(tmap_info_t * mi) +{ + errno = 0; + +#ifdef HAVE_MMAP + (void)munmap(mi->txt_data, mi->txt_full_size); + +#else // don't HAVE_MMAP + /* + * IF the memory is writable *AND* it is not private (copy-on-write) + * *AND* the memory is "sharable" (seen by other processes) + * THEN rewrite the data. Emulate mmap visibility. + */ + if ( FILE_WRITABLE(mi->txt_prot, mi->txt_flags) + && (lseek(mi->txt_fd, 0, SEEK_SET) >= 0) ) + write(mi->txt_fd, mi->txt_data, mi->txt_size); + + free(mi->txt_data); +#endif /* HAVE_MMAP */ + + mi->txt_errno = errno; + close_mmap_files(mi); + + return mi->txt_errno; +} + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/text_mmap.c */ diff --git a/autoopts/time.c b/autoopts/time.c new file mode 100644 index 0000000..debaa7a --- /dev/null +++ b/autoopts/time.c @@ -0,0 +1,145 @@ + +/** + * \file time.c + * + * @addtogroup autoopts + * @{ + */ +/* + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +/*=export_func optionTimeVal + * private: + * + * what: process an option with a time duration. + * arg: + tOptions * + opts + program options descriptor + + * arg: + tOptDesc * + od + the descriptor for this arg + + * + * doc: + * Decipher a time duration value. +=*/ +void +optionTimeVal(tOptions * opts, tOptDesc * od) +{ + time_t val; + + if (INQUERY_CALL(opts, od)) + return; + + val = parse_duration(od->optArg.argString); + if (val == BAD_TIME) { + fprintf(stderr, zNotDuration, opts->pzProgName, od->optArg.argString); + if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0) + (*(opts->pUsageProc))(opts, EXIT_FAILURE); + } + + if (od->fOptState & OPTST_ALLOC_ARG) { + AGFREE(od->optArg.argString); + od->fOptState &= ~OPTST_ALLOC_ARG; + } + + od->optArg.argInt = (long)val; +} + +/*=export_func optionTimeDate + * private: + * + * what: process an option with a time and date. + * arg: + tOptions * + opts + program options descriptor + + * arg: + tOptDesc * + od + the descriptor for this arg + + * + * doc: + * Decipher a time and date value. +=*/ +void +optionTimeDate(tOptions * opts, tOptDesc * od) +{ +#if defined(HAVE_GETDATE_R) && defined(HAVE_PUTENV) + if (INQUERY_CALL(opts, od)) + return; + + if ((! HAS_pzPkgDataDir(opts)) || (opts->pzPkgDataDir == NULL)) + goto default_action; + + /* + * Export the DATEMSK environment variable. getdate_r() uses it to + * find the file with the strptime formats. If we cannot find the file + * we need ($PKGDATADIR/datemsk), then fall back to just a time duration. + */ + { + static char * envptr = NULL; + + if (envptr == NULL) { + static char const fmt[] = "DATEMSK=%s/datemsk"; + size_t sz = sizeof(fmt) + strlen(opts->pzPkgDataDir); + envptr = AGALOC(sz, fmt); + if (snprintf(envptr, sz, fmt, opts->pzPkgDataDir) >= (int)sz) + option_exits(EXIT_FAILURE); + + putenv(envptr); + } + + if (access(envptr+8, R_OK) != 0) + goto default_action; + } + + /* + * Convert the date to a time since the epoch and stash it in a long int. + */ + { + struct tm stm; + time_t tm; + + if (getdate_r(od->optArg.argString, &stm) != 0) { + fprintf(stderr, zNotDate, opts->pzProgName, + od->optArg.argString); + if ((opts->fOptSet & OPTPROC_ERRSTOP) != 0) + (*(opts->pUsageProc))(opts, EXIT_FAILURE); + return; + } + + tm = mktime(&stm); + + if (od->fOptState & OPTST_ALLOC_ARG) { + AGFREE(od->optArg.argString); + od->fOptState &= ~OPTST_ALLOC_ARG; + } + + od->optArg.argInt = tm; + } + return; + + default_action: + +#endif + optionTimeVal(opts, od); + if (od->optArg.argInt != BAD_TIME) + od->optArg.argInt += (long)time(NULL); +} +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/time.c */ diff --git a/autoopts/tokenize.c b/autoopts/tokenize.c new file mode 100644 index 0000000..7489e3d --- /dev/null +++ b/autoopts/tokenize.c @@ -0,0 +1,322 @@ +/** \file tokenize.c + * + * Tokenize a string, accommodating quoted strings. + * + * @addtogroup autoopts + * @{ + */ +/* + * This file defines the string_tokenize interface + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +static void +copy_cooked(ch_t ** ppDest, char const ** ppSrc) +{ + ch_t * pDest = (ch_t *)*ppDest; + const ch_t * pSrc = (const ch_t *)(*ppSrc + 1); + + for (;;) { + ch_t ch = *(pSrc++); + switch (ch) { + case NUL: *ppSrc = NULL; return; + case '"': goto done; + case '\\': + pSrc += ao_string_cook_escape_char((char *)pSrc, (char *)&ch, 0x7F); + if (ch == 0x7F) + break; + /* FALLTHROUGH */ + + default: + *(pDest++) = ch; + } + } + + done: + *ppDest = (ch_t *)pDest; /* next spot for storing character */ + *ppSrc = (char const *)pSrc; /* char following closing quote */ +} + + +static void +copy_raw(ch_t ** ppDest, char const ** ppSrc) +{ + ch_t * pDest = *ppDest; + cc_t * pSrc = (cc_t *) (*ppSrc + 1); + + for (;;) { + ch_t ch = *(pSrc++); + switch (ch) { + case NUL: *ppSrc = NULL; return; + case '\'': goto done; + case '\\': + /* + * *Four* escapes are handled: newline removal, escape char + * quoting and apostrophe quoting + */ + switch (*pSrc) { + case NUL: *ppSrc = NULL; return; + case '\r': + if (*(++pSrc) == NL) + ++pSrc; + continue; + + case NL: + ++pSrc; + continue; + + case '\'': + ch = '\''; + /* FALLTHROUGH */ + + case '\\': + ++pSrc; + break; + } + /* FALLTHROUGH */ + + default: + *(pDest++) = ch; + } + } + + done: + *ppDest = pDest; /* next spot for storing character */ + *ppSrc = (char const *) pSrc; /* char following closing quote */ +} + +static token_list_t * +alloc_token_list(char const * str) +{ + token_list_t * res; + + int max_token_ct = 2; /* allow for trailing NULL pointer & NUL on string */ + + if (str == NULL) goto enoent_res; + + /* + * Trim leading white space. Use "ENOENT" and a NULL return to indicate + * an empty string was passed. + */ + str = SPN_WHITESPACE_CHARS(str); + if (*str == NUL) goto enoent_res; + + /* + * Take an approximate count of tokens. If no quoted strings are used, + * it will be accurate. If quoted strings are used, it will be a little + * high and we'll squander the space for a few extra pointers. + */ + { + char const * pz = str; + + do { + max_token_ct++; + pz = BRK_WHITESPACE_CHARS(pz+1); + pz = SPN_WHITESPACE_CHARS(pz); + } while (*pz != NUL); + + res = malloc(sizeof(*res) + (size_t)(pz - str) + + ((size_t)max_token_ct * sizeof(ch_t *))); + } + + if (res == NULL) + errno = ENOMEM; + else res->tkn_list[0] = (ch_t *)(res->tkn_list + (max_token_ct - 1)); + + return res; + + enoent_res: + + errno = ENOENT; + return NULL; +} + +/*=export_func ao_string_tokenize + * + * what: tokenize an input string + * + * arg: + char const * + string + string to be tokenized + + * + * ret_type: token_list_t * + * ret_desc: pointer to a structure that lists each token + * + * doc: + * + * This function will convert one input string into a list of strings. + * The list of strings is derived by separating the input based on + * white space separation. However, if the input contains either single + * or double quote characters, then the text after that character up to + * a matching quote will become the string in the list. + * + * The returned pointer should be deallocated with @code{free(3C)} when + * are done using the data. The data are placed in a single block of + * allocated memory. Do not deallocate individual token/strings. + * + * The structure pointed to will contain at least these two fields: + * @table @samp + * @item tkn_ct + * The number of tokens found in the input string. + * @item tok_list + * An array of @code{tkn_ct + 1} pointers to substring tokens, with + * the last pointer set to NULL. + * @end table + * + * There are two types of quoted strings: single quoted (@code{'}) and + * double quoted (@code{"}). Singly quoted strings are fairly raw in that + * escape characters (@code{\\}) are simply another character, except when + * preceding the following characters: + * @example + * @code{\\} double backslashes reduce to one + * @code{'} incorporates the single quote into the string + * @code{\n} suppresses both the backslash and newline character + * @end example + * + * Double quote strings are formed according to the rules of string + * constants in ANSI-C programs. + * + * example: + * @example + * #include + * int ix; + * token_list_t * ptl = ao_string_tokenize(some_string) + * for (ix = 0; ix < ptl->tkn_ct; ix++) + * do_something_with_tkn(ptl->tkn_list[ix]); + * free(ptl); + * @end example + * Note that everything is freed with the one call to @code{free(3C)}. + * + * err: + * NULL is returned and @code{errno} will be set to indicate the problem: + * @itemize @bullet + * @item + * @code{EINVAL} - There was an unterminated quoted string. + * @item + * @code{ENOENT} - The input string was empty. + * @item + * @code{ENOMEM} - There is not enough memory. + * @end itemize +=*/ +token_list_t * +ao_string_tokenize(char const * str) +{ + token_list_t * res = alloc_token_list(str); + ch_t * pzDest; + + /* + * Now copy each token into the output buffer. + */ + if (res == NULL) + return res; + + pzDest = (ch_t *)(res->tkn_list[0]); + res->tkn_ct = 0; + + do { + res->tkn_list[ res->tkn_ct++ ] = pzDest; + for (;;) { + int ch = (ch_t)*str; + if (IS_WHITESPACE_CHAR(ch)) { + found_white_space: + str = SPN_WHITESPACE_CHARS(str+1); + break; + } + + switch (ch) { + case '"': + copy_cooked(&pzDest, &str); + if (str == NULL) { + free(res); + errno = EINVAL; + return NULL; + } + if (IS_WHITESPACE_CHAR(*str)) + goto found_white_space; + break; + + case '\'': + copy_raw(&pzDest, &str); + if (str == NULL) { + free(res); + errno = EINVAL; + return NULL; + } + if (IS_WHITESPACE_CHAR(*str)) + goto found_white_space; + break; + + case NUL: + goto copy_done; + + default: + str++; + *(pzDest++) = (unsigned char)ch; + } + } copy_done:; + + /* + * NUL terminate the last token and see if we have any more tokens. + */ + *(pzDest++) = NUL; + } while (*str != NUL); + + res->tkn_list[ res->tkn_ct ] = NULL; + + return res; +} + +#ifdef TEST +#include +#include + +int +main(int argc, char ** argv) +{ + if (argc == 1) { + printf("USAGE: %s arg [ ... ]\n", *argv); + return 1; + } + while (--argc > 0) { + char * arg = *(++argv); + token_list_t * p = ao_string_tokenize(arg); + if (p == NULL) { + printf("Parsing string ``%s'' failed:\n\terrno %d (%s)\n", + arg, errno, strerror(errno)); + } else { + int ix = 0; + printf("Parsed string ``%s''\ninto %d tokens:\n", arg, p->tkn_ct); + do { + printf(" %3d: ``%s''\n", ix+1, p->tkn_list[ix]); + } while (++ix < p->tkn_ct); + free(p); + } + } + return 0; +} +#endif + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/tokenize.c */ diff --git a/autoopts/tpl/Mdoc.pm b/autoopts/tpl/Mdoc.pm new file mode 100644 index 0000000..4638526 --- /dev/null +++ b/autoopts/tpl/Mdoc.pm @@ -0,0 +1,542 @@ +=begin comment + +## Mdoc.pm -- Perl functions for mdoc processing +## +## Author: Oliver Kindernay (GSoC project for NTP.org) +## +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd +=end comment +=head1 NAME + +Mdoc - perl module to parse Mdoc macros + +=head1 SYNOPSIS + + use Mdoc qw(ns pp soff son stoggle mapwords); + +See mdoc2man and mdoc2texi for code examples. + +=head1 FUNCTIONS + +=over 4 + +=item def_macro( NAME, CODE, [ raw => 1, greedy => 1, concat_until => '.Xx' ] ) + +Define new macro. The CODE reference will be called by call_macro(). You can +have two distinct definitions for and inline macro and for a standalone macro +(i. e. 'Pa' and '.Pa'). + +The CODE reference is passed a list of arguments and is expected to return list +of strings and control characters (see C). + +By default the surrouding "" from arguments to macros are removed, use C +to disable this. + +Normaly CODE reference is passed all arguments up to next nested macro. Set +C to to pass everything up to the end of the line. + +If the concat_until is present, the line is concated until the .Xx macro is +found. For example the following macro definition + + def_macro('.Oo', gen_encloser(qw([ ]), concat_until => '.Oc' } + def_macro('.Cm', sub { mapwords {'($_)'} @_ } } + +and the following input + + .Oo + .Cm foo | + .Cm bar | + .Oc + +results in [(foo) | (bar)] + +=item get_macro( NAME ) + +Returns a hash reference like: + + { run => CODE, raw => [1|0], greedy => [1|0] } + +Where C is the CODE reference used to define macro called C + +=item parse_line( INPUT, OUTPUT_CODE, PREPROCESS_CODE ) + +Parse a line from the C filehandle. If a macro was detected it returns a +list (MACRO_NAME, @MACRO_ARGS), otherwise it calls the C, giving +caller a chance to modify line before printing it. If C is +defined it calls it prior to passing argument to a macro, giving caller a +chance to alter them. if EOF was reached undef is returned. + +=item call_macro( MACRO, ARGS, ... ) + +Call macro C with C. The CODE reference for macro C is +called and for all the nested macros. Every called macro returns a list which +is appended to return value and returned when all nested macros are processed. +Use to_string() to produce a printable string from the list. + +=item to_string ( LIST ) + +Processes C returned from call_macro() and returns formatted string. + +=item mapwords BLOCK ARRAY + +This is like perl's map only it calls BLOCK only on elements which are not +punctuation or control characters. + +=item space ( ['on'|'off] ) + +Turn spacing on or off. If called without argument it returns the current state. + +=item gen_encloser ( START, END ) + +Helper function for generating macros that enclose their arguments. + gen_encloser(qw({ })); +returns + sub { '{', ns, @_, ns, pp('}')} + +=item set_Bl_callback( CODE , DEFS ) + +This module implements the Bl/El macros for you. Using set_Bl_callback you can +provide a macro definition that should be executed on a .Bl call. + +=item set_El_callback( CODE , DEFS ) + +This module implements the Bl/El macros for you. Using set_El_callback you can +provide a macro definition that should be executed on a .El call. + +=item set_Re_callback( CODE ) + +The C is called after a Rs/Re block is done. With a hash reference as a +parameter, describing the reference. + +=back + +=head1 CONSTANTS + +=over 4 + +=item ns + +Indicate 'no space' between to members of the list. + +=item pp ( STRING ) + +The string is 'punctuation point'. It means that every punctuation +preceeding that element is put behind it. + +=item soff + +Turn spacing off. + +=item son + +Turn spacing on. + +=item stoggle + +Toogle spacing. + +=item hs + +Print space no matter spacing mode. + +=back + +=head1 TODO + +* The concat_until only works with standalone macros. This means that + .Po blah Pc +will hang until .Pc in encountered. + +* Provide default macros for Bd/Ed + +* The reference implementation is uncomplete + +=cut + +package Mdoc; +use strict; +use warnings; +use List::Util qw(reduce); +use Text::ParseWords qw(quotewords); +use Carp; +use Exporter qw(import); +our @EXPORT_OK = qw(ns pp soff son stoggle hs mapwords gen_encloser nl); + +use constant { + ns => ['nospace'], + soff => ['spaceoff'], + son => ['spaceon'], + stoggle => ['spacetoggle'], + hs => ['hardspace'], +}; + +sub pp { + my $c = shift; + return ['pp', $c ]; +} +sub gen_encloser { + my ($o, $c) = @_; + return sub { ($o, ns, @_, ns, pp($c)) }; +} + +sub mapwords(&@) { + my ($f, @l) = @_; + my @res; + for my $el (@l) { + local $_ = $el; + push @res, $el =~ /^(?:[,\.\{\}\(\):;\[\]\|])$/ || ref $el eq 'ARRAY' ? + $el : $f->(); + } + return @res; +} + +my %macros; + +############################################################################### + +# Default macro definitions start + +############################################################################### + +def_macro('Xo', sub { @_ }, concat_until => '.Xc'); + +def_macro('.Ns', sub {ns, @_}); +def_macro('Ns', sub {ns, @_}); + +{ + my %reference; + def_macro('.Rs', sub { () } ); + def_macro('.%A', sub { + if ($reference{authors}) { + $reference{authors} .= " and @_" + } + else { + $reference{authors} = "@_"; + } + return (); + }); + def_macro('.%T', sub { $reference{title} = "@_"; () } ); + def_macro('.%O', sub { $reference{optional} = "@_"; () } ); + + sub set_Re_callback { + my ($sub) = @_; + croak 'Not a CODE reference' if not ref $sub eq 'CODE'; + def_macro('.Re', sub { + my @ret = $sub->(\%reference); + %reference = (); @ret + }); + return; + } +} + +def_macro('.Bl', sub { die '.Bl - no list callback set' }); +def_macro('.It', sub { die ".It called outside of list context - maybe near line $." }); +def_macro('.El', sub { die '.El requires .Bl first' }); + + +{ + my $elcb = sub { () }; + + sub set_El_callback { + my ($sub) = @_; + croak 'Not a CODE reference' if ref $sub ne 'CODE'; + $elcb = $sub; + return; + } + + sub set_Bl_callback { + my ($blcb, %defs) = @_; + croak 'Not a CODE reference' if ref $blcb ne 'CODE'; + def_macro('.Bl', sub { + + my $orig_it = get_macro('.It'); + my $orig_el = get_macro('.El'); + my $orig_bl = get_macro('.Bl'); + my $orig_elcb = $elcb; + + # Restore previous .It and .El on each .El + def_macro('.El', sub { + def_macro('.El', delete $orig_el->{run}, %$orig_el); + def_macro('.It', delete $orig_it->{run}, %$orig_it); + def_macro('.Bl', delete $orig_bl->{run}, %$orig_bl); + my @ret = $elcb->(@_); + $elcb = $orig_elcb; + @ret + }); + $blcb->(@_) + }, %defs); + return; + } +} + +def_macro('.Sm', sub { + my ($arg) = @_; + if (defined $arg) { + space($arg); + } else { + space() eq 'off' ? + space('on') : + space('off'); + } + () +} ); +def_macro('Sm', do { my $off; sub { + my ($arg) = @_; + if (defined $arg && $arg =~ /^(on|off)$/) { + shift; + if ($arg eq 'off') { soff, @_; } + elsif ($arg eq 'on') { son, @_; } + } + else { + stoggle, @_; + } +}} ); + +############################################################################### + +# Default macro definitions end + +############################################################################### + +sub def_macro { + croak 'Odd number of elements for hash argument <'.(scalar @_).'>' if @_%2; + my ($macro, $sub, %def) = @_; + croak 'Not a CODE reference' if ref $sub ne 'CODE'; + + $macros{ $macro } = { + run => $sub, + greedy => delete $def{greedy} || 0, + raw => delete $def{raw} || 0, + concat_until => delete $def{concat_until}, + }; + if ($macros{ $macro }{concat_until}) { + $macros{ $macros{ $macro }{concat_until} } = { run => sub { @_ } }; + $macros{ $macro }{greedy} = 1; + } + return; +} + +sub get_macro { + my ($macro) = @_; + croak "Macro <$macro> not defined" if not exists $macros{ $macro }; + +{ %{ $macros{ $macro } } } +} + +#TODO: document this +sub parse_opts { + my %args; + my $last; + for (@_) { + if ($_ =~ /^\\?-/) { + s/^\\?-//; + $args{$_} = 1; + $last = _unquote($_); + } + else { + $args{$last} = _unquote($_) if $last; + undef $last; + } + } + return %args; +} + +sub _is_control { + my ($el, $expected) = @_; + if (defined $expected) { + ref $el eq 'ARRAY' and $el->[0] eq $expected; + } + else { + ref $el eq 'ARRAY'; + } +} + +{ + my $sep = ' '; + + sub to_string { + if (@_ > 0) { + # Handle punctunation + my ($in_brace, @punct) = ''; + my @new = map { + if (/^([\[\(])$/) { + ($in_brace = $1) =~ tr/([/)]/; + $_, ns + } + elsif (/^([\)\]])$/ && $in_brace eq $1) { + $in_brace = ''; + ns, $_ + } + elsif ($_ =~ /^[,\.;:\?\!\)\]]$/) { + push @punct, ns, $_; + (); + } + elsif (_is_control($_, 'pp')) { + $_->[1] + } + elsif (_is_control($_)) { + $_ + } + else { + splice (@punct), $_; + } + } @_; + push @new, @punct; + + # Produce string out of an array dealing with the special control characters + # space('off') must but one character delayed + my ($no_space, $space_off) = 1; + my $res = ''; + while (defined(my $el = shift @new)) { + if (_is_control($el, 'hardspace')) { $no_space = 1; $res .= ' ' } + elsif (_is_control($el, 'nospace')) { $no_space = 1; } + elsif (_is_control($el, 'spaceoff')) { $space_off = 1; } + elsif (_is_control($el, 'spaceon')) { space('on'); } + elsif (_is_control($el, 'spacetoggle')) { space() eq 'on' ? + $space_off = 1 : + space('on') } + else { + if ($no_space) { + $no_space = 0; + $res .= "$el" + } + else { + $res .= "$sep$el" + } + + if ($space_off) { space('off'); $space_off = 0; } + } + } + $res + } + else { + ''; + } + } + + sub space { + my ($arg) = @_; + if (defined $arg && $arg =~ /^(on|off)$/) { + $sep = ' ' if $arg eq 'on'; + $sep = '' if $arg eq 'off'; + return; + } + else { + return $sep eq '' ? 'off' : 'on'; + } + } +} + +sub _unquote { + my @args = @_; + $_ =~ s/^"([^"]+)"$/$1/g for @args; + wantarray ? @args : $args[0]; +} + +sub call_macro { + my ($macro, @args) = @_; + my @ret; + + my @newargs; + my $i = 0; + + @args = _unquote(@args) if (!$macros{ $macro }{raw}); + + # Call any callable macros in the argument list + for (@args) { + if ($_ =~ /^[A-Z][a-z]+$/ && exists $macros{ $_ }) { + push @ret, call_macro($_, @args[$i+1 .. $#args]); + last; + } else { + if ($macros{ $macro }{greedy}) { + push @ret, $_; + } + else { + push @newargs, $_; + } + } + $i++; + } + + if ($macros{ $macro }{concat_until}) { + my ($n_macro, @n_args) = (''); + while (1) { + die "EOF was reached and no $macros{ $macro }{concat_until} found" + if not defined $n_macro; + ($n_macro, @n_args) = parse_line(undef, sub { push @ret, shift }); + if ($n_macro eq $macros{ $macro }{concat_until}) { + push @ret, call_macro($n_macro, @n_args); + last; + } + else { + $n_macro =~ s/^\.//; + push @ret, call_macro($n_macro, @n_args) if exists $macros{ $n_macro }; + } + } + } + + if ($macros{ $macro }{greedy}) { + #print "MACROG $macro (", (join ', ', @ret), ")\n"; + return $macros{ $macro }{run}->(@ret); + } + else { + #print "MACRO $macro (", (join ', ', @newargs), ")".(join ', ', @ret)."\n"; + return $macros{ $macro }{run}->(@newargs), @ret; + } +} + +{ + my ($in_fh, $out_sub, $preprocess_sub); + sub parse_line { + $in_fh = $_[0] if defined $_[0] || !defined $in_fh; + $out_sub = $_[1] if defined $_[1] || !defined $out_sub; + $preprocess_sub = $_[2] if defined $_[2] || !defined $preprocess_sub; + + croak 'out_sub not a CODE reference' + if not ref $out_sub eq 'CODE'; + croak 'preprocess_sub not a CODE reference' + if defined $preprocess_sub && not ref $preprocess_sub eq 'CODE'; + + while (my $line = <$in_fh>) { + chomp $line; + if ($line =~ /^\.[A-z][a-z0-9]+/ || $line =~ /^\.%[A-Z]/ || + $line =~ /^\.\\"/) + { + $line =~ s/ +/ /g; + my ($macro, @args) = quotewords(' ', 1, $line); + @args = grep { defined $_ } @args; + $preprocess_sub->(@args) if defined $preprocess_sub; + if ($macro && exists $macros{ $macro }) { + return ($macro, @args); + } else { + $out_sub->($line); + } + } + else { + $out_sub->($line); + } + } + return; + } +} + +1; +__END__ diff --git a/autoopts/tpl/aginfo.tpl b/autoopts/tpl/aginfo.tpl new file mode 100644 index 0000000..3c9d478 --- /dev/null +++ b/autoopts/tpl/aginfo.tpl @@ -0,0 +1,12 @@ +[= AutoGen5 template + +texi + +## Copyright (C) 2006-2018 Bruce Korb, all rights reserved. + +=] +[= `echo please note that this is obsolete >&2` =][= + +INCLUDE "agtexi-cmd.tpl" + +\=] diff --git a/autoopts/tpl/aginfo3.tpl b/autoopts/tpl/aginfo3.tpl new file mode 100644 index 0000000..efccb1a --- /dev/null +++ b/autoopts/tpl/aginfo3.tpl @@ -0,0 +1,126 @@ +{+ AutoGen5 template -*- nroff -*- + +texi + +## aginfo3.tpl -- Template for function texi doc +## +## Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + ++}{+ + +(out-push-new (sprintf "%s.menu" (base-name))) +(define lib-name (get "library")) +(if (< (string-length lib-name) 1) + (set! lib-name (base-name)) ) +(define node-name (sprintf "lib%s procedures" lib-name)) +(define sec-name (sprintf "lib%s External Procedures" lib-name)) + +(define doc-level (getenv "LEVEL")) +(if (not (string? doc-level)) + (set! doc-level "section")) +(sprintf "* %-28s %s\n" (string-append node-name "::") sec-name) +}{+ +(out-pop) ++}@node {+ (. node-name) +} +@{+ (. doc-level) +} {+ (. sec-name) +} + +{+ + +IF (not (exist? "lib-description")) + ++}These are the publicly exported procedures from the lib@i{{+(. lib-name)+}} +library. Any other functions mentioned in the @i{header} file are +for the private use of the library.{+ + +ELSE +}{+ lib-description +}{+ +ENDIF +} + +@menu{+ + +FOR export-func +}{+ + IF (not (exist? "private")) +} +* lib{+(sprintf "%-24s" (string-append + lib-name "-" (get "name") "::")) + +} {+name +}{+ + + ENDIF private +}{+ + +ENDFOR export-func +} +@end menu + +This {+(. doc-level)+} was automatically generated by AutoGen +using extracted information and the {+(tpl-file)+} template.{+ + +FOR export-func +}{+ + IF (not (exist? "private")) + ++} + +@node lib{+library+}-{+name+} +@{+CASE (. doc-level)+}{+ + = chapter +}{+ + = section +}sub{+ + = subsection +}subsub{+ + ESAC +}section {+name+} +@findex {+name+} + +{+what+} + +@noindent +Usage: +@example +{+ % ret-type "%s res = " ++}{+name+}({+ + IF (exist? "arg") +} {+ + FOR arg ", " +}{+arg-name+}{+ + ENDFOR +} {+ + ENDIF +}); +@end example{+ + IF (or (exist? "arg") (exist? "ret-type")) +} +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab -------------{+ + FOR arg "\n" +} +@item @tab {+arg-name+} @tab @code{{+arg-type+}} +@tab {+arg-desc+}{+ + ENDFOR+}{+ + IF (exist? "ret-type") +} +@item @tab returns @tab {+ret-type+} +@tab {+ ret-desc +}{+ + + ENDIF +} +@end multitable{+ + + ENDIF ++} + +{+doc+} +{+ % err "\n%s\n" +}{+ + + ENDIF private +}{+ + +ENDFOR export-func + + ++} diff --git a/autoopts/tpl/agman-cmd.tpl b/autoopts/tpl/agman-cmd.tpl new file mode 100644 index 0000000..9a1777b --- /dev/null +++ b/autoopts/tpl/agman-cmd.tpl @@ -0,0 +1,63 @@ +[+: -*- Mode: nroff -*- + + AutoGen5 template man + +## agman-cmd.tpl -- Template for command line man pages +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## Copyright (C) 1992-2018 Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +# Produce a man page for section 1, 5 or 8 commands. +# Which is selected via: -DMAN_SECTION=n +# passed to the autogen invocation. "n" may have a suffix, if desired. +# +:+][+: +(out-push-new) :+] +if test -z "${MAN_PAGE_DATE}" +then LC_ALL=C date '+%d %b %Y' | sed 's/ */ /g' +else echo "${MAN_PAGE_DATE}" +fi +[+: +(define mpage-date (shell (out-pop #t))) + +(define head-line (lambda() + (sprintf ".TH %s %s \"%s\" \"%s\" \"%s\"\n.\\\"\n" + (get "prog-name") man-sect + mpage-date package-text section-name) )) + +(define man-page #t) +(out-push-new) :+][+: + +INCLUDE "cmd-doc.tlib" :+][+: +INVOKE build-doc :+][+: + + (shell (string-append + "fn='" (find-file "mdoc2man") "'\n" + "test -f ${fn} || die mdoc2man not found from $PWD\n" + "${fn} <<\\_EndOfMdoc_ || die ${fn} failed in $PWD\n" + (out-pop #t) + "\n_EndOfMdoc_" )) + +:+][+: + +(out-move (string-append (get "prog-name") "." + man-sect)) :+][+: + +agman-cmd.tpl ends here :+] diff --git a/autoopts/tpl/agman-file.tpl b/autoopts/tpl/agman-file.tpl new file mode 100644 index 0000000..8b6430a --- /dev/null +++ b/autoopts/tpl/agman-file.tpl @@ -0,0 +1,90 @@ +[+: -*- Mode: nroff -*- + + AutoGen5 template man + +## agman-file.tpl -- Template for file man pages +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## Copyright (C) 1992-2018 Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +# Produce a man page for section 5 - configuration file formats. +# +:+][+: +(out-push-new) :+] +if test -z "${MAN_PAGE_DATE}" +then LC_ALL=C date '+%d %b %Y' | sed 's/ */ /g' +else echo "${MAN_PAGE_DATE}" +fi +[+: +(define mpage-date (shell (out-pop #t))) + +(define head-line (lambda() + (sprintf ".TH %s %s \"%s\" \"%s\" \"%s\"\n.\\\"\n" + (get "prog-name") man-sect + mpage-date package-text section-name) )) + +(define man-page #t) + +:+][+: + +INCLUDE "cmd-doc.tlib" + +:+] +.\" +.SH NAME +[+: prog-name :+] \- [+: prog-title :+] configuration file +[+: + +(define command-doc #f) +(out-push-new) :+][+: + +INVOKE build-doc :+][+: + + (shell (string-append + "fn='" (find-file "mdoc2man") "'\n" + "test -f ${fn} || die mdoc2man not found from $PWD\n" + "${fn} <<\\_EndOfMdoc_ || die ${fn} failed in $PWD\n" + (out-pop #t) + "\n_EndOfMdoc_" )) + +:+][+: + +(out-move (string-append (get "prog-name") "." + man-sect)) :+][+: # + +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +.\" S Y N O P S I S +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = :+][+: + +DEFINE mk-synopsis :+][+: + (out-push-new file-name) \:+] +.SH SYNOPSIS +.B [+: file-path :+] +.PP [+: + +(if (exist? "explain") + (string-append "\n.PP\n" + (join "\n.PP\n" (stack "explain"))) ) :+][+: + +(out-pop) :+][+: + +ENDDEF mk-synopsis + +agman-file.tpl ends here :+] diff --git a/autoopts/tpl/agman.tlib b/autoopts/tpl/agman.tlib new file mode 100644 index 0000000..bef8e2a --- /dev/null +++ b/autoopts/tpl/agman.tlib @@ -0,0 +1,98 @@ +[+: AutoGen5 template -*- shell-script -*- + +null + +:+][+: + +## agman-lib.tpl -- Template for command line man pages +## +## Author: Jim Van Zandt +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +## This "library" converts texi-isms into man-isms. It gets included +## by the man page template at the point where texi-isms might start appearing +## and then "emit-man-text" is invoked when all the text has been assembled. +## +## Display the command line prototype, +## based only on the argument processing type. +## +## And run the entire output through "sed" to convert texi-isms + +:+][+: + +(define sed-script (string-append (base-name) ".post-proc-sed")) +(out-push-new sed-script) + +\:+] +s;@code{\([^}]*\)};\\fB\1\\fP;g +s;@var{\([^}]*\)};\\fB\1\\fP;g +s;@samp{\([^}]*\)};\\fB\1\\fP;g +s;@i{\([^}]*\)};\\fI\1\\fP;g +s;@file{\([^}]*\)};\\fI\1\\fP;g +s;@emph{\([^}]*\)};\\fI\1\\fP;g +s;@strong{\([^}]*\)};\\fB\1\\fP;g +s/@\([{}]\)/\1/g +s,^\$\*$,.br, +/@ *example/,/@ *end *example/s/^/ / +s/^ *@ *example/.nf/ +s/^ *@ *end *example/.fi/ +/^ *@ *noindent/d +/^ *@ *enumerate/d +s/^ *@ *end *enumerate/.br/ +/^ *@ *table/d +s/^ *@ *end *table/.br/ +s/^@item \(.*\)/.sp\ +.IR "\1"/ +s/^@item/.sp 1/ +s/\*\([a-zA-Z0-9:~=_ -]*\)\*/\\fB\1\\fP/g +s/``\([a-zA-Z0-9:~+=_ -]*\)''/\\(lq\1\\(rq/g +s/^'/\\'/ +s/^@\*/.br/ +s/ -/ \\-/g +s/^\.in \\-/.in -/ +[+: + +(out-suspend "sed-script") +(define raw-text (string-append (base-name) ".raw")) +(out-push-new raw-text) + +:+][+: + +DEFINE emit-man-text :+][+: + (out-pop) + (out-resume "sed-script") :+][+: + + FOR doc-sub :+][+: + + (define field-name (get "sub-name")) + (define rep-string (string-append "<<" field-name ">>")) + (string-substitute (get "sub-expr") rep-string (get field-name)) + :+][+: + ENDFOR doc-sub :+][+: + + (out-pop) + (shellf "sed -f %1$s %2$s ; rm -f %1$s %2$s" + sed-script raw-text) :+][+: + +ENDDEF emit-man-text :+][+: # + +agman-lib.tpl ends here :+] diff --git a/autoopts/tpl/agman1.tpl b/autoopts/tpl/agman1.tpl new file mode 100644 index 0000000..0b931a2 --- /dev/null +++ b/autoopts/tpl/agman1.tpl @@ -0,0 +1,12 @@ +[+: -*- Mode: nroff -*- + +AutoGen5 template man=%s.1 + +## Copyright (C) 2001-2018 Bruce Korb, all rights reserved. + +:+] +[+: `echo please note that this is obsolete >&2` :+][+: + +INCLUDE "agman-cmd.tpl" + +\:+] diff --git a/autoopts/tpl/agman3.tpl b/autoopts/tpl/agman3.tpl new file mode 100644 index 0000000..6e53191 --- /dev/null +++ b/autoopts/tpl/agman3.tpl @@ -0,0 +1,145 @@ +{+ AutoGen5 template -*- nroff -*- + +null + +## agman3.tpl -- Template for command line man pages +## +## Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + ++}{+ + +(define see-also "") +(if (exist? "see-also") + (set! see-also (string-append (get "see-also") " ")) ) + ++}{+ + +FOR export-func +}{+ + (if (not (exist? "private")) + (set! see-also (string-append see-also + (get "name") "(3) " )) ) + +}{+ + +ENDFOR export-func +}{+ + + +FOR export-func +}{+ + IF (not (exist? "private")) +}{+ + + (out-push-new (string-append + (get "name") ".3" )) + ++}.TH {+name+} 3 {+ ` + if test -z "${MAN_PAGE_DATE}" + then date +%Y-%m-%d + else echo "${MAN_PAGE_DATE}"; fi +` +} "" "Programmer's Manual" +{+ + +;; The following "dne" argument is a string of 5 characters: +;; '.' '\\' '"' and two spaces. It _is_ hard to read. " +;; +(dne ".\\\" ") + ++} +.SH NAME +{+name+} - {+what+} +.sp 1 +.SH SYNOPSIS +{+IF (exist? "header") +} +#include <\fI{+header+}\fP> +.br{+ + ENDIF+} +cc [...] -o outfile infile.c -l\fB{+library+}\fP [...] +.sp 1 +{+ ?% ret-type "%s" void ++} \fB{+name+}\fP({+ + IF (not (exist? "arg")) +}void{+ + ELSE +}{+ + FOR arg ", " +}{+arg-type+} \fI{+arg-name+}\fP{+ + ENDFOR arg +}{+ + ENDIF +}); +.sp 1 +.SH DESCRIPTION +{+ + INCLUDE "agman.tlib" ++}{+ +(get "doc") +}{+ + IF (exist? "arg") +}{+ + FOR arg +} +.TP +.IR {+ arg-name +} +{+ arg-desc +}{+ + + ENDFOR arg +}{+ + ENDIF arg exists +}{+ + + IF (exist? "ret-type") +} +.sp 1 +.SH RETURN VALUE +{+ret-desc+}{+ + + ENDIF +}{+ + + IF (exist? "err") +} +.sp 1 +.SH ERRORS +{+ err +}{+ + + ENDIF +}{+ + + IF (exist? "example") +} +.sp 1 +.SH EXAMPLES +.nf +.in +5 +{+ example +} +.in -5 +.fi{+ + + ENDIF +}{+ + +emit-man-text + ++} +.SH SEE ALSO +The \fIinfo\fP documentation for the -l\fI{+library+}\fP library. +.br +{+ +(define tmp-txt (get "see")) +(if (> (string-length see-also) 0) + (set! tmp-txt (string-append see-also ", " tmp-txt)) ) + +(shellf "echo '%s' | \ +sed 's@%s(3) @@;s/3) $/3)/;s/(3) /(3), /g;s/, *,/,/g;s/^, *//'" + tmp-txt (get "name")) +} +{+ + + (out-pop) +}{+ + + ENDIF private +}{+ + +ENDFOR export-func + + ++} diff --git a/autoopts/tpl/agmdoc-cmd.tpl b/autoopts/tpl/agmdoc-cmd.tpl new file mode 100644 index 0000000..084830b --- /dev/null +++ b/autoopts/tpl/agmdoc-cmd.tpl @@ -0,0 +1,52 @@ +[+: -*- Mode: nroff -*- + + AutoGen5 template mdoc + +## agman-cmd.tpl -- Template for command line mdoc pages +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +# Produce a man page for section 1, 5 or 8 commands. +# Which is selected via: -DMAN_SECTION=n +# passed to the autogen invocation. "n" may have a suffix, if desired. +# +:+][+: +(out-push-new) :+] +if test -z "${MAN_PAGE_DATE}" +then LC_ALL=C date '+%B %e %Y' | sed 's/ */ /g' +else echo "${MAN_PAGE_DATE}" +fi +[+: +(define mpage-date (shell (out-pop #t))) + +(define head-line (lambda() (string-append + ".Dd " mpage-date + "\n.Dt " UP-PROG-NAME " " man-sect " " section-name + "\n.Os\n") )) + +(define man-page #f) :+][+: + +INCLUDE "cmd-doc.tlib" :+][+: +INVOKE build-doc :+][+: + +(out-move (string-append + (get "prog-name") "." man-sect)) :+][+: +agmdoc-cmd.tpl ends here :+] diff --git a/autoopts/tpl/agmdoc-file.tpl b/autoopts/tpl/agmdoc-file.tpl new file mode 100644 index 0000000..ed8c8ed --- /dev/null +++ b/autoopts/tpl/agmdoc-file.tpl @@ -0,0 +1,76 @@ +[+: -*- Mode: nroff -*- + + AutoGen5 template mdoc + +## agman-file.tpl -- Template for file mdoc pages +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +# Produce an mdoc page for section 5 - configuration file formats. +# +:+][+: +(out-push-new) :+] +if test -z "${MAN_PAGE_DATE}" +then LC_ALL=C date '+%B %e %Y' | sed 's/ */ /g' +else echo "${MAN_PAGE_DATE}" +fi +[+: +(define mpage-date (shell (out-pop #t))) + +(define head-line (lambda() (string-append + ".Dd " mpage-date + "\n.Dt " UP-PROG-NAME " " man-sect " " section-name + "\n.Os " (shell "uname -sr") "\n") )) + +(define man-page #f) + +:+][+: + +INCLUDE "cmd-doc.tlib" + +:+] +.Sh NAME +.Nm [+: prog-name :+] +.Nd [+: prog-title :+] +[+: INVOKE build-doc :+][+: + +(out-move (string-append (get "prog-name") "." + man-sect)) :+][+:# + +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +.\" S Y N O P S I S +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = :+][+: + +DEFINE mk-synopsis :+][+: + (out-push-new file-name) \:+] +.Sh SYNOPSIS +.Sy [+: file-path :+] +.Pp [+: + +FOR explain "\n.Pp\n" :+][+: + explain :+][+: +ENDFOR :+][+: + +(out-pop) :+][+: + +ENDDEF mk-synopsis + +agmdoc-file.tpl ends here :+] diff --git a/autoopts/tpl/agpl.lic b/autoopts/tpl/agpl.lic new file mode 100644 index 0000000..bff4469 --- /dev/null +++ b/autoopts/tpl/agpl.lic @@ -0,0 +1,19 @@ +Copyright (C) , all rights reserved. +This is free software. It is licensed for use, modification and +redistribution under the terms of the GNU Affero GPL, version 3 +or later + + is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + + 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . + +GNU Affero GPL, version 3 or later diff --git a/autoopts/tpl/agtexi-cmd.tpl b/autoopts/tpl/agtexi-cmd.tpl new file mode 100644 index 0000000..a6d080c --- /dev/null +++ b/autoopts/tpl/agtexi-cmd.tpl @@ -0,0 +1,970 @@ +[= AutoGen5 template -*- Mode: texinfo -*- + +texi=invoke_PROGRAMNAME.texi + +# Documentation template +# +# This file is part of AutoOpts, a companion to AutoGen. +# AutoOpts is free software. +# AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +# +# AutoOpts is available under any one of two licenses. The license +# in use must be one of these two and the choice is under the control +# of the user of the license. +# +# The GNU Lesser General Public License, version 3 or later +# See the files "COPYING.lgplv3" and "COPYING.gplv3" +# +# The Modified Berkeley Software Distribution License +# See the file "COPYING.mbsd" +# +# These files have the following sha256 sums: +# +# 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +# 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +# 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +=][= + +INVOKE initialization =][= +INVOKE emit-description =] + +This [=(string-downcase doc-level)=] was generated by @strong{AutoGen}, +using the @code{agtexi-cmd} template and the option descriptions for the [=(. +coded-prog-name)=] program.[= (name-copyright) =] + +@menu +[= + (out-push-new) (out-suspend "menu") + (out-push-new) =][= + +INVOKE emit-usage-opt =][= + +;; FOR all options, ... +;; +(define opt-name "") +(define extra-text "") +(define optname-from "A-Z_^") +(define optname-to "a-z--") +(define invalid-doc "* INVALID *") +(if (exist? "preserve-case") (begin + (set! optname-from "_^") + (set! optname-to "--") )) +(if (and have-doc-options (not (exist? "flag[].documentation"))) (begin + (ag-fprintf "menu" menu-entry-fmt + "base-options:: " "Base options") + (print-node opt-name "Base options") +) ) + +=][=# + +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +FOR flag =][= + IF (and (last-for?) (exist? "documentation")) =][= BREAK =][= ENDIF =][= + + (set! opt-name (string-tr! (get "name") optname-from optname-to)) + (if (exist? "documentation") + (begin + (set! label-str (string-append opt-name " options")) + (ag-fprintf "menu" menu-entry-fmt + (string-append opt-name ":: ") label-str) + (print-node opt-name label-str) + (ag-fprintf 0 "\n%s." (get "descrip")) + (set! tmp-str (get "documentation")) + (if (> (string-length tmp-str) 1) + (ag-fprintf 0 "\n%s" tmp-str)) + ) + (begin + (set! tmp-str (get "doc" invalid-doc)) + (if (< 0 (string-length tmp-str)) (begin + (set! label-str (string-append opt-name " option" + (if (exist? "value") + (string-append " (-" (get "value") ")") + "" ) )) + (if have-doc-options + (ag-fprintf 0 opt-node-fmt opt-name label-str) + (begin + (ag-fprintf "menu" menu-entry-fmt + (string-append opt-name ":: ") label-str) + (print-node opt-name label-str) + ) + ) + (ag-fprintf 0 "\n@cindex %s-%s" down-prog-name opt-name) + ) ) + ) + ) =][= + + IF (and (not (exist? "documentation")) + (< 0 (string-length tmp-str)) ) + =][= + IF (exist? "aliases") =][= + INVOKE emit-aliases =][= + ELSE =][= + INVOKE emit-opt-text =][= + ENDIF =][= + ENDIF =][= + +ENDFOR flag =][= + +IF + (define home-rc-files (> (count "homerc") 0)) + (if (and (not home-rc-files) (exist? "homerc")) + (set! home-rc-files (> (string-length (get "homerc")) 0)) ) + (define environ-init (exist? "environrc")) + (or home-rc-files environ-init) + =][= + + INVOKE emit-presets =][= + +ENDIF =][= + +INVOKE emit-exit-status =][= +INVOKE emit-doc-sections =][= + +(out-suspend "opt-desc") +(out-resume "menu") +(emit (out-pop #t)) +(emit "@end menu\n") +(out-resume "opt-desc") +(emit (out-pop #t)) +(define post-proc-cmd (get "doc-sub-cmd" "sed -f %s %s")) + +(if do-post-proc (begin + (out-pop) + (shellf post-proc-cmd post-proc-file raw-doc-file) +) ) + +=][=# + +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +DEFINE emit-doc-sections =][= + +FOR doc-section =][= + + IF (define opt-name (string-capitalize! (get "ds-type"))) + (or (== opt-name "Exit Status") + (== opt-name "Description") + (exist? "omit-texi")) =][= + CONTINUE =][= + ENDIF =][= + + (define section-file (string-append tmp-dir "/" + (string-substitute opt-name " " "-"))) + (if (not (access? section-file R_OK)) (begin + (ag-fprintf "menu" menu-entry-fmt (string-append opt-name "::") opt-name) + (set! label-str (string-append + down-prog-name " " (string-capitalize opt-name))) + (out-push-new section-file) + (print-node opt-name label-str) + ) (begin + (out-push-add section-file) + (emit "\n") + ) ) + + (define cvt-fn (get "ds-format" "texi")) + (if (not (== cvt-fn "texi")) + (divert-convert cvt-fn) ) =][= + (emit (string-append "\n" (get "ds-text") "\n")) + (convert-divert) + (out-pop) + +=][= +ENDFOR doc-section =][= + +FOR doc-section =][= + IF (define opt-name (string-capitalize! (get "ds-type"))) + (define section-file (string-append tmp-dir "/" + (string-substitute opt-name " " "-"))) + (access? section-file R_OK) + =][= + (shellf "cat %1$s ; rm -f %1$s" section-file) + =][= + ENDIF accessible section file =][= +ENDFOR doc-section =][= + +ENDDEF emit-doc-sections + +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +DEFINE emit-description =][= + +(if (exist? "explain") + (emit (string-append "\n" (get "explain") "\n")) ) +(set! tmp-str (get "option-format" "texi")) +(divert-convert tmp-str) + +=][= + +IF (match-value? == "doc-section.ds-type" "DESCRIPTION") =][= + + FOR doc-section =][= + IF (== (get "ds-type") "DESCRIPTION") =][= + (define cvt-fn (get "ds-format" "texi")) + (if (not (== cvt-fn "texi")) + (divert-convert cvt-fn) ) + (emit (string-append "\n" (get "ds-text") "\n")) + =][= + BREAK =][= + + ENDIF =][= + ENDFOR =][= + +ELSE =][= + +(join "\n\n" + (if (exist? "prog-info-descrip") + (stack "prog-info-descrip") + (if (exist? "prog-man-descrip") + (stack "prog-man-descrip") + (if (exist? "prog-descrip") + (stack "prog-descrip") + (stack "detail") +) ) ) ) =][= + +ENDIF =][= + +(convert-divert) =][= + +ENDDEF emit-description + +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +DEFINE emit-exit-status =][= + (ag-fprintf "menu" menu-entry-fmt "exit status::" "exit status") + (print-node "exit status" (string-append program-name " exit status")) =] + +One of the following exit values will be returned: +@table @samp +@item 0 (EXIT_[= + (set! tmp-str (get "exit-name[0]" "SUCCESS")) + (string-upcase (string->c-name! tmp-str)) + =]) +[= + (define need-ex-noinput (exist? "homerc")) + (define need-ex-software #t) + (get "exit-desc[0]" "Successful program execution.")=] +@item 1 (EXIT_[= + + (set! tmp-str (get "exit-name[1]" "FAILURE")) + (string-upcase (string->c-name! tmp-str))=]) +[= (get "exit-desc[1]" + "The operation failed or the command syntax was not valid.") =][= + +FOR exit-desc (for-from 2) =][= + (if (= (for-index) 66) + (set! need-ex-noinput #f) + (if (= (for-index) 70) + (set! need-ex-software #f) )) + (set! tmp-str (get (sprintf "exit-name[%d]" (for-index)) "* unnamed *")) + (sprintf "\n@item %d (EXIT_%s)\n%s" (for-index) + (string-upcase (string->c-name! tmp-str)) + (get (sprintf "exit-desc[%d]" (for-index)))) + =][= +ENDFOR exit-desc =][= + +(if need-ex-noinput + (emit "\n@item 66 (EX_NOINPUT) +A specified configuration file could not be loaded.")) + +(if need-ex-noinput + (emit "\n@item 70 (EX_SOFTWARE) +libopts had an internal operational error. Please report +it to autogen-users@@lists.sourceforge.net. Thank you.")) +=] +@end table[= + +ENDDEF emit-exit-status + +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +DEFINE emit-aliases =] + +This is an alias for the @code{[= aliases =]} option, +[= (sprintf "@pxref{%1$s %2$s, the %2$s option documentation}.\n" + down-prog-name (get "aliases")) =][= + +ENDDEF emit-aliases + +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +DEFINE emit-opt-text =] + +This is the ``[=(string-downcase! (get "descrip"))=]'' option.[= + IF (exist? "arg-type") =] +This option takes a[= (if (exist? "arg-optional") "n optional" "") + =] [= arg-type =] argument[= +(if (exist? "arg-name") (string-append " @file{" + (string-substitute (get "arg-name") "@" "@@") "}")) + =].[= + ENDIF =][= + + IF (out-push-new) + + (exist? "min") =]@item +is required to appear on the command line. +[= + ENDIF=][= + + IF (exist? "max") =]@item +may appear [= + IF % max (== "%s" "NOLIMIT") + =]an unlimited number of times[= + ELSE + =]up to [=max=] times[= + ENDIF=]. +[= + ENDIF=][= + + IF (exist? "disable") =]@item +can be disabled with --[=disable=]-[=(. opt-name)=][= + (if (exist? "enable") (emit + "\nand enabled with --" (get "enable") "-" opt-name)) =]. +[= + ENDIF=][= + + IF (exist? "enabled") =]@item +It is enabled by default. +[= + ENDIF=][= + + IF (exist? "ifdef") =]@item +must be compiled in by defining @code{[=(get "ifdef") + =]} during the compilation. +[= + ENDIF =][= + + IF (exist? "ifndef") =]@item +must be compiled in by @strong{un}-defining @code{[=(get "ifndef") + =]} during the compilation. +[= + ENDIF=][= + + IF (exist? "no_preset") =]@item +may not be preset with environment variables or configuration (rc/ini) files. +[= + ENDIF=][= + + IF (exist? "equivalence") =]@item +is a member of the [=equivalence=] class of options. +[= + ENDIF=][= + + IF (exist? "flags_must") =]@item +must appear in combination with the following options: +[= FOR flags_must ", " =][=flags_must=][= + ENDFOR=]. +[= + ENDIF=][= + + IF (exist? "flags_cant") =]@item +must not appear in combination with any of the following options: +[= FOR flags_cant ", " =][=flags_cant=][= + ENDFOR=]. +[= + ENDIF=][= + + IF (~* (get "arg-type") "key|set") =]@item +This option takes a keyword as its argument[= + + CASE arg-type =][= + =* key =]. +The argument sets an enumeration value that can be tested by comparing[= + + =* set =] list. +Each entry turns on or off membership bits. These bits can be tested +with bit tests against[= + ESAC arg-type =] the option value macro ([= +(string-upcase (string-append +(if (exist? "prefix") (string-append (get "prefix") "_") "") +"OPT_VALUE_" (get "name") )) =]). +The available keywords are: +@example +[= (shell (string-append + "${CLexe:-columns} -I4 --spread=1 -W50 <<\\" heredoc-marker + (join "\n" (stack "keyword") "\n") + heredoc-marker + ) ) =] +@end example +[= + + IF (=* (get "arg-type") "key") =] +or their numeric equivalent. +[= ENDIF =][= + + ENDIF key/set arg =][= + + IF (set! extra-text (out-pop #t)) + (> (string-length extra-text) 2) + =] + +@noindent +This option has some usage constraints. It: +@itemize @bullet +[= (. extra-text) =]@end itemize +[= ENDIF =][= + +?% doc "\n%s" "\nThis option has no @samp{doc} documentation." =][= + IF (exist? "deprecated") =] + +@strong{NOTE}@strong{: THIS OPTION IS DEPRECATED}[= + + ENDIF =][= + +ENDDEF emit-opt-text + +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +DEFINE set-home-rc-vars =][= + CASE homerc =][= + ==* '$@' =][= + (set! explain-pkgdatadir #t) + (set! cfg-file-name (string-substitute (get "homerc") + "$@" "$(pkgdatadir)")) =][= + + == '.' =][= + (set! cfg-file-name "$PWD") + (set! env-var-list (string-append env-var-list "PWD, ")) + =][= + + ==* './' =][= + (set! explain-pkgdatadir #t) + (set! env-var-list (string-append env-var-list "PWD, ")) + (set! cfg-file-name (string-append "$PWD" (substring (get "homerc") 1))) + =][= + + ~~* '\$[A-Za-z]' =][= + (set! cfg-file-name (get "homerc")) + (set! env-var-list (string-append env-var-list + (shellf "echo '%s' | sed 's/^.//;s#/.*##'" cfg-file-name) + ", " )) + =][= + + == "" =][= (set! cfg-file-name "") =][= + + * =][= + (set! cfg-file-name (get "homerc")) =][= + ESAC =][= + +ENDDEF set-home-rc-vars + +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +DEFINE emit-multiple-rc =] +@noindent +@code{libopts} will search in [= + + (define explain-pkgdatadir #f) + (define env-var-list "") + rc-count =] places for configuration files: +@itemize @bullet[= +FOR homerc =][= + INVOKE set-home-rc-vars =][= + (if (> (string-length cfg-file-name) 0) + (sprintf "\n@item\n%s" cfg-file-name )) + =][= + +ENDFOR homerc =] +@end itemize[= + (if explain-pkgdatadir (ag-fprintf 0 +"\nThe value for @code{$(pkgdatadir)} is recorded at package configure time +and replaced by @file{libopts} when @file{%s} runs." program-name)) + +(if (> (string-length env-var-list) 1) + (shell (string-append +"list='@code{'`echo '" env-var-list "' | \ + sed -e 's#, $##' \ + -e 's#, #}, @code{#g' \ + -e 's#, \\([^ ][^ ]*\\)$#, and \\1#'`\\} +echo +echo 'The environment variables' ${list} +echo 'are expanded and replaced when @file{" program-name "} runs.'" +)) ) =] +For any of these that are plain files, they are simply processed. +For any that are directories, then a file named @file{[= + (if (exist? "rcfile") (get "rcfile") + (string-append "." program-name "rc"))=]} is searched for +within that directory and processed. +[= + +ENDDEF emit-multiple-rc + +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +DEFINE emit-one-rc-dir =] +@noindent +@code{libopts} will search in [= + (define env-var-list "") + (define explain-pkgdatadir #f)=][= + INVOKE set-home-rc-vars + +=]@file{[=(. cfg-file-name) =]} for configuration (option) data.[= + IF (. explain-pkgdatadir) =] +The value for @code{$(pkgdatadir)} is recorded at package configure time +and replaced by @file{libopts} when @file{[=prog-name=]} runs. +[=ENDIF=][= +(if (> (string-length env-var-list) 1) + (sprintf +"\nThe environment variable @code{%s} is expanded and replaced when +the program runs" env-var-list)) =] +If this is a plain file, it is simply processed. +If it is a directory, then a file named @file{[= +(if (exist? "rcfile") (get "rcfile") + (string-append "." program-name "rc")) +=]} is searched for within that directory. +[= + +ENDDEF emit-one-rc-dir + +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +DEFINE emit-rc-file-info =] +[= + + IF (define rc-count (count "homerc")) + (define cfg-file-name "") + (> rc-count 1) =][= + + INVOKE emit-multiple-rc =][= + + ELIF (> (string-length (get "homerc")) 1) + =][= + INVOKE emit-one-rc-dir =][= + ENDIF (> rc-count 1) + +=] +Configuration files may be in a wide variety of formats. +The basic format is an option name followed by a value (argument) on the +same line. Values may be separated from the option name with a colon, +equal sign or simply white space. Values may be continued across multiple +lines by escaping the newline with a backslash. + +Multiple programs may also share the same initialization file. +Common options are collected at the top, followed by program specific +segments. The segments are separated by lines like: +@example +[[=(. UP-PROG-NAME)=]] +@end example +@noindent +or by +@example + +@end example +@noindent +Do not mix these styles within one configuration file. + +Compound values and carefully constructed string values may also be +specified using XML syntax: +@example + + ...<...>... + +@end example +@noindent +yielding an @code{option-name.sub-opt} string value of +@example +"...<...>..." +@end example +@code{AutoOpts} does not track suboptions. You simply note that it is a +hierarchicly valued option. @code{AutoOpts} does provide a means for searching +the associated name/value pair list (see: optionFindValue).[= + +ENDDEF emit-rc-file-info + +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +DEFINE emit-presets =] + +[= + (ag-fprintf "menu" menu-entry-fmt "config::" + (string-append "presetting/configuring " down-prog-name) ) + + (print-node "config" + (string-append "presetting/configuring " program-name) ) =] + +Any option that is not marked as @i{not presettable} may be preset by +loading values from [= + +IF + + (if home-rc-files (emit + "configuration (\"rc\" or \"ini\") files")) + + environ-init + + =][= + (if home-rc-files (emit ", and values from ")) + =]environment variables named @code{[=(. UP-PROG-NAME)=]} and @code{[= +(. UP-PROG-NAME)=]_}. @code{} must be one of +the options listed above in upper case and segmented with underscores. +The @code{[=(. UP-PROG-NAME)=]} variable will be tokenized and parsed like +the command line. The remaining variables are tested for existence and their +values are treated like option arguments[= + ENDIF have environment inits =]. +[= + + IF (. home-rc-files) =][= + INVOKE emit-rc-file-info =][= + ENDIF home-rc-files =] + +The command line options relating to configuration and/or usage help are: +[= + +IF (exist? "version") =] +@[= (. head-level) =] version[= (flag-string "version-value" "v") =] + +Print the program version to standard out, optionally with licensing +information, then exit 0. The optional argument specifies how much licensing +detail to provide. The default is to print [= +(if (exist? "gnu-usage") + "the license name with the version" + "just the version") +=]. The licensing information may be selected with an option argument. +Only the first letter of the argument is examined: + +@table @samp +@item version +Only print the version.[= +(if (not (exist? "gnu-usage")) " This is the default.")=] +@item copyright +Name the copyright usage licensing terms.[= +(if (exist? "gnu-usage") " This is the default.")=] +@item verbose +Print the full copyright usage licensing terms. +@end table +[= +ENDIF version =][= + +IF (exist? "usage-opt") =] +@[= (. head-level) =] usage[= (flag-string "usage-value" "u") =] + +Print abbreviated usage to standard out, then exit 0. +[= +ENDIF usage-opt =][= + +IF (exist? "vendor-opt") =] +@[= (. head-level) =] vendor-option (-W) + +Options that do not have flag values specified must be specified with +@code{-W} and the long option name. That long name is the argument to +this option. Any options so named that require an argument must have +that argument attached to the option name either with quoting or an +equal sign. +[= +ENDIF vendor-opt =][= + +IF (exist? "resettable") =] +@[= (. head-level) =] reset-option[= (flag-string "reset-value" "R") =] + +Resets the specified option to the compiled-in initial state. +This will undo anything that may have been set by configuration files. +The option argument may be either the option flag character or its long name. +[= +ENDIF resettable =][= + +IF (exist? "home-rc") =][= + IF (not (exist? "disable-save")) =] +@[= (. head-level) =] save-opts[= (flag-string "save-opts-value" ">") =] + +Saves the final, configured option state to the specified file (the optional +option argument). If no file is specified, then it will be saved to the +highest priority (last named) @file{rc-file} in the search list. +The command will exit after updating this file. +[= + ENDIF disable-save =][= + + IF (not (exist? "disable-load")) =] +@[= (. head-level) =] load-opts[= (flag-string "load-opts-value" "<") =] + +Loads the named configuration file. +[= + ENDIF disable-load =][= +ENDIF home-rc =][= + +ENDDEF emit-presets + +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +DEFINE header \=] +\input texinfo +@c -*-texinfo-*- +@c %**start of header +@setfilename [= (string-append down-prog-name ".info") =] +@settitle [= (sprintf (if (exist? "package") "%2$s - %1$s" "%s") + (get "package") (get "prog-title")) =] +@c %**end of header +@setchapternewpage off +@titlepage +@sp 10 +@comment The title is printed in a large font. +@center @titlefont{Sample Title} + +@c The following two commands start the copyright page. +@page +@vskip 0pt plus 1filll +[= (name-copyright) =][= +IF (exist? "copyright.type") =] +[= (license-full (get "copyright.type") program-name "" + (get "copyright.owner" (get "copyright.author" "")) + (get "copyright.date") ) =][= +ENDIF =] +@end titlepage +@node Top, [= prog-name =] usage, , (dir) +@top [= prog-title =] +[= + +ENDDEF header + +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +DEFINE emit-usage-opt =][= + + (define label-str (string-append + program-name " help/usage (@option{" help-opt "})")) + (ag-fprintf "menu" menu-entry-fmt "usage::" label-str) + (sprintf node-fmt "usage" label-str) =] +@cindex [=(. down-prog-name)=] help + +This is the automatically generated usage text for [= prog-name =]. + +The text printed is the same whether selected with the @code{help} option +(@option{[= (. help-opt) =]}) or the @code{more-help} option (@option{[= +(. more-help-opt) =]}). @code{more-help} will print +the usage text by passing it through a pager program. +@code{more-help} is disabled on platforms without a working +@code{fork(2)} function. The @code{PAGER} environment variable is +used to select the program, defaulting to @file{more}. Both will exit +with a status code of 0. + +@exampleindent 0 +@example +[= (out-push-new) =] +prog_name=[= (. program-name) =] +PROG=./${prog_name} +test -f ${PROG} || { + PROG=`echo $PROG | tr '[A-Z]' '[a-z]'` + test -f ${PROG} || PROG=`echo $PROG | tr x_ x-` +} +if [ ! -f ${PROG} ] +then + if [= (string-append program-name " " help-opt) =] > /dev/null 2>&1 + then PROG=`command -v ${prog_name}` + else PROG="echo ${prog_name} is unavailable - no " + fi +fi +${PROG} [=(. help-opt)=] 2>&1 | \ + sed -e "s/Usage: lt-${prog_name} /Usage: ${prog_name} /" \ + -e 's/@/@@/g;s/{/@{/g;s/}/@}/g' \ + -e 's/ / /g' +[= (shell (out-pop #t)) =] +@end example +@exampleindent 4 +[= + +ENDDEF emit-usage-opt + +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +DEFINE initialization =][= + + ;;# START-BUILDTREE-ISMS + ;; + (shell "CLexe=${AGexe%/agen5/*}/columns/columns + test -x \"${CLexe}\" || { + CLexe=${AGexe%/autogen}/columns + test -x \"${CLexe}\" || die 'columns program is not findable' + }") + +=][= # END-BUILDTREE-ISMS + +(shell "CLexe=`echo ${AGexe} | sed 's@/autogen@/columns@'` + test -x \"${CLexe}\" || CLexe=`which columns`") + +# END-INSTALL-ONLY-CODE =][= + + ;; divert-convert divert text for conversion to .texi format + ;; convert-divert convert the diversion done with divert-convert + ;; + (define divert-convert (lambda (diversion-type) (begin + (set! was-diverted + (not (or (== diversion-type "texi") (== diversion-type "")))) + (if was-diverted (begin + (set! cvt-script + (find-file (string-append diversion-type "2texi"))) + (if (not (defined? 'cvt-script)) + (error (sprintf "unknown source format type: %s" + diversion-type)) ) + (out-push-new) )) ))) + + (define heredoc-marker "_Unlikely_Here_Doc_Marker_\n") + (define convert-divert (lambda () + (if was-diverted (shell (string-append + cvt-script "<<\\" heredoc-marker (out-pop #t) "\n" heredoc-marker + )) ))) + + (define was-diverted #f) + (define diversion-type "") + (define cvt-script "") + (define tmp-str "") + + (define name-copyright (lambda () + (if (exist? "copyright") + (string-append "\nThis software is released under " + (license-name (get "copyright.type" "an unknown copyright")) + "." ) ) )) + + (make-tmp-dir) + (define program-name (get "prog-name")) + (define down-prog-name (string-downcase program-name)) + (define UP-PROG-NAME (string-upcase program-name)) + (shellf "export AG_DEF_PROG_NAME=%s" program-name) + (define doc-level (getenv "LEVEL")) + (if (not (string? doc-level)) + (set! doc-level "section")) + (define file-name (string-append down-prog-name ".texi")) + (define coded-prog-name (string-append "@code{" down-prog-name "}")) + + (define replace-prog-name (lambda (nm) + (string-substitute (get nm) down-prog-name coded-prog-name ) )) + + (define have-doc-options (exist? "flag.documentation")) + (define print-menu #t) + (define do-doc-nodes #f) + (define menu-entry-fmt (string-append + "* " down-prog-name " %-24s %s\n")) + (define emit-menu-entry (lambda (is-doc) (not is-doc))) + (if have-doc-options + (set! emit-menu-entry (lambda (is-doc) is-doc)) ) + (define chk-flag-val (exist? "flag.value")) + (define flag-string (lambda (v-nm v-df) (if (not chk-flag-val) "" + (string-append " (-" + (if (exist? v-nm) (get v-nm) v-df) + ")") ))) + + (define help-opt "") + (if (exist? "long-opts") + (set! help-opt "--help") + (if (not (exist? "flag.value")) + (set! help-opt "help") + (if (not (exist? "help-value")) + (set! help-opt "-?") + (begin + (set! tmp-str (get "help-value")) + (if (> (string-length tmp-str) 0) + (set! help-opt (string-append "-" tmp-str)) + (set! help-opt "--help") + ) ) + ))) + + (define more-help-opt "") + (if (exist? "long-opts") + (set! more-help-opt "--more-help") + (if (not (exist? "flag.value")) + (set! more-help-opt "more-help") + (if (not (exist? "more-help-value")) + (set! more-help-opt "-!") + (begin + (set! tmp-str (get "more-help-value")) + (if (> (string-length tmp-str) 0) + (set! more-help-opt (string-append "-" tmp-str)) + (set! more-help-opt "--more-help") + ) ) + ))) + + =][= + + CASE (. doc-level) =][= + == document =][= INVOKE header =][= + (define sub-level "chapter") + (define head-level "heading") =][= + == chapter =][= + (define sub-level "section") + (define head-level "subheading") =][= + == section =][= + (define sub-level "subsection") + (define head-level "subsubheading") =][= + == subsection =][= + (define sub-level "subsubsection") + (define head-level "subsubheading") =][= + + * =][=(error (sprintf "invalid doc level: %s\n" doc-level)) =][= + + ESAC doc level =][= + + (define node-fmt (string-append + "\n@node " down-prog-name " %s\n@" sub-level " %s")) + (define print-node (lambda (a b) (ag-fprintf 0 node-fmt a b) )) + + (define opt-node-fmt (if have-doc-options + (string-append "\n@" head-level + " %2$s.\n@anchor{" down-prog-name " %1$s}") + node-fmt + )) + + (define exit-sts-fmt "\n\n@node %1$s %2$s\n@%3$s %1$s %2$s\n") + (if (not (== doc-level "document")) + (set! file-name (string-append "invoke-" file-name)) ) + + (out-move file-name) + + (out-push-new (string-substitute (out-name) ".texi" ".menu")) + + (ag-fprintf 0 "* %-32s Invoking %s\n" + (string-append program-name " Invocation::") + program-name ) + + (out-pop) + +\=] +@node [= prog-name =] Invocation +@[=(. doc-level) =] Invoking [= prog-name =] +@pindex [= prog-name =] +@cindex [= prog-title =][= + + FOR concept =] +@cindex [= concept =][= + ENDFOR + +=] +@ignore +[= + +(dne "# " "# ") + +=] +@end ignore +[= +(define rep-string "") +(define do-post-proc #f) +(define post-proc-file "") +(define raw-doc-file "") +(define post-proc-commands "") =][= + +FOR doc-sub =][= + (define field-name (get "sub-type" "texi")) + (if (~~ "texi" field-name) (begin + (set! do-post-proc #t) + (set! field-name (get "sub-name")) + (set! rep-string (string-append "<<" field-name ">>")) + (set! post-proc-commands (string-append post-proc-commands + (string-substitute (get "sub-text") rep-string (get field-name)) + "\n" )) + ) ) =][= + +ENDFOR doc-sub =][= + +(if (> (string-length post-proc-commands) 1) (begin + (set! post-proc-file (string-append tmp-dir "/post-proc-cmds")) + (out-push-new post-proc-file) + (emit post-proc-commands) + (out-pop) + (set! raw-doc-file (string-append tmp-dir "/raw-doc")) + (out-push-new raw-doc-file) +) ) + +=][= + +ENDDEF initialization + +@c agtexi-cmd.tpl ends here =] diff --git a/autoopts/tpl/agtexi-file.tpl b/autoopts/tpl/agtexi-file.tpl new file mode 100644 index 0000000..eeaaf37 --- /dev/null +++ b/autoopts/tpl/agtexi-file.tpl @@ -0,0 +1,327 @@ +[= AutoGen5 template -*- Mode: texinfo -*- + +texi + +# Documentation template +# +# This file is part of AutoOpts, a companion to AutoGen. +# AutoOpts is free software. +# AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +# +# AutoOpts is available under any one of two licenses. The license +# in use must be one of these two and the choice is under the control +# of the user of the license. +# +# The GNU Lesser General Public License, version 3 or later +# See the files "COPYING.lgplv3" and "COPYING.gplv3" +# +# The Modified Berkeley Software Distribution License +# See the file "COPYING.mbsd" +# +# These files have the following sha256 sums: +# +# 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +# 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +# 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +=][= + +INVOKE initialization =][= + +(out-push-new (string-substitute (out-name) ".texi" ".menu")) + +(ag-fprintf 0 "* %-32s Notes about %s\n" + (string-append program-name " Notes::") + program-name ) + +(out-pop) +(if (exist? "explain") + (emit (string-append "\n" (get "explain") "\n")) ) +(set! tmp-str (get "option-doc-format" "texi")) +(divert-convert tmp-str) + +=][= + +IF (match-value? == "doc-section.ds-type" "DESCRIPTION") =][= + + FOR doc-section =][= + IF (== (get "ds-type") "DESCRIPTION") =][= + (define cvt-fn (get "ds-format" "texi")) + (if (not (== cvt-fn "texi")) + (divert-convert cvt-fn) ) =][= + (emit (string-append "\n" (get "ds-text") "\n")) + =][= + BREAK =][= + + ENDIF =][= + ENDFOR =][= + +ELSE =][= + +(join "\n\n" + (if (exist? "prog-info-descrip") + (stack "prog-info-descrip") + (if (exist? "prog-man-descrip") + (stack "prog-man-descrip") + (if (exist? "prog-descrip") + (stack "prog-descrip") + (stack "detail") +) ) ) ) =][= + +ENDIF =][= + +(convert-divert) =] + +This [=(string-downcase doc-level)=] was generated by @strong{AutoGen}, +using the @code{agtexi-cmd} template and the option descriptions for the [=(. +coded-prog-name)=] program.[= (name-copyright) =] + +@menu +[= + (out-push-new) (out-suspend "menu") + (out-push-new) + (define label-str (string-append + program-name " help/usage Something")) + =][=# + +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +FOR flag =][= + + (set! opt-name (string-tr! (get "name") optname-from optname-to)) + (if (exist? "documentation") + (begin + (set! label-str (string-append opt-name " options")) + (ag-fprintf "menu" menu-entry-fmt + (string-append opt-name ":: ") label-str) + (print-node opt-name label-str) + (ag-fprintf 0 "\n%s." (get "descrip")) + (set! tmp-str (get "documentation")) + (if (> (string-length tmp-str) 1) + (ag-fprintf 0 "\n%s" tmp-str)) + ) + (begin + (set! tmp-str (get "doc" invalid-doc)) + (if (< 0 (string-length tmp-str)) (begin + (set! label-str (string-append opt-name " option" + (if (exist? "value") + (string-append " (-" (get "value") ")") + "" ) )) + (if have-doc-options + (ag-fprintf 0 opt-node-fmt opt-name label-str) + (begin + (ag-fprintf "menu" menu-entry-fmt + (string-append opt-name ":: ") label-str) + (print-node opt-name label-str) + ) + ) + (ag-fprintf 0 "\n@cindex %s-%s" down-prog-name opt-name) + ) ) + ) + ) =][= + + IF (and (not (exist? "documentation")) + (< 0 (string-length tmp-str)) ) + =][= + ENDIF =][= + +ENDFOR flag =][= + +INVOKE emit-doc-sections =][= + +(out-suspend "opt-desc") +(out-resume "menu") +(emit (out-pop #t)) +(emit "@end menu\n") +(out-resume "opt-desc") +(out-pop #t) =][=# + +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +DEFINE emit-doc-sections =][= + +FOR doc-section =][= + + IF (define opt-name (string-capitalize! (get "ds-type"))) + (or (== opt-name "Exit Status") + (== opt-name "Description") + (exist? "omit-texi")) =][= + CONTINUE =][= + ENDIF =][= + + (ag-fprintf "menu" menu-entry-fmt (string-append opt-name "::") opt-name) + =][= + (set! label-str (string-append + down-prog-name " " (string-capitalize opt-name))) + =][= + (print-node opt-name label-str) + =][= + (define cvt-fn (get "ds-format" "texi")) + =][= + (if (not (== cvt-fn "texi")) + (divert-convert cvt-fn) ) =][= + (emit (string-append "\n" (get "ds-text") "\n")) + (convert-divert) =][= + +ENDFOR doc-section =][= + +ENDDEF emit-doc-sections + +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +DEFINE header \=] +\input texinfo +@c -*-texinfo-*- +@c %**start of header +@setfilename [= (string-append down-prog-name ".info") =] +@settitle [= (sprintf (if (exist? "package") "%2$s - %1$s" "%s") + (get "package") (get "prog-title")) =] +@c %**end of header +@setchapternewpage off +@titlepage +@sp 10 +@comment The title is printed in a large font. +@center @titlefont{Sample Title} + +@c The following two commands start the copyright page. +@page +@vskip 0pt plus 1filll +[= (name-copyright) =][= +IF (exist? "copyright.type") =] +[= (license-full (get "copyright.type") program-name "" + (get "copyright.owner" (get "copyright.author" "")) + (get "copyright.date") ) =][= +ENDIF =] +@end titlepage +@node Top, [= prog-name =] usage, , (dir) +@top [= prog-title =] +[= + +ENDDEF header + +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +DEFINE initialization =][= + + ;; divert-convert divert text for conversion to .texi format + ;; convert-divert convert the diversion done with divert-convert + ;; + (define divert-convert (lambda (diversion-type) (begin + (set! was-diverted + (not (or (== diversion-type "texi") (== diversion-type "")))) + (if was-diverted (begin + (set! cvt-script + (find-file (string-append diversion-type "2texi"))) + (if (not (defined? 'cvt-script)) + (error (sprintf "unknown source format type: %s" + diversion-type)) ) + (out-push-new) )) ))) + + (define heredoc-marker "_Unlikely_Here_Doc_Marker_\n") + (define convert-divert (lambda () + (if was-diverted (shell (string-append + cvt-script "<<\\" heredoc-marker (out-pop #t) "\n" heredoc-marker + )) ))) + + (define was-diverted #f) + (define diversion-type "") + (define cvt-script "") + (define tmp-str "") + + (define name-copyright (lambda () + (if (exist? "copyright") + (string-append "\nThis software is released under " + (license-name (get "copyright.type" "an unknown copyright")) + "." ) ) )) + + (make-tmp-dir) + (define program-name (get "prog-name")) + (define down-prog-name (string-downcase program-name)) + (define UP-PROG-NAME (string-upcase program-name)) + (shell "export AG_DEF_PROG_NAME=" program-name + "\nCLexe=`echo ${AGexe} | sed 's@/autogen@/columns@'`") + + (define doc-level (getenv "LEVEL")) + (if (not (string? doc-level)) + (set! doc-level "section")) + (define file-name (string-append down-prog-name ".texi")) + (define coded-prog-name (string-append "@code{" down-prog-name "}")) + + (define replace-prog-name (lambda (nm) + (string-substitute (get nm) down-prog-name coded-prog-name ) )) + + (define have-doc-options (exist? "flag.documentation")) + (define print-menu #t) + (define do-doc-nodes #f) + (define menu-entry-fmt (string-append + "* " down-prog-name " %-24s %s\n")) + (define emit-menu-entry (lambda (is-doc) (not is-doc))) + (if have-doc-options + (set! emit-menu-entry (lambda (is-doc) is-doc)) ) + (define chk-flag-val (exist? "flag.value")) + (define flag-string (lambda (v-nm v-df) (if (not chk-flag-val) "" + (string-append " (-" + (if (exist? v-nm) (get v-nm) v-df) + ")") ))) + + =][= + + CASE (. doc-level) =][= + == document =][= INVOKE header =][= + (define sub-level "chapter") + (define head-level "heading") =][= + == chapter =][= + (define sub-level "section") + (define head-level "subheading") =][= + == section =][= + (define sub-level "subsection") + (define head-level "subsubheading") =][= + == subsection =][= + (define sub-level "subsubsection") + (define head-level "subsubheading") =][= + + * =][=(error (sprintf "invalid doc level: %s\n" doc-level)) =][= + + ESAC doc level =][= + + (define node-fmt (string-append + "\n@node " down-prog-name " %s\n@" sub-level " %s")) + (define print-node (lambda (a b) (ag-fprintf 0 node-fmt a b) )) + + (define opt-node-fmt (if have-doc-options + (string-append "\n@" head-level + " %2$s.\n@anchor{" down-prog-name " %1$s}") + node-fmt + )) + + (define exit-sts-fmt "\n\n@node %1$s %2$s\n@%3$s %1$s %2$s\n") + =][= + + IF (not (== doc-level "document")) =][= + (set! file-name (string-append "invoke-" file-name)) + \=] +@node [= prog-name =] Notes +@[=(. doc-level) =] Notes about [= prog-name =] +@pindex [= prog-name =] +@cindex [= prog-title =][= + +FOR concept =] +@cindex [= concept =][= +ENDFOR =][= + + ENDIF document component + +=] +@ignore +[= + +(out-move file-name) +(dne "# " "# ") + +=] +@end ignore +[= + +ENDDEF initialization + +@c agtexi-cmd.tpl ends here =] diff --git a/autoopts/tpl/bits.tpl b/autoopts/tpl/bits.tpl new file mode 100644 index 0000000..a272423 --- /dev/null +++ b/autoopts/tpl/bits.tpl @@ -0,0 +1,717 @@ +[= AutoGen5 Template -*- Mode: C -*- + +h c + +## Author: Bruce Korb +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + + (define base-name "") + (define BASE-NAME "") + (define element-type "") + (define init-done #f) + (define is-64-bit #f) + (define is-array #f) + (define name-width 0) + (define desc-width 0) + (define bit-list "") + (define bit-name "") + (define tmp-name "") + + (define id-name (lambda (sfx) + (string-append + prefix "_" (string-upcase! (string->c-name! (get "b-name"))) sfx + ) )) + + (define mask-name (lambda (sfx) + (string-append + prefix "_" (string-upcase! (string->c-name! (get "m-name"))) sfx + ) )) + +=][= + +INVOKE preamble + +=][= + +CASE (suffix) =][= + +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +== h + +=] +[= + (shell "sedcmd='s/$/_val} +/;s/^/${/'") + (make-header-guard "bit_mask") =] +#include [= (if (exist? "stdint-hdr") + (string-append "\"" (get "stdint-hdr") "\"") + "" ) =] + +typedef [= + + (define type-name (string-append base-name "_bits_t")) + (define tmp + (if (< (high-lim "bit") 32) (begin + (set! element-type "uint32_t") + "uint32_t %s_bits_t") + (if (< (high-lim "bit") 64) (begin + (set! element-type "uint64_t") + (set! is-64-bit #t) + "uint64_t %s_bits_t" ) + (begin + (set! element-type "uint32_t") + (set! is-array #t) + (sprintf "uint32_t %%s_bits_t[%s]" + (shellf "mask_ct=`calc '( %d + 32 ) / 32'` ; echo $mask_ct" + (high-lim "bit")) ) )) )) + + (sprintf tmp base-name) + +=]; +typedef enum {[= + +FOR bit =][= + + (set! bit-name (string->c-name! (get "b-name"))) + (shellf + "%1$s_val=`calc '2 ^ %2$d'`\nmask_val=`calc \"${mask_val} + ${%1$s_val}\"`" + bit-name (for-index)) + + (set! tmp (string-length bit-name)) + (if (> tmp name-width) + (set! name-width tmp)) + (set! tmp (string-length (get "b-what"))) + (if (> tmp desc-width) + (set! desc-width tmp)) =][= + +ENDFOR bit =][= + + (define define-width (+ name-width 6 (string-length prefix))) + (define enum-fmt (sprintf "\n %%-%ds =%%4d%%s /* %%-%ds */" + define-width desc-width)) + +=][= + +FOR bit =][= + + (sprintf enum-fmt (id-name "_ID") (for-index) + (if (last-for?) " " ",") (get "b-what")) =][= +ENDFOR bit + += = = = = = = = = = = = = = = = =][= + +IF (ag-fprintf 0 "\n} %s_enum_t;\n" base-name) + (define def-fmt (sprintf "\n#define %%-%ds " define-width)) + + (< (high-lim "bit") 32) =][= + + INVOKE emit-word-macro one = 'U' mask-fmt = "%08XU" =][= + +ELIF (< (high-lim "bit") 64) =][= + + INVOKE emit-word-macro one = 'ULL' mask-fmt = "%016XULL" =][= + +ELSE more than 64 bits =][= + + INVOKE emit-multi-macros =][= + +ENDIF how many bits =][= + +IF (if (exist? "extra-defs") + (emit (string-append "\n\n" (get "extra-defs") "\n"))) + + (not (exist? "no-code")) =] +/* + * Return a string containing the names of the bits set. + */ +extern char * +[= (. base-name) =]_names([= (. type-name) =] bits); + +#define INV_[= (. BASE-NAME) =] -1 +#define DUP_[= (. BASE-NAME) =] -2 + +/* + * Set the bits in "bits" as specified by the input string "str". + * If any names are untranslatable (not in the name list or are + * ambiguous in that they match the initial portion of more than + * one entry), it will return -1 or -2, respectively. + * Otherwise, it returns the number of bits set in "bits". + */ +extern int +[= (. base-name) =]_bits( + [= (. type-name) =] * const bits, + char const * str); +[= ENDIF =] +#endif /* [= (. header-guard) =] */[= + +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +== c + + +=] +#include +#include +#include +#include +[= + + (if (exist? "no-code") (out-delete)) + (ag-fprintf 0 "#include \"%s\"\n" header-file) + (string-table-new "nm") + (string-table-add "nm" "* INVALID *") + (define ix 0) + (define offset-list "") + (define sorted-off "") =][= + +FOR bit (for-from 0) (for-by 1) =][= + + (if (exist? "b-name") + (begin + (set! tmp (string-downcase! (string->c-name! (get "b-name")))) + (set! ix (string-table-add "nm" tmp)) + (set! offset-list (string-append offset-list (sprintf "%d\n" ix))) + (set! sorted-off (string-append sorted-off + (sprintf "%-40s { %3d, %3d }\n" tmp ix (for-index)))) + ) + + (set! offset-list (string-append offset-list "0\n" )) + ) =][= + +ENDFOR bit =][= + + (emit-string-table "nm") + (sprintf "\nchar *\n%1$s_names(%1$s_bits_t bits)\n{" base-name) +=] + static int const nm_ixa[ [= (+ 1 (high-lim "bit")) =] ] = { +[= + + (define string-table-size (lambda (st-name) + (hash-ref (hash-ref stt-table st-name) "current-index") )) + + (emit (shellf "columns -I8 -S, --spread=1 <<_EOF_\n%s_EOF_" offset-list)) +=] }; + + static char buf[ [= (+ (string-table-size "nm") (count "bit")) =] ]; + char * buf_p = buf; + int ix = 0; +[= + +IF (< (high-lim "bit") 64) + +=] + while (bits != 0) { + if ((bits & 1) != 0) { + char const * p = nm + nm_ixa[ix]; + + if (buf_p > buf) { + *(buf_p++) = ','; + *(buf_p++) = ' '; + } + + if (p == nm) { + Oops: + strncpy(buf_p, nm, sizeof (buf) - (buf_p - buf)); + break; + } + + while ((*(buf_p++) = *(p++)) != '\0') ; + buf_p--; + } + bits >>= 1; + if (++ix > [= (high-lim "bit") =]) { + if (bits != 0) + goto Oops; + break; + } + }[= + +ELSE more than 64: + +=] + int bix = 0; + int bit_lim = 32; + do { + uint32_t bit_word = bits[bix]; + int ix = bix * 32; + + while (bit_word != 0) { + if ((bit_word & 1) != 0) { + char const * p = nm + nm_ixa[ix]; + + if (buf_p > buf) { + *(buf_p++) = ','; + *(buf_p++) = ' '; + } + + if (p == nm) { + Oops: + strncpy(buf_p, nm, sizeof (buf) - (buf_p - buf)); + break; + } + + while ((*(buf_p++) = *(p++)) != '\0') ; + buf_p--; + } + bit_word >>= 1; + if (++ix > [= (high-lim "bit") =]) { + if (bit_word != 0) + goto Oops; + return buf; + } + } + } while (++bix < [= `echo $mask_ct` =]);[= + +ENDIF + +=] + + return buf; +} + +static int +str_to_id(char const * str, char const ** p_str) +{ + static char nm_buf[ [= (+ 1 name-width) =] ]; + int res = -1; + int part = 1; + size_t len = 0; + + /* + * Extract the lower cased name with '-' replaced with '_' + */ + { + char * p = nm_buf; + + for (;;) { + char ch = *(str++); + switch (ch) { + case '-': + ch = '_'; + /* FALLTHROUGH */ + + case '_': + break; + + default: + if (isupper(ch)) + ch = _tolower(ch); + else if (! isalnum(ch)) { + str--; + goto have_name; + } + } + + if (++len > [= (. name-width) =]) + return -1; + + *(p++) = ch; + } have_name :; + + *p = '\0'; + len = p - nm_buf; + if (len == 0) + return INV_[= (. BASE-NAME) =]; + } + + /* + * Search the alphabetized table + */ + do { + static struct { + unsigned short const nm_off, val; + } nm_ixa[ [= (count "bit") =] ] = { +[= + (shellf (string-append + "(sort | sed 's/.*{/{/' | columns -I8 -S, --spread=1)<<_EOF_\n" + sorted-off "_EOF_" + )) +=] }; + + int av; + int lo = 0; + int hi = [= (- (count "bit") 1) =]; + + /* + * Binary search for first match + */ + do { + char const * p; + int df; + + av = (lo + hi) / 2; + p = nm + nm_ixa[av].nm_off; + df = strncmp(p, nm_buf, len); + + if (df == 0) { + res = nm_ixa[av].val; + if (p[len] == '\0') + part = 0; + + break; + } + + if (df > 0) + hi = av - 1; + else lo = av + 1; + + } while (lo <= hi); + + if (res < 0) + return INV_[= (. BASE-NAME) =]; + + if (part == 0) + break; + + /* + * Partial match. Look for an earlier match. One may be a full match. + */ + lo = av; + while (lo > 0) { + char const * p = nm + nm_ixa[--lo].nm_off; + int df = strncmp(p, nm_buf, len); + if (df != 0) + break; + if (p[len] == '\0') { + part = 0; + res = nm_ixa[lo].val; + break; + } + part++; + } + + if (part > 1) { + *p_str = nm_buf; + return DUP_[= (. BASE-NAME) =]; + } + + if ((part == 0) || (av == [= (- (count "bit") 1) =])) + break; + + /* + * Look for a successor match. No full match possible. + */ + { + char const * p = nm + nm_ixa[av+1].nm_off; + int df = strncmp(p, nm_buf, len); + if (df == 0) { + *p_str = nm_buf; + return DUP_[= (. BASE-NAME) =]; + } + } + } while (0); + + while (isspace(*str)) str++; + *p_str = str; + return res; +} + +int +[= + +# = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +(. base-name) =]_bits( + [= (. type-name) =] * const bits[= (if is-array "_p")=], + char const * str) +{[= + IF (. is-array) =] + [= (. element-type) =] * const bits = VOIDP(bits_p);[= + ENDIF =] + int ct = 0; + int res = 0; + + memset(bits, '\0', sizeof([= (. type-name) =])); + + another_bit: + + while (isspace(*str) || (*str == ',')) str++; + + for (;;) { + if (isdigit(*str)) { + [=(. element-type) =] num = + ([=(. element-type) =])strtoull(str, &str, 0); + *bits |= num; + ct += (num != 0); + + } else if (isalpha(*str)) { + res = str_to_id(str, &str); + if (res < 0) { + if (res == DUP_[= (. BASE-NAME) =]) + fprintf(stderr, "duplicate matches for '%s'\n", str); + goto fail_exit; + } + ct++; +[= + + IF (. is-array) =] + bits[res/32] |= 1 << (res & 0x1F);[= + ELIF (. is-64-bit) =] + *bits |= 1ULL << res;[= + ELSE =] + *bits |= 1 << res;[= + ENDIF + +=] + } else switch (*str) { + case ',': + goto another_bit; + + case '\0': + return ct; + + default: + res = INV_[= (. BASE-NAME) =]; + goto fail_exit; + } + } + + fail_exit: + memset(bits, '\0', sizeof(*bits)); + return res; +} + +#ifdef TEST_BITS + +static char const bit_names[] = +[= +(kr-string (string-append "The known " base-name " bit names are:\n" + (shellf (string-append + "(sort | columns -I2 --spread=1\n) <<_EOF_\n" + (string-downcase! (join "\n" (stack "bit.b-name"))) + "\n_EOF_")) + "\n" )) + =]; + +int +main(int argc, char** argv) +{ + static char const fmt_z[] = "'%s' yields: %s\n"; + [= (. type-name) =] bts; + if (argc != 2) { + fputs(bit_names, stderr); + return 1; + } + { + int ct = [= (. base-name) =]_bits(&bts, argv[1]); + if (ct <= 0) { + char const * pz; + switch (ct) { + case 0: pz = "no results"; break; + case INV_[= (. BASE-NAME) =]: pz = "invalid name"; break; + case DUP_[= (. BASE-NAME) =]: pz = "multiple match"; break; + } + fprintf(stderr, fmt_z, argv[1], pz); + fputs(bit_names, stderr); + return 1; + } + } + { + char * pz = [= (. base-name) =]_names(bts); + printf(fmt_z, argv[1], pz); + } + return 0; +} +#endif +[= + +ESAC =] +/* end of [= (out-name) =] */ +[=# + += = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +DEFINE preamble =][= + + (if (not init-done) (begin + + (if (not (exist? "mask-name")) + (error "no defined bit mask name")) + + (shell "calc() { bc <<_EOF_ +$* +_EOF_ +} + mask_val=0") + (set! init-done #t) + (set! base-name (string-downcase! (string->c-name! (get "mask-name")))) + (set! BASE-NAME (string-upcase base-name)) + (set! prefix (string-upcase (string->c-name! + (if (exist? "prefix") (get "prefix") base-name) ))) + ) ) + + (dne " * " "/* ") =] + */ +[= + +ENDDEF preamble + += = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +DEFINE emit-bit-list =][= + + (if (exist? "b-name") + (set! bit-list (string-append (join "\n" (stack "b-name")) "\n")) + (set! bit-list "") + ) =][= + + FOR m-inc =][= + (set! tmp (string->c-name! (get "m-inc"))) + (set! bit-list (string-append bit-list + (shellf "echo \"${%s}\"" tmp) "\n")) + =][= + ENDFOR m-inc=][= + + (set! bit-list (string->c-name! bit-list)) + (shellf "%s='%s'" (string->c-name! (get "m-name")) bit-list) + + (emit (shell (string-append + + "(sort -u | columns -I8 --spread=1 -S' |' --format=" prefix "_%s_BIT " + "--line=' \\'\n) <<\\_EOF_\n" + (string-upcase bit-list) + "_EOF_" + + ))) + + (shell (string-append + "sum=`(sort -u | \ + sed -e \"${sedcmd}\"\n) <<\\_EOF_\n" + bit-list + "_EOF_\n`\n" + "sum=`eval calc ${sum} 0`\n" + "printf " + (if (>= (high-lim "bit") 32) + "' \\\\\\n /* 0x%016XULL */\\n'" + (if (>= (high-lim "bit") 16) + "' \\\\\\n /* 0x%08XU */\\n'" + "' \\\\\\n /* 0x%04XU */\\n'" )) + " ${sum}" + )) +=][= + +ENDDEF emit-bit-list + += = = = = = = = = = = = = = = = = = = = =][= + +DEFINE emit-word-macro =][= + + (set! tmp-name (string-upcase! (string-append prefix "_" + (if (exist? "zero-name") (get "zero-name") "NO_BITS") ))) + (sprintf def-fmt tmp-name) =]0[= one =][= + + FOR bit =][= + + (sprintf def-fmt (id-name "_BIT")) =](1[=one=] << [= (id-name "_ID") =])[= + + ENDFOR =][= + + (ag-fprintf 0 def-fmt (string-append BASE-NAME "_MASK")) + (shellf "printf 0x%s ${mask_val}" (get "mask-fmt")) + + =][= + + FOR mask + + =] +[= (sprintf def-fmt (mask-name "_MASK")) =]( \ +[= INVOKE emit-bit-list =] )[= + + ENDFOR mask =][= + + FOR un-mask + + =] +[= (sprintf def-fmt (mask-name "_MASK")) =]([= + (string-append BASE-NAME "_MASK") =] & ~( \ +[= INVOKE emit-bit-list =]))[= + + ENDFOR un-mask=][= + + (if (exist? "defined") (string-append "\n\n" (get "defined"))) + +=][= IF (not (exist? "omit-test-n-set")) =] + +#define SET_[= (. BASE-NAME) =](_m, _b) \ + do { (_m) |= 1[= one =] << _b; } while (0) +#define CLEAR_[= (. BASE-NAME) =](_m, _b) \ + do { (_m) &= ~(1[= one =] << _b); } while (0) +#define TEST_[= (. BASE-NAME) =](_m, _b) (((_m) & (1[= one =] << _b)) != 0) +#define AND_[= (. BASE-NAME) =](_d, _s1, _s2) \ + do { (_d) = (_s1) & (_s2); } while (0) +#define OR_[= (. BASE-NAME) =](_d, _s1, _s2) \ + do { (_d) = (_s1) | (_s2); } while (0) +#define XOR_[= (. BASE-NAME) =](_d, _s1, _s2) \ + do { (_d) = (_s1) ^ (_s2); } while (0) +#define NOT_[= (. BASE-NAME) =](_d, _s) \ + do { (_d) = ~(_s); } while (0) +[= ENDIF omit-test-n-set =][= +ENDDEF emit-word-macro + += = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +DEFINE emit-loop-macro + +=][= + + (sprintf "#define %5s_%s" (get "mac-name") BASE-NAME) =][= + + CASE op-code =][= + == "~" =](_d, _s)[= (set! tmp one-arg-op)=][= + * =](_d, _s1, _s2)[= (set! tmp two-arg-op)=][= + ESAC op-code =] \ + [= (. iterate) =] \ + [= (sprintf tmp (get "op-code")) =][= + +ENDDEF emit-loop-macro + += = = = = = = = = = = = = = = = = = = =][= + +DEFINE emit-multi-macros + +=][= + +defined + +=][= IF (not (exist? "omit-test-n-set")) =] + +#define SET_[= +(define iterate (sprintf "do { int _ix_ = 0; for (;_ix_ < %s; _ix_++) {" + (shell "echo $mask_ct") )) +(define two-arg-op "(_d)[_ix_] = (_s1)[_ix_] %s (_s2)[_ix_]; } } while (0)") +(define one-arg-op "(_d)[_ix_] = %s(_s)[_ix_]; } } while (0)") + + BASE-NAME =](_m, _b) \ + do { (_m)[(_b)/32] |= 1U << ((_b) % 32); } while (0) +#define CLEAR_[= (. BASE-NAME) =](_m, _b) \ + do { (_m)[(_b)/32] &= ~(1U << ((_b) % 32)); } while (0) +#define TEST_[= (. BASE-NAME) =](_m, _b) \ + (((_m)[(_b)/32] & (1U << ((_b) % 32))) != 0) +[= INVOKE emit-loop-macro op-code = "&" mac-name = AND =] +[= INVOKE emit-loop-macro op-code = "|" mac-name = OR =] +[= INVOKE emit-loop-macro op-code = "^" mac-name = XOR =] +[= INVOKE emit-loop-macro op-code = "~" mac-name = NOT =] +[= ENDIF omit-test-n-set =][= + +ENDDEF emit-multi-macros =][= + +# End of bits.tpl \=] diff --git a/autoopts/tpl/cmd-doc.tlib b/autoopts/tpl/cmd-doc.tlib new file mode 100644 index 0000000..87e17fd --- /dev/null +++ b/autoopts/tpl/cmd-doc.tlib @@ -0,0 +1,1182 @@ +[+: -*- Mode: nroff -*- + + AutoGen5 template man + +# cmd-doc.tlib -- Template for command line man/mdoc pages +# +# This file is part of AutoOpts, a companion to AutoGen. +# AutoOpts is free software. +# Copyright (C) 1992-2018 Bruce Korb - all rights reserved +# +# AutoOpts is available under any one of two licenses. The license +# in use must be one of these two and the choice is under the control +# of the user of the license. +# +# The GNU Lesser General Public License, version 3 or later +# See the files "COPYING.lgplv3" and "COPYING.gplv3" +# +# The Modified Berkeley Software Distribution License +# See the file "COPYING.mbsd" +# +# These files have the following sha256 sums: +# +# 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +# 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +# 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +# Produce a man page for section 1, 5, 6 or 8 commands. Which is +# selected via: -DMAN_SECTION=n. "n" may have a suffix, if desired. +# These sections have default section names that may be overridden +# with -DSECTIN_NAME=XX, also passed to the autogen invocation. +# +:+][+: + + ;;# START-BUILDTREE-ISMS + ;; + (shell "CLexe=${AGexe%/agen5/*}/columns/columns + test -x \"${CLexe}\" || { + CLexe=${AGexe%/autogen}/columns + test -x \"${CLexe}\" || die 'columns program is not findable' + }") + +:+][+: # END-BUILDTREE-ISMS + +(shell "CLexe=`echo ${AGexe} | sed 's@/autogen@/columns@'` + test -x \"${CLexe}\" || CLexe=`which columns`") + +# END-INSTALL-ONLY-CODE :+][+: + +(define down-prog-name (string-downcase! (get "prog-name"))) +(define UP-PROG-NAME (get-up-name "prog-name")) + +(define command-doc #t) +(define tmp-val (getenv "MAN_SECTION")) +(define man-sect (if (exist? "cmd-section") (get "cmd-section") "1")) +(define file-name "") +(define sect-name "") +(define macro-name "") +(define tmp-str "") +(define fname-line "") +(define use-flags (exist? "flag.value")) +(define named-mode (not (or use-flags (exist? "long-opts") ))) + +(if (defined? 'tmp-val) + (if (string? tmp-val) + (set! man-sect tmp-val))) + +(define section-name + (if (=* man-sect "1") "User Commands" + (if (=* man-sect "5") "File Formats" + (if (=* man-sect "6") "Games" + (if (=* man-sect "8") "System Management" + (error + "the agman-cmd template only produces section 1, 5, 6 and 8 man pages") +))))) +(set! tmp-val (getenv "SECTION_NAME")) +(if (defined? 'tmp-val) (if (string? tmp-val) + (set! section-name tmp-val) )) + +(define package-text "") +(define package+version (and (exist? "package") (exist? "version"))) + +(if (or (exist? "package") (exist? "version")) (begin + (set! package-text (string-append + (get "package") + (if package+version " (" "") + (get "version") + (if package+version ")" "") )) +) ) + +(define name-to-fname (lambda (nm) + (string-tr (string-downcase nm) " " "-") )) + +(define sect-line-fname (lambda () (begin + (out-push-new file-name) + (emit (string-append ".Sh \"" sect-name "\"\n")) + (string-append "mk-" macro-name) ))) + +(make-tmp-dir) +(shell "mkdir $tmp_dir/SEC") +(define home-rc-files (exist? "homerc")) +(define home-rc-text + "\nSee \\fBOPTION PRESETS\\fP for configuration files.") + +(define environ-init (exist? "environrc")) +(define environ-text + "\nSee \\fBOPTION PRESETS\\fP for configuration environment variables.") + +(emit (head-line)) +(dne ".\\\" ") :+] +.Sh NAME +.Nm [+: prog-name :+] +.Nd [+: prog-title :+] +[+: INCLUDE "tpl-config.tlib" :+][+:# + +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +.\" B U I L D D O C +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = :+][+: + +DEFINE build-doc :+][+: + +(if (not command-doc) (begin + (set! home-rc-files #f) + (set! home-rc-text "") +) ) :+][+: + +INVOKE doc-sections :+][+: +INVOKE ao-sections :+][+: +INVOKE assemble-sections :+][+: + +ENDDEF build-doc + +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +.\" A S S E M B L E S E C T I O N S +.\" +.\" Emit the files for each section that was provided, and do conversions +.\" +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = :+][+: + +DEFINE assemble-sections :+][+: + +(out-push-new) + +:+][+: +#.\" Insert the sections in the prescribed order +#.\" Ensure a newline between them all. We strip blank lines, +#.\" so extra blank lines get removed. +#:+] +{ + cvt_prog='[+: + + (define target-form (if man-page "man" "mdoc")) + (define source-form (get "option-format" "texi")) + (define converter (string-append source-form "2" target-form )) + (set! tmp-str (find-file converter)) + + (if (not (defined? 'tmp-str)) + (error (string-append "cannot locate " converter))) + tmp-str :+]' + cvt_prog=`cd \`dirname "$cvt_prog"\` >/dev/null && pwd + `/`basename "$cvt_prog"` + cd $tmp_dir/SEC + test -x "$cvt_prog" || die "'$cvt_prog' is not executable" + + list='synopsis description options option-presets' + for f in $list + do test -f $f && { + cat $f ; echo + } + done > ../raw-doc + rm -f $list name + + list='implementation-notes environment files examples exit-status errors + compatibility see-also conforming-to history authors copyright bugs + notes' + for f in $list + do test -f $f && { + cat $f ; echo + } + done > ../end-doc + rm -f $list + + cat * ../end-doc >> ../raw-doc +} 2>/dev/null +cd .. +[+: +IF (exist? "doc-sub") :+][+: + (out-push-new (string-append tmp-dir "/doc-secs")) :+][+: + FOR doc-sub :+][+: + + IF (define field-name (get "sub-type" target-form)) + (~~ target-form field-name) :+][+: + + (set! field-name (get "sub-name")) + (define rep-string (string-append "<<" field-name ">>")) + (emit (string-substitute (get "sub-text") rep-string (get field-name))) + "\n" + + :+][+: ENDIF :+][+: + + ENDFOR doc-sub :+][+: + + (out-pop) + (define post-proc-cmd (string-append + (get "doc-sub-cmd" "sed -f %s %s") " | " + egrep-prog " -v '^[ ]*$'")) + (sprintf post-proc-cmd "doc-secs" "raw-doc") + :+][+: +ELSE \:+] +[+:(. egrep-prog):+] -v '^[ ]*$' raw-doc[+: +ENDIF doc-sub exists :+] | $cvt_prog[+: + +(shell (out-pop #t)) + +:+][+: + +ENDDEF assemble-sections + +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +.\" D O C S E C T I O N S +.\" +.\" Emit the files for each section that was provided. +.\" If multiple sections exist, they get glued together with ".Pp" +.\" between them. +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = :+][+: + +DEFINE doc-sections :+][+: + +FOR doc-section :+][+: + IF + (define sec-type (string-upcase (get "ds-type"))) + (define sec-name (name-to-fname sec-type)) + (define cvt-fn (find-file (string-append + (get "ds-format" "man") "2mdoc"))) + (if (not (defined? 'cvt-fn)) + (error (sprintf "Cannot locate converter for %s" + (get "ds-format" "man")))) + + (define sec-file (string-append tmp-dir "/SEC/" sec-name)) + (access? sec-file R_OK) :+][+: + (out-push-add sec-file) + (emit ".Pp\n") :+][+: + + ELSE :+][+: CASE + (out-push-new sec-file) + sec-type :+][+: + + == "" :+][+: (error "unnamed doc-section") :+][+: + *==* " " :+].Sh "[+: (. sec-type) :+]"[+: + * :+].Sh [+: (. sec-type) :+][+: + ESAC :+][+: + ENDIF :+] +[+: + + (shell (string-append + "fn='" cvt-fn "'\n" + "test -f ${fn} || die ${fn} not found from $PWD\n" + "export PERL5LIB=`dirname \"$fn\"`\n" + "${fn} <<\\_EndOfDocSection_ || die ${fn} failed in $PWD\n" + (get "ds-text") + "\n_EndOfDocSection_" + )) :+][+: + + CASE (emit "\n") sec-type :+][+: + == FILES :+][+: + (if home-rc-files (emit home-rc-text)) + (set! home-rc-files #f) :+][+: + + == ENVIRONMENT :+][+: + (if environ-init (emit environ-text)) + (set! environ-init #f) :+][+: + ESAC :+][+: + + (out-pop) + :+][+: + +ENDFOR doc-section :+][+: + +ENDDEF doc-sections + +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +.\" A O S E C T I O N S +.\" +.\" Emit the files for the sections that these templates augment, +.\" replace or conditionally replace +.\" +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = :+][+: + +DEFINE ao-sections :+][+: + IF (. command-doc) :+][+: + INVOKE cond-section sec = "OPTIONS" mode = "replace" :+][+: + INVOKE cond-section sec = "EXIT STATUS" mode = "insert" :+][+: + + IF (or home-rc-files environ-init) :+][+: + INVOKE cond-section sec = "OPTION PRESETS" mode = "replace" :+][+: + + IF (. home-rc-files) :+][+: + INVOKE cond-section sec = "FILES" mode = "append" :+][+: + ENDIF :+][+: + + IF (. environ-init) :+][+: + INVOKE cond-section sec = "ENVIRONMENT" mode = "append" :+][+: + ENDIF :+][+: + ENDIF :+][+: + + ELSE section 5, not command :+][+: + INVOKE cond-section sec = "FILES" mode = "append" :+][+: + ENDIF section 5/not :+][+: + + INVOKE cond-section sec = "SYNOPSIS" mode = "alt" :+][+: + INVOKE cond-section sec = "DESCRIPTION" mode = "append" :+][+: + INVOKE cond-section sec = "AUTHORS" mode = "alt" :+][+: + INVOKE cond-section sec = "BUGS" mode = "append" :+][+: + INVOKE cond-section sec = "NOTES" mode = "append" :+][+: + +IF (exist? "copyright") :+][+: + INVOKE cond-section sec = "COPYRIGHT" mode = "alt" :+][+: +ENDIF :+][+: + +ENDDEF ao-sections + +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +.\" C O N D I T I O N A L S E C T I O N +.\" +.\" Figure out what to do for AutoOpts required sections, depending on "mode" +.\" In all cases, if the file does not exist, invoke the "mk" macro to create +.\" a new file. If it does exist, then: +.\" +.\" alt Alternate -- emit no text +.\" replace throw away any pre-existing file. +.\" append invoke the "append" macro to emit additional text +.\" insert save the current contents, replacing the .Sh line with .Pp. +.\" invoke the "mk" macro then emit the saved text +.\" +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = :+][+: + +DEFINE cond-section :+][+: + + IF + (set! sect-name (string-upcase! (string-substitute + (get "sec") "-" " " ))) + (set! macro-name (string-downcase! (string-substitute + sect-name " " "-" ))) + (set! file-name (string-append tmp-dir "/SEC/" macro-name)) + + (not (access? file-name R_OK)) :+][+: + + INVOKE (sect-line-fname) :+][+: + + ELSE file exists :+][+: + + CASE (get "mode") :+][+: + + == replace :+][+: + INVOKE (sect-line-fname) :+][+: + + == append :+][+: + (out-push-add file-name) :+][+: + INVOKE (string-append "append-" macro-name) :+][+: + + == insert :+][+: + (set! fname-line (shellf + "sed '1s/.Sh .*/.Pp/' %1$s ; rm -f %1$s" file-name)) :+][+: + INVOKE (sect-line-fname) :+][+: + + == alt :+][+: + (out-push-new) :+][+: + + * :+][+: + (error (sprintf "invalid section type: %s" (get "mode"))) + + :+][+: + ESAC :+][+: + + ENDIF file existence/non-existence :+][+: + (out-pop) :+][+: # All paths open out :+][+: +ENDDEF cond-section + +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +.\" M K - D E S C R I P T I O N +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = :+][+: + +DEFINE mk-description :+][+: + + (out-push-new) + (emit + (if (exist? "prog-man-descrip") + (stack-join "\n.Pp\n" "prog-man-descrip") + (if (exist? "detail") + (stack-join "\n.Pp\n" "detail") + "There is no description for this command." + ) ) ) + (shell "sed 's/^$/.sp/' <<\\_EODesc_\n" (out-pop #t) "\n_EODesc_") + + :+][+: + INVOKE append-description :+][+: + +ENDDEF mk-description + +.\" = = = = = = = = = = = = = = = = = = +.\" A P P E N D - D E S C R I P T I O N +.\" = = = = = = = = = = = = = = = = = = :+][+: + +DEFINE append-description :+][+: + +IF (= (get "main.main-type") "for-each"):+][+: + + CASE main.handler-type :+][+: + ~* ^(name|file)|.*text :+] +.Pp +This program will perform its function for every file named on the command +line or every file named in a list read from stdin. The arguments or input +names must be pre\-existing files. The input list may contain comments, +which[+: + + !E :+] +.Pp +This program will perform its function for every command line argument +or every non\-comment line in a list read from stdin. +The input list comments[+: + + * :+][+: + (error "the 'for-each' main has in invalid handler-type.") :+][+: + ESAC \:+] + are blank lines or lines beginning with a '[+: + ?% comment-char "%s" "#" :+]' character. +[+: + +ENDIF - "main" is of "for-each" type :+][+: + +ENDDEF append-description + +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +.\" M K - O P T I O N S +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = :+][+: + +DEFINE mk-options + +:+][+: + +(define opt-arg "") +(define dis-name "") +(define opt-name "") +(define optname-from "A-Z_^") +(define optname-to "a-z--") +(define cvt-cmd "") +(define formatted-doc (exist? "option-format")) + +(if formatted-doc (begin + (out-push-new) + (set! cvt-cmd (string-append (get "option-format") "2mdoc")) +) ) + +(if (exist? "preserve-case") + (begin + (set! optname-from "_^") + (set! optname-to "--") +) ) + +(define fix-optname (lambda (o_nm) (begin + (set! o_nm (string-tr o_nm optname-from optname-to)) + (set! o_nm (string-substitute o_nm "-" "\\-" )) + o_nm ))) + +(if (exist? "option-info") + (string-append ".Pp\n" (get "option-info") "\n") ) +\:+] +.Bl -tag[+: + +FOR flag :+][+: + IF (not (exist? "documentation")) :+][+: + IF (exist? "aliases") :+][+: + INVOKE emit-alias-opt :+][+: + ELSE :+][+: + INVOKE emit-flag-text :+][+: + ENDIF :+][+: + + ELSE :+] +.Ss "[+: (get "descrip" "") :+]"[+: +(set! tmp-str (get "documentation" "")) +(if (> (string-length tmp-str) 3) (string-append + "\n" tmp-str "\n" )) :+][+: + + ENDIF :+][+: +ENDFOR flag + +.\" = = = = = = = = = = = = = = = = = +.\" help option +.\" = = = = = = = = = = = = = = = = = + +:+] +.It [+: + (define tmp-val (get "help-value" "\\&?")) + (if (and use-flags (> (string-length tmp-val) 0)) + (string-append "Fl " tmp-val + (if (exist? "long-opts") " , Fl -help" "") ) + (string-append (if (exist? "long-opts") "Fl -" "") "help" ) + ) \:+] + +Display usage information and exit.[+:# + +.\" = = = = = = = = = = = = = = = = = +.\" more-help option +.\" = = = = = = = = = = = = = = = = = :+][+: + + IF (not (exist? "no-libopts")) :+] +.It [+: + (define tmp-val (get "more-help-value" "\\&!")) + (if (and use-flags (> (string-length tmp-val) 0)) + (string-append "Fl " tmp-val + (if (exist? "long-opts") " , Fl -more-help" "") ) + (string-append (if (exist? "long-opts") "Fl -" "") "more-help" ) + ) \:+] + +Pass the extended usage information through a pager.[+: + +ENDIF no no-libopts + +.\" = = = = = = = = = = = = = = = = = +.\" save and load configuration +.\" = = = = = = = = = = = = = = = = = :+][+: + +IF (exist? "homerc") :+] +.It [+: + + IF (not (exist? "disable-save")) :+][+: + + (define tmp-val (get "save-opts-value" ">")) + (if (and use-flags (> (string-length tmp-val) 0)) + (string-append "Fl " tmp-val " Oo Ar cfgfile Oc" + (if (exist? "long-opts") + " , Fl -save-opts Oo Ns = Ns Ar cfgfile Oc" ) "") + (string-append (if (exist? "long-opts") "Fl -" "") + "save-opts Oo Ns = Ns Ar cfgfile Oc" ) + ) \:+] + +Save the option state to \fIcfgfile\fP. The default is the \fIlast\fP +configuration file listed in the \fBOPTION PRESETS\fP section, below. +The command will exit after updating the config file. +.It [+: + ENDIF saving not disabled :+][+: + + (define tmp-val (get "load-opts-value" "<")) + (define tmp-str (if (exist? "long-opts") "Fl -" "")) + + (if (and use-flags (> (string-length tmp-val) 0)) + (string-append "Fl " tmp-val " Ar cfgfile" + (if (exist? "long-opts") + (string-append " , " tmp-str "load-opts Ns = Ns Ar cfgfile" + " , " tmp-str "no-load-opts" ) + "") ) + (string-append tmp-str "load-opts Ns = Ns Ar cfgfile , " + tmp-str "no-load-opts" ) + ) \:+] + +Load options from \fIcfgfile\fP. +The \fIno-load-opts\fP form will disable the loading +of earlier config/rc/ini files. \fI\-\-no-load-opts\fP is handled early, +out of order.[+: + +ENDIF (exist? "homerc") + +.\" = = = = = = = = = = = = = = = = = +.\" version +.\" = = = = = = = = = = = = = = = = = :+][+: + +IF (exist? "version") :+] +.It [+: + + (define tmp-val (get "version-value" "v")) + (if (and use-flags (> (string-length tmp-val) 0)) + (string-append "Fl " tmp-val " Op Brq Ar v|c|n" + (if (exist? "long-opts") + " Fl -version Op Brq Ar v|c|n" ) "") + (string-append (if (exist? "long-opts") "Fl -" "") + "version Op Brq Ar v|c|n" ) + ) \:+] + +Output version of program and exit. The default mode is `v', a simple +version. The `c' mode will print copyright information and `n' will +print the full copyright notice.[+: +ENDIF :+] +.El +[+: + +(if formatted-doc + (shell (string-append + "fn='" (find-file cvt-cmd) + "'\ntest -f ${fn} || die '" cvt-cmd " not found'\n" + "${fn} <<\\_EndOfMdoc_ || die ${fn} failed in $PWD\n" + (out-pop #t) + "\n_EndOfMdoc_" )) ) :+][+: + +ENDDEF mk-options + +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +.\" M K - O P T I O N - P R E S E T S +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = :+][+: + +DEFINE mk-option-presets \:+] +Any option that is not marked as \fInot presettable\fP may be preset +by loading values from [+: + IF (. home-rc-files) + :+]configuration ("RC" or ".INI") file(s)[+: + IF (. environ-init) :+] and values from +[+: + ENDIF :+][+: + ENDIF :+][+: + IF (. environ-init) :+]environment variables named: +.nf + \fB[+:(. UP-PROG-NAME):+]_\fP or \fB[+:(. UP-PROG-NAME):+]\fP +.fi +.ad[+: + IF (. home-rc-files) :+] +The environmental presets take precedence (are processed later than) +the configuration files.[+: + ENDIF :+][+: + ELSE :+].[+: + ENDIF :+][+: + + CASE + (define rc-file + (get "rcfile" (string-append "." (get "prog-name") "rc")) ) + (count "homerc") :+][+: + + == "0" :+][+: + == "1" :+][+: + + CASE homerc :+][+: + ~~ '\.|\$HOME' :+] +The file "\fI[+: (string-append (get "homerc") "/" rc-file) +:+]\fP" will be used, if present.[+: + + == "" :+][+: + + * :+] +The \fIhomerc\fP file is "\fI[+:homerc:+]\fP", unless that is a directory. +In that case, the file "\fI[+: (. rc-file) :+]\fP" +is searched for within that directory.[+: + ESAC :+][+: + + * :+] +The \fIhomerc\fP files are [+: + FOR homerc ", " :+][+: + IF (last-for?) :+]and [+: + ENDIF :+]"\fI[+: homerc :+]\fP"[+: ENDFOR :+]. +If any of these are directories, then the file \fI[+: (. rc-file) :+]\fP +is searched for within those directories.[+: + ESAC :+][+: + +ENDDEF mk-option-presets + +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +.\" M K - E X I T - S T A T U S +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = :+][+: + +DEFINE mk-exit-status \:+] +One of the following exit values will be returned: +.Bl -tag +[+: +(ag-fprintf 0 ".It 0 \" (EXIT_%s)\"\n%s\n" + (string->c-name! (string-upcase (get "exit-name[0]" "SUCCESS"))) + (get "exit-desc[0]" "Successful program execution.") ) + +(define need-ex-noinput (exist? "homerc")) +(define need-ex-software #t) + +(ag-fprintf 0 ".It 1 \" (EXIT_%s)\"\n%s\n" + (string->c-name! (string-upcase (get "exit-name[1]" "FAILURE"))) + (get "exit-desc[1]" + "The operation failed or the command syntax was not valid.")) :+][+: + +FOR exit-desc (for-from 2) :+][+: + (if (= (for-index) 66) + (set! need-ex-noinput #f) + (if (= (for-index) 70) + (set! need-ex-software #f) )) + + (set! tmp-str (get (sprintf "exit-name[%d]" (for-index)) "* unnamed *")) + (sprintf ".It %d \" (EXIT_%s)\"\n%s\n" + (for-index) + (string-upcase (string->c-name! tmp-str)) + (get "exit-desc" "")) :+][+: +ENDFOR exit-desc :+][+: +(if need-ex-noinput + (emit ".It 66 \" (EX_NOINPUT)\" +A specified configuration file could not be loaded.\n")) + +(if need-ex-software + (emit ".It 70 \" (EX_SOFTWARE)\" +libopts had an internal operational error. Please report +it to autogen-users@lists.sourceforge.net. Thank you.\n")) + +(if (> (string-length fname-line) 1) + (emit fname-line)) :+] +.El +[+: + +ENDDEF mk-exit-status + +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +.\" M K - A U T H O R S +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = :+][+: + +DEFINE mk-authors :+][+: + + (define remove-authors #t) + + (set! tmp-val + (if (exist? "copyright.author") + (stack-join ",\n" "copyright.author") + (stack-join ",\n" "copyright.owner") )) + + (if (> (string-length tmp-val) 1) + (string-append tmp-val "\n") + (delete-file file-name)) + + :+][+: + +ENDDEF mk-authors + +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +.\" M K - B U G S +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = :+][+: + +DEFINE mk-bugs :+][+: + + (set! tmp-val (get "copyright.eaddr" (get "eaddr"))) + (if (> (string-length tmp-val) 1) + (string-append "Please send bug reports to: " tmp-val "\n") + (delete-file file-name) ) + :+][+: + +ENDDEF mk-bugs :+][+: + +DEFINE append-bugs :+][+: + + (set! tmp-val (get "copyright.eaddr" (get "eaddr"))) + (if (> (string-length tmp-val) 1) + (string-append "\n.Pp\nPlease send bug reports to: " tmp-val "\n") ) + :+][+: + +ENDDEF append-bugs + +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +.\" M K - C O P Y R I G H T (+ licensing) +.\" +.\" This section is guaranteed to be the last section in the man page +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = :+][+: + +DEFINE mk-copyright \:+] +Copyright (C) [+: copyright.date :+] [+: + (get "copyright.owner" (get "copyright.author" (get "copyright.eaddr"))) + :+] all rights reserved. +[+: CASE (get "copyright.type") :+][+: + = note :+][+: (get "copyright.text") :+][+: + == '' :+]This program has an unspecified license.[+: + + * :+][+: + (string-append "This program is released under the terms of " + (license-name (get "copyright.type")) ".") :+][+: + + ESAC :+] +[+: +ENDDEF mk-copyright + +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +.\" M K - N O T E S +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = :+][+: + +DEFINE mk-notes \:+] +This manual page was \fIAutoGen\fP-erated from the \fB[+: prog-name :+]\fP +option definitions. +[+: + +ENDDEF mk-notes + +.\" = = = = = APPEND TO IT: :+][+: + +DEFINE append-notes :+] +.Pp +This manual page was \fIAutoGen\fP-erated from the \fB[+: prog-name :+]\fP +option definitions.[+: + +ENDDEF append-notes + +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +.\" M K - E N V I R O N M E N T +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = :+][+: + +DEFINE mk-environment :+][+: + INVOKE append-environment :+][+: +ENDDEF mk-environment + +.\" = = = = = APPEND TO IT: :+][+: + +DEFINE append-environment :+] +[+:(. environ-text) :+][+: +ENDDEF append-environment + +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +.\" M K - F I L E S +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = :+][+: + +DEFINE mk-files :+][+: + INVOKE append-files :+][+: +ENDDEF mk-files + +.\" = = = = = APPEND TO IT: :+][+: + +DEFINE append-files :+] +[+:(. home-rc-text) :+][+: +ENDDEF append-files + +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +.\" E M I T A L I A S O P T +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = :+][+: + +DEFINE emit-alias-opt :+] +.It [+: + IF (exist? "value") :+][+: + IF (exist? "long-opts") \:+] + Fl [+:value:+] , Fl \-[+: name :+][+: + ELSE \:+] + Fl [+:value:+][+: + ENDIF (exist? "long-opts") :+][+: + + ELSE value does not exist -- named option only :+][+: + + IF (not (exist? "long-opts")) \:+] + [+: name :+][+: + ELSE \:+] + Fl \-[+: (get "name") :+][+: + ENDIF :+][+: + ENDIF :+] +This is an alias for the \fI--[+: aliases :+]\fR option.[+: + IF (exist? "deprecated") :+] +.sp +.B +NOTE: THIS OPTION IS DEPRECATED +[+: + ENDIF :+][+: +ENDDEF emit-alias-opt + +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +.\" E M I T F L A G T E X T +.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = :+][+: + +DEFINE emit-flag-text :+][+: + + (if (exist? "enable") + (set! opt-name (string-append (get "enable") "-" (get "name"))) + (set! opt-name (get "name")) ) + (if (exist? "disable") + (set! dis-name (string-append (get "disable") "-" (get "name"))) + (set! dis-name "") ) + + (set! opt-name (fix-optname opt-name)) + (if (> (string-length dis-name) 0) + (set! dis-name (fix-optname dis-name)) ) + + (if (not (exist? "arg-type")) + (set! opt-arg "") + (set! opt-arg (string-append "Ar " + (fix-optname (if (exist? "arg-name") + (get "arg-name") + (string-downcase! (get "arg-type")) )) + )) + ) + +:+] +.It [+: + IF (exist? "value") :+][+: + IF (exist? "long-opts") :+][+: + + # * * * * * * * * * * * * * * * * * * * * + * + * The option has a flag value (character) AND + * the program uses long options + * + \:+] + Fl [+:value:+][+: + IF (not (exist? "arg-type")) :+] , Fl -[+: + ELSE :+] [+:(. opt-arg):+] , Fl -[+: + ENDIF :+][+: (. opt-name) :+] [+: + IF (exist? "arg-type") :+][+: + ? arg-optional Oo Ns = Ns + :+] [+: (. opt-arg) :+] [+: + arg-optional Oc :+][+: + ENDIF :+][+: + IF (exist? "disable") :+] , Fl -[+:(. dis-name):+][+: + ENDIF :+][+: + + ELSE :+][+: + + # * * * * * * * * * * * * * * * * * * * * + * + * The option has a flag value (character) BUT + * the program does _NOT_ use long options + * + \:+] + Fl [+:value:+] [+: + IF (exist? "arg-type") :+][+: + arg-optional Oo :+] [+:(. opt-arg):+] [+: + arg-optional Oc :+] [+: + ENDIF " :+][+: + ENDIF (exist? "long-opts") :+][+: + + + ELSE value does not exist -- named option only :+][+: + + IF (not (exist? "long-opts")) :+][+: + + # * * * * * * * * * * * * * * * * * * * * + * + * The option does not have a flag value (character). + * The program does _NOT_ use long options either. + * Special magic: All arguments are named options. + * + \:+] + [+: (. opt-name) :+] [+: + IF (exist? "arg-type") :+] [+: + ? arg-optional ' Oo = Ns' ' Ns = Ns ' + :+] [+:(. opt-arg) :+] [+: + arg-optional Oc :+] [+: + ENDIF:+][+: + IF (exist? "disable") :+] , Fl -[+:(. dis-name):+][+: + ENDIF :+][+: + + + ELSE :+][+: + # * * * * * * * * * * * * * * * * * * * * + * + * The option does not have a flag value (character). + * The program, instead, only accepts long options. + * + \:+] + Fl -[+: (. opt-name) :+] [+: + + IF (exist? "arg-type") :+][+: + arg-optional Oo :+] Ns = Ns [+:(. opt-arg):+] [+: + arg-optional Oc :+][+: + ENDIF :+][+: + + (if (exist? "disable") + (string-append ", Fl \\-" dis-name) + "") :+][+: + ENDIF :+][+: + ENDIF :+] +[+: (get "descrip" "") :+].[+: + + IF (exist? "min") :+] +This option is required to appear.[+: + ENDIF :+][+: + + IF (exist? "max") :+] +This option may appear [+: + IF % max (= "%s" "NOLIMIT") + :+]an unlimited number of times[+:ELSE + :+]up to [+: max :+] times[+: + ENDIF:+].[+: + ENDIF:+][+: + + IF (exist? "disable") :+] +The \fI[+:(. dis-name):+]\fP form will [+: + IF (exist? "stack-arg") + :+]clear the list of option arguments[+: + ELSE :+]disable the option[+: + ENDIF :+].[+: + ENDIF:+][+: + + IF (exist? "enabled") :+] +This option is enabled by default.[+: + ENDIF :+][+: + + IF (exist? "no-preset") :+] +This option may not be preset with environment variables +or in initialization (rc) files.[+: + ENDIF :+][+: + + IF (and (exist? "default") named-mode) :+] +This option is the default option.[+: + ENDIF :+][+: + + IF (exist? "equivalence") :+] +This option is a member of the [+:equivalence:+] class of options.[+: + ENDIF :+][+: + + IF (exist? "flags-must") :+] +This option must appear in combination with the following options: +[+: FOR flags-must ", " :+][+:flags-must:+][+:ENDFOR:+].[+: + ENDIF :+][+: + + IF (exist? "flags-cant") :+] +This option must not appear in combination with any of the following options: +[+: FOR flags-cant ", " :+][+:flags-cant:+][+:ENDFOR:+].[+: + ENDIF :+][+: + + + IF (~* (get "arg-type") "key|set") :+] +This option takes a keyword as its argument[+: + + IF (=* (get "arg-type") "set") + +:+] list. Each entry turns on or off +membership bits. The bits are set by name or numeric value and cleared +by preceding the name or number with an exclamation character ('!'). +They can all be cleared with the magic name \fInone\fR and they can all be set +with +.IR all . +A single option will process a list of these values.[+: + + ELSE + +:+]. The argument sets an enumeration value that can +be tested by comparing them against the option value macro.[+: + + ENDIF + +:+] +The available keywords are: +.in +4 +.nf +.na +[+: (shellf "${CLexe} --indent='' --spread=1 -W50 <<_EOF_\n%s\n_EOF_" + (join "\n" (stack "keyword")) ) :+] +.fi +or their numeric equivalent. +.in -4[+: (if (exist? "arg-default") "\n.sp" ) :+][+: + + ELIF (=* (get "arg-type") "num") :+] +This option takes an integer number as its argument.[+: + + IF (exist? "arg-range") :+] +The value of +.[+:(. opt-arg):+] +is constrained to being: +.in +4 +.nf +.na[+:FOR arg_range ", or" :+] +[+: (shell " +range='" (get "arg-range") "' + +case \"X${range}\" in +X'->'?* ) + echo \"less than or equal to\" ` + echo $range | sed 's/->//' ` ;; + +X?*'->' ) + echo \"greater than or equal to\" ` + echo $range | sed 's/->.*//' ` ;; + +X?*'->'?* ) + echo \"in the range \" ` + echo $range | sed 's/->/ through /' ` ;; + +X?* ) + echo exactly $range ;; + +X* ) echo $range is indeterminate +esac" ) :+][+: + ENDFOR arg-range " :+] +.fi +.in -4[+: + + ENDIF arg-range exists :+][+: + + ENDIF arg-type key/set/num :+][+: + + IF (exist? "arg-default") :+] +The default +.[+: (. opt-arg) :+] +for this option is: +.ti +4 + [+: (join " + " (stack "arg-default" )) :+][+: + ENDIF :+] +.sp +[+: + (if (exist? "doc") (string-substitute (get "doc" "") "\n\n" "\n.sp\n") + "This option has not been fully documented." ) :+][+: + IF (exist? "deprecated") :+] +.sp +.B +NOTE: THIS OPTION IS DEPRECATED +[+: + ENDIF :+][+: + +ENDDEF emit-flag-text :+][+: + +DEFINE mk-synopsis :+][+: + (out-push-new file-name) \:+] +.Sh SYNOPSIS +.Nm[+: + + IF (. use-flags) :+][+: + IF (exist? "long-opts") :+] +.\" Mixture of short (flag) options and long options +.Op Fl flags +.Op Fl flag Op Ar value +.Op Fl \-option-name Ns Oo Oo Ns "=| " Oc Ns Ar value Oc +[+: ELSE no long options: :+] +.Op Fl flags +.Op Fl flag Op Ar value +[+: ENDIF + :+][+: + ELIF (exist? "long-opts") + :+] +.Op Fl \-option-name +.Op Fl \-option-name Ar value +[+: + + ELIF (not (exist? "argument")) :+] +.Op Ar option\-name Ar value +.Pp +All arguments are named options. +[+: + ENDIF :+][+: + + IF (exist? "argument") :+][+: + argument :+][+: + + IF (exist? "reorder-args") :+] +.Pp +Operands and options may be intermixed. They will be reordered. +[+: ENDIF :+][+: + + ELIF (or (exist? "long-opts") use-flags) + +:+] +.Pp +All arguments must be options. +[+: + + ENDIF :+][+: + + IF (exist? "main") :+][+: + CASE main.main-type :+][+: + == shell-process :+] +.Pp +This program will emit text that is expected to be evaluated by +a Bourne-compatible shell, thus digesting the options for the script.[+: + + == shell-parser :+] +.Pp +This program is designed to produce output suitable for inclusion +into a shell script that will parse the options described.[+: + + == for-each :+] +.Pp +The operands that this program operates on may be specified either +on the command line or read from standard input, one per line. +In that input, leading and trailing white space is stripped, +blank lines are ignored[+: + + IF (define comment-char (get "comment-char" "#")) + (> (string-length comment-char) 1) \:+] + and lines beginning with the character +.I [+: (substring comment-char 1 0):+] +are treated as comments[+: + ENDIF :+].[+: + + IF (exist? "interleaved") :+] +Options may be interleaved with operands both on the command +line and when operands are read from standard input.[+: + ENDIF interleaved + +:+] +Standard input may not be a terminal.[+: + + ESAC main-type :+][+: + ENDIF main exists :+] +.Pp +[+: + +FOR explain "\n.Pp\n" :+][+: + (get "explain" "") :+][+: +ENDFOR :+][+: + +(out-pop) :+][+: + +ENDDEF mk-synopsis + +.\" cmd-doc.tlib ends here \:+] diff --git a/autoopts/tpl/def2pot.tpl b/autoopts/tpl/def2pot.tpl new file mode 100644 index 0000000..29f7acb --- /dev/null +++ b/autoopts/tpl/def2pot.tpl @@ -0,0 +1,144 @@ +[= AutoGen5 template pot =][= +# +# this template can be used to generate .pot file for the +# option definition files for these templates: +# aginfo.tpl, agman-cmd.tpl, agmdoc-cmd.tpl +# + +# This file is part of AutoOpts, a companion to AutoGen. +# AutoOpts is free software. +# AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +# +# AutoOpts is available under any one of two licenses. The license +# in use must be one of these two and the choice is under the control +# of the user of the license. +# +# The GNU Lesser General Public License, version 3 or later +# See the files "COPYING.lgplv3" and "COPYING.gplv3" +# +# The Modified Berkeley Software Distribution License +# See the file "COPYING.mbsd" +# +# These files have the following sha256 sums: +# +# 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +# 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +# 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +====================== FUNCTIONS BEGIN =======================][= +DEFINE genmsg =][= + + IF (set! msg-id (get "msgid")) + (set! msg-text (get-text msg-id)) + (< 0 (string-length msg-text)) =] +#: [=(def-file-line msg-id "%s:%d") =] +msgid [= (c-string msg-text) =] +msgstr "" +[=ENDIF =][= +ENDDEF =][= + +DEFINE genmsg2 =][= + IF (set! msg-text (get "msgid")) + (string-length msg-text) =] +#: [=(def-file-line msg-text "%s:%d") =] +msgid [= (c-string msg-text) =] +msgstr "" +[=ENDIF =][= +ENDDEF =][= + +(define get-text (lambda (nm) (shell (string-append + + "{ sed 's/@[a-z]*{\\([^}]*\\)}/\\1/g' | " + "${CLexe} --fill -I0 -W72\n" + "} <<\\_EODesc_\n" + (get nm) + "\n_EODesc_" +)))) +(define msg-text "") +(define msg-id "") + + ;;# START-BUILDTREE-ISMS + ;; + (shell "CLexe=${AGexe%/agen5/*}/columns/columns + test -x \"${CLexe}\" || { + CLexe=${AGexe%/autogen}/columns + test -x \"${CLexe}\" || die 'columns program is not findable' + }") + +=][= # END-BUILDTREE-ISMS + +(shell "CLexe=`echo ${AGexe} | sed 's@/autogen@/columns@'` + test -x \"${CLexe}\" || CLexe=`which columns`") + +# END-INSTALL-ONLY-CODE =][= # + +;; ==================== FUNCTIONS END =========================== + +;; pot file header and comment info \=] +# localization template (.pot) for [= (def-file) =] of [= prog-name =], +# this file is used to generate localized manual for [= prog-name =]. +# Copyright (C) [= (shell "date +%Y") =][= + + IF (exist? "copyright") =] +# This file is distributed under the terms of the +# [= (license-name (get "copyright.type")) \=] + +# The program owners may be reached via: +# [=(shellf + "author='%s' email='%s' date=`date +%%Y` + printf '%%s <%%s>, %%s.' \"$author\" \"$email\" \"${date}\"" + (get "copyright.owner" "FIRST AUTHOR") + (get "copyright.eaddr" "EMAIL@ADDRESS") +)=][= ENDIF =] +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: [= prog-name =] [= version =]\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: [= (shell "date +\"%F %R%z\"") =]\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" +[= +genmsg msgid=prog-title =][= + +IF (exist? "full-usage") =][= + genmsg msgid=full-usage =][= +ELSE =][= + FOR flag =][= + genmsg msgid=descrip =][= + genmsg msgid=doc =][= + ENDFOR =][= +ENDIF =][= + +IF (exist? "short-usage") =][= + genmsg msgid=short-usage =][= +ENDIF =][= + +FOR explain =][= + genmsg msgid=explain =][= +ENDFOR =][= + +FOR detail =][= + genmsg msgid=detail =][= +ENDFOR =][= + +CASE (get "copyright.type") =][= + = note =][= + == '' =][= + * =][= + genmsg2 msgid=(string-append + "This program is released under the terms of " + (license-name (get "copyright.type")) ".") + =][= +ESAC =][= + +genmsg msgid=option-info =][= +genmsg msgid=argument =][= +genmsg msgid=man-doc =][= +genmsg msgid=copyright.text =] diff --git a/autoopts/tpl/getopt.tpl b/autoopts/tpl/getopt.tpl new file mode 100644 index 0000000..880583b --- /dev/null +++ b/autoopts/tpl/getopt.tpl @@ -0,0 +1,510 @@ +[+ AutoGen5 Template -*- Mode: C -*- + + h=%s-temp.h + c=%s-temp.c +][+ + +`stamp=\`sed 's,.*stamp: *",,;s,".*,,' <<\_EOF_ + Time-stamp: "2018-08-08 17:59:09 bkorb" +_EOF_ +\` ` +][+ + +;; This file is part of AutoOpts, a companion to AutoGen. +;; AutoOpts is free software. +;; AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +;; +;; AutoOpts is available under any one of two licenses. The license +;; in use must be one of these two and the choice is under the control +;; of the user of the license. +;; +;; The GNU Lesser General Public License, version 3 or later +;; See the files "COPYING.lgplv3" and "COPYING.gplv3" +;; +;; The Modified Berkeley Software Distribution License +;; See the file "COPYING.mbsd" +;; +;; These files have the following sha256 sums: +;; +;; 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +;; 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +;; 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + + (if (not (exist? "settable")) + (error "'settable' must be specified globally for getopt_long\n")) + (if (not (exist? "no-libopts")) + (error "'no-libopts' must be specified globally to use getopt\n")) + (define prog-name (string->c-name! (get "prog-name"))) + (define PROG-NAME (string-upcase prog-name)) + (out-move (string-append "getopt-" prog-name "." (suffix))) + (dne " * " "/* " ) +] + *[+ + + IF (exist? "copyright") +] + * +[+ + CASE copyright.type +][+ + == "" +] * licensing type not specified.[+ + = note +][+ (prefix " * " (get "copyright.text")) +][+ + * +][+ + (license-description (get "copyright.type") prog-name " * " + (get "copyright.owner")) +][+ + ESAC +][+ + ENDIF +] + * + * Last template edit: [+ `echo $stamp` +] + */[+ +CASE (suffix) +][+ +== h +][+ + (define header-file (out-name)) + (out-push-new) \+] +{ +[+ # START-BUILDTREE-ISMS: + +# The following code is sedded away in install-hook.sh. +# The goal is to ensure we use build tree templates in testing mode, and +# remove them when installing this file. + +\+] + aobdir=`echo ${AGexe} | sed 's@/agen5/.*$@@'`/autoopts + agopts=-L`dirname [+ (tpl-file #t) +]`' ' + test "X-L$aobdir/tpl " = "X$agopts" || \ + agopts="-L${aobdir}/tpl $agopts" + tarfile=`set -- ${aobdir}/libopts*.tar.* + test -f $1 || { + cd ${aobdir} + ${MAKE:-make} libsrc || exit 1 + cd - + set -- ${aobdir}/libopts*.tar.* + test -f $1 || die 'libopts tarball not built' + } >&2 + echo $1`[+ + +# END-BUILDTREE-ISMS the following code is for installed version: + agopts= + aocfg=`echo ${AGexe} | sed 's@/[^/]*$@@'`/autoopts-config + test -x "${aocfg}" || aocfg=`which autoopts-config` + tarfile=`${aocfg} libsrc` + +# END-INSTALL-ONLY-CODE +] + if test -n "${AG_Tracing}" + then + AG_Dep_File=`dirname "${AG_Tracing}"`/ao-[+ (base-name) +].dep + agopts="${agopts}-MF${AG_Dep_File} -MT${AG_Dep_File%.dep}.targ" + fi + cmd="${AGexe} -b[+(base-name)+] ${agopts} -Toptions.tpl [+(def-file)+]" + $cmd || die "COMMAND FAIL: $cmd" + def_hdr=[+ (base-name) +].h + sed 's@@"[+ (. header-file) + +]"@' $def_hdr > XXX-$$ + mv -f XXX-$$ $def_hdr + hdrfile=`gunzip -c $tarfile | tar tf - | fgrep /autoopts/options.h` + gunzip -c $tarfile | tar xf - $hdrfile + exec 3< $hdrfile + untardir=`echo $hdrfile | sed 's@/.*@@'` +} >&2 + +while : +do + IFS= read -r -u3 line || die "no header guard in $hdrfile" + case "$line" in + *AUTOOPTS_OPTIONS_H_GUARD ) break ;; + esac +done +echo + +echo "$line" +IFS= read -r -u3 line || die "short $hdrfile" +case "$line" in +'#define AUTOOPTS_OPTIONS_H_GUARD'* ) : ;; +*) die "invalid header guard in $hdrfile" ;; +esac +echo "$line" +echo '#include "[+ +(if (exist? "config-header") + (get "config-header") + (error "getopt template requires a \"config-header\" attribute") +) +]"' + +while : +do + IFS= read -r -u3 line || die "no CPLUSPLUS_CLOSER in $hdrfile" + case "$line" in + *'Versions where in various fields first appear'* ) break ;; + esac + echo "$line" +done + +cat <<- _EOF_ + * option loop function + */ + #ifdef __cplusplus + #define CPLUSPLUS_OPENER extern "C" { + CPLUSPLUS_OPENER + #define CPLUSPLUS_CLOSER } + #else + #define CPLUSPLUS_CLOSER + #endif + + extern int process_[+(. prog-name)+]_opts(int argc, char ** argv); + extern void optionPrintVersion(tOptions * opts, tOptDesc * od); + extern void optionUsage(tOptions * opts, int exit_code); + + CPLUSPLUS_CLOSER + _EOF_ + +sed '1,/^CPLUSPLUS_CLOSER/d' <&3 +exec 3<&- +rm -rf $untardir +[+ (shell (out-pop #t)) +] +[+ == c +] +#include "[+ (. header-file) +]" + +#include + +#include +#include +#include +#include <[+ (if (exist? "long-opts") "getopt" "unistd") +].h> +#include "[+ (base-name) +].h" + +#ifndef DIRCH +# if defined(_WIN32) && !defined(__CYGWIN__) +# define DIRCH '\\' +# else +# define DIRCH '/' +# endif +#endif[+ + +IF (exist? "long-opts") +] + +/* + * getopt_long option descriptor + */ +static struct option a_long_opts[] = {[+ + + FOR flag +][+ + (sprintf + + "\n { %-20s %d, NULL, VALUE_OPT_%s }," + (string-append (c-string (get "name")) ",") + (if (exist? "arg-type") 1 0) + (string-upcase (string->c-name! (get "name"))) + ) +][+ + + ENDFOR flag + ++] + { "help", 0, NULL, VALUE_OPT_HELP },[+ +IF (exist? "version") +] + { "version", 0, NULL, VALUE_OPT_VERSION },[+ +ENDIF +] + { NULL, 0, NULL, 0 } +}; +[+ ENDIF +] +/* + * Option flag character list + */ +static char z_opts[] = "[+ # close quote for emacs " +][+ + FOR flag +][+ + CASE value +][+ + ~ [!-~] +][+ value +][+ + + CASE arg-type +][+ + =* str +]:[+ + == "" +][+ + * +][+ (error (sprintf + "error in %s opt: The only allowed arg type is 'string'\n" + (get "name") )) +][+ + ESAC +][+ + + ESAC +][+ + + ENDFOR flag +][+ + + IF (not (exist? "help-value")) +]?[+ + ELSE +][+ + CASE help-value +][+ + == "" +][+ + == '"' +]\"[+ + * +][+ help-value +][+ + ESAC +][+ + ENDIF +][+ + + IF (exist? "version") +][+ + IF (not (exist? "version-value")) +]v[+ + ELSE +][+ + CASE version-value +][+ + == "" +][+ + == '"' +]\"[+ + * +][+ version-value +][+ + ESAC +][+ + ENDIF +][+ + ENDIF +][+ + + (define help-opt + (if (exist? "long-opts") "--help" + (if (not (exist? "flag.value")) "help" + (if (exist? "help-value") (string-append "-" (get "help-value")) + "-?" ))) ) + ;; open quote for emacs " +]"; + +/* + * AutoOpts library replacement routines: + */ +noreturn void +optionUsage (tOptions * pOptions, int status) +{ + if (status != 0) + fprintf (stderr, _("Try `%s [+(. help-opt)+]' for more information.\n"), + [+ (. prog-name) +]Options.pzProgName); + else + { + fputs (_([+ + INVOKE emit-usage-string usage-type = short +]), stdout); + } + + exit (status); +} + +noreturn void +optionPrintVersion (tOptions * pOptions, tOptDesc * pOptDesc) +{ + char const * pz_by = + _("[+ # " +][+ + + (sprintf "%s%s %s" prog-name + (if (exist? "prog-group") + (sprintf " (%s)" (get "prog-group")) + "" ) + (get "version") ) +]\n\ +Written by [+(join ", " (stack "copyright.author"))+].\n\n\ +Copyright (C) [+ copyright.date +] [+ copyright.owner +]\n[+ + +CASE copyright.type +][+ +*~ [l]*gpl +]\ +This is free software; see the source for copying conditions. There is NO\n\ +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.[+ + +ESAC +][+ # " +]\n"); + + fputs (pz_by, stdout); + exit (EXIT_SUCCESS); +} + +/* + * If an option appears more often than is allowed, ... + */ +static void +usage_too_many (tOptDesc* pOptDesc) +{ + char const * pz = + _("[+(. prog-name) + +] error: the '%s' option appears more than %d times\n"); + fprintf (stderr, pz, pOptDesc->pz_Name, pOptDesc->optMaxCt); + USAGE(EXIT_FAILURE); +} +[+ + IF (exist? "flag.min") ++] +/* + * There is at least one option that must appear. + */ +static void +usage_too_few (tOptDesc* pOptDesc) +{ + char const * pz = + _("[+(. prog-name) + +] error: the '%s' option must appear %d times\n"); + fprintf (stderr, pz, pOptDesc->pz_Name, pOptDesc->optMinCt); + USAGE(EXIT_FAILURE); +} +[+ + ENDIF ++][+ + IF (exist? "flag.flags-cant") ++] +/* + * There is at least one pair of options that may not appear together + * on the command line. + */ +static void +usage_cannot (char const* pz_what, char const* pz_cant) +{ + char const * pz = + _("[+(. prog-name) + +] error: the `%s' option conflicts with the `%s' option.\n"); + fprintf (stderr, pz, pz_what, pz_cant); + USAGE(EXIT_FAILURE); +} +[+ + ENDIF ++][+ + IF (exist? "flag.flags-must") ++] +/* + * There is at least one pair of options that are required to appear + * together on the command line. + */ +static void +usage_must (char const* pz_what, char const* pz_must) +{ + char const * pz = + _("[+(. prog-name) + +] error: the `%s' option requires the `%s' option.\n"); + fprintf (stderr, pz, pz_what, pz_must); + USAGE(EXIT_FAILURE); +} +[+ + ENDIF ++] +/* + * Process the options for the "[+(. prog-name)+]" program. + * This function was generated to use the getopt[+ + (if (exist? "long-opts") "_long(3GNU)" "(3posix)") +] function. + * There are [+ (+ (count "flag") (if (exist? "version") 2 1)) + +] options for this program, + * including "help (usage)"[+ + IF (exist? "version") +] and "version"[+ ENDIF +]. + */ +int +process_[+(. prog-name)+]_opts (int argc, char** argv) +{ + { + char * pz_prog = strrchr (argv[0], DIRCH); + /* + * This violates the const-ness of the pzProgName field. + * The const-ness is to prevent accidents. This is not accidental. + */ + char ** pp = VOIDP(&([+ (. prog-name) +]Options.pzProgName)); + + if (pz_prog != NULL) + pz_prog++; + else + pz_prog = argv[0]; + *pp = pz_prog; + } + + for (;;) { + switch ([+ + +IF (exist? "long-opts") + +]getopt_long (argc, argv, z_opts, a_long_opts, NULL)[+ +ELSE +]getopt (argc, argv, z_opts)[+ +ENDIF +]) { + case -1: goto leave_processing; + case 0: break;[+ + FOR flag +][+ + (define OPT-NAME (string-upcase! (string->c-name! (get "name")))) ++] + + case VALUE_OPT_[+ (. OPT-NAME) +]:[+ + + IF (not (exist? "max")) +] + if (HAVE_OPT([+(. OPT-NAME)+])) + usage_too_many (&DESC([+(. OPT-NAME) +]));[+ + + ELIF (not (= (get "max") "nolimit")) +] + if (DESC([+(. OPT-NAME)+]).optOccCt++ >= DESC([+(. OPT-NAME)+]).optMaxCt) + usage_too_many (&DESC([+(. OPT-NAME) +]));[+ + ENDIF ++] + SET_OPT_[+(. OPT-NAME)+][+ (if (exist? "arg-type") "(optarg)") +]; + break;[+ + + ENDFOR +] + + case VALUE_OPT_HELP: + USAGE(EXIT_SUCCESS); + /* NOTREACHED */ +[+ IF (exist? "version") +] + case VALUE_OPT_VERSION: + optionPrintVersion (&[+ (. prog-name) +]Options, &DESC(VERSION)); + /* NOTREACHED */ +[+ ENDIF +] + default: + USAGE(EXIT_FAILURE); + } + } leave_processing:; +[+ +FOR flag +][+ + IF + (set! OPT-NAME (string-upcase! (string->c-name! (get "name")))) + (define check-have-opt (or (exist? "flags-cant") (exist? "flags-must"))) + check-have-opt ++] + if (HAVE_OPT([+ (. OPT-NAME) +])) {[+ + + FOR flags-cant +] + if (HAVE_OPT([+ (string-upcase! (string->c-name! (get "flags-cant"))) +])) + usage_cannot (DESC([+ (. OPT-NAME) +]).pz_Name, DESC([+ + (string-upcase! (string->c-name! (get "flags-cant"))) +]).pz_Name);[+ + ENDFOR cant +][+ + + FOR flags-must +] + if (! HAVE_OPT([+(string-upcase! (string->c-name! (get "flags-must")))+])) + usage_must (DESC([+ (. OPT-NAME) +]).pz_Name, DESC([+ + (string-upcase! (string->c-name! (get "flags-must"))) +]).pz_Name);[+ + ENDFOR must +][+ + + IF (exist? "min") +][+ + IF (> (string->number (get "min" "0")) 1) +] + if (DESC([+(. OPT-NAME)+]).optOccCt < DESC([+(. OPT-NAME)+]).optMinCt) + usage_too_few (&DESC([+(. OPT-NAME) +]));[+ + + ENDIF +][+ + ENDIF +] + } +[+ + + ENDIF + ++][+ + + IF (exist? "min") +][+ + IF (. check-have-opt) ++] else[+ + + ELSE ++] + if ([+ # + We have a minimum count, but we have not checked for option existence + yet because there are no option interdependencies. We must therefore + now check to see if the option has appeared the required number of + times. In the absence of a max count, our limit must be one and we + only check for presence. If a max count exists, then we will also + have kept the occurrence count. Check that against the limit. +][+ + + IF (not (exist? "max")) + +]! HAVE_OPT([+ (. OPT-NAME) +])[+ + ELSE max ct exists + +]DESC([+(. OPT-NAME)+]).optOccCt < DESC([+(. OPT-NAME)+]).optMinCt[+ + ENDIF +])[+ + + ENDIF +] + usage_too_few (&DESC([+(. OPT-NAME) +])); +[+ + ENDIF +][+ +ENDFOR +] + return 0; +} +[+ ESAC +][+ + +DEFINE emit-usage-string +][+ + + (out-push-new) +][+ + INCLUDE "usage.tlib" +][+ + (out-suspend "use-text") + (out-push-new) \+] +sed -e '/version information/s/ -v \[arg\]/ -v /' \ + -e '/: illegal option --/d' \ + -e 's/ --version\[=arg\]/ --version /' <<_EOF_ +[+ (out-resume "use-text") (out-pop #t) +] +_EOF_[+ + + (kr-string (string-append (shell (out-pop #t)) "\n" ) + ) + ++][+ + +ENDDEF + +# end of getopt.tpl \+] diff --git a/autoopts/tpl/gpl.lic b/autoopts/tpl/gpl.lic new file mode 100644 index 0000000..f728389 --- /dev/null +++ b/autoopts/tpl/gpl.lic @@ -0,0 +1,19 @@ +Copyright (C) , all rights reserved. +This is free software. It is licensed for use, modification and +redistribution under the terms of the GNU General Public License, +version 3 or later + + is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + + is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program. If not, see . + +the GNU General Public License, version 3 or later diff --git a/autoopts/tpl/gplv2.lic b/autoopts/tpl/gplv2.lic new file mode 100644 index 0000000..7c6ed85 --- /dev/null +++ b/autoopts/tpl/gplv2.lic @@ -0,0 +1,19 @@ +Copyright (C) , all rights reserved. +This is free software. It is licensed for use, modification and +redistribution under the terms of the GNU General Public License, +version 2 + + is free software: you can redistribute it and/or modify it +under the terms of version 2 of the GNU General Public License, +as published by the Free Software Foundation. + + 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, +version 2, along with this program. +If not, see . + +the GNU General Public License, version 2 diff --git a/autoopts/tpl/lgpl.lic b/autoopts/tpl/lgpl.lic new file mode 100644 index 0000000..92373ab --- /dev/null +++ b/autoopts/tpl/lgpl.lic @@ -0,0 +1,19 @@ +Copyright (C) , all rights reserved. +This is free software. It is licensed for use, modification and +redistribution under the terms of the GNU Lesser General Public License, +version 3 or later + + is free software: you can redistribute it and/or modify it +under the terms of the GNU Lesser General Public License as published +by the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + + 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 Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see ."; + +the GNU Lesser General Public License, version 3 or later diff --git a/autoopts/tpl/lgplv2.lic b/autoopts/tpl/lgplv2.lic new file mode 100644 index 0000000..70233f3 --- /dev/null +++ b/autoopts/tpl/lgplv2.lic @@ -0,0 +1,20 @@ +Copyright (C) , all rights reserved. +This is free software. It is licensed for use, modification and +redistribution under the terms of the GNU Lesser General Public License, +version 2 or later + +The 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, see + + +the GNU Lesser General Public License, version 2.0 or later diff --git a/autoopts/tpl/man2mdoc.pl b/autoopts/tpl/man2mdoc.pl new file mode 100755 index 0000000..0816c21 --- /dev/null +++ b/autoopts/tpl/man2mdoc.pl @@ -0,0 +1,304 @@ +#!/usr/bin/perl + +## man2mdoc.pl -- Convert man tags to mdoc tags +## +## Author: Harlan Stenn +## +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +use strict; + +my ($taglist , $optlistold, $paraold, $parafirstval,$List, + $indentation,$isindentated); + +my ($line); + +$isindentated = 0; #this variable is used check the indentation +$indentation = 0; #this variable is used to set the indentation if given +$List = 0; +$parafirstval = 0; +$paraold = 0; +$taglist = 0; ### 1 = taglist, 0 = other list types except taglist +$optlistold = 0; ## 1 = previous list entry was there, 0 = not + +while ($line = ) +{ + if ($line !~ /^\./ ) { + if ($line =~ /[\\fB|\\fI]/) { + MakeMacro($line); + print "\n"; + next; + } + + print $line; + next; + } + + $line =~ s/^\.//; + + next + if ($line =~ /\\"/); + + $line = ParseMacro($line); + + print($line) + if (defined $line); +} + +sub ParseMacro +{ + my ($line) = @_; + + my (@words,$retval); + $retval = ''; + @words = split(/\s+/,$line); + + while($_ = shift (@words)) { + if (/^sp$/ || /^ne$/ || /^na$/|| /^rt$/|| /^mk$/|| /^ad$/) { + last; + } + + if (/^RS$/) { + $List = 1; + # this is to check whether that indentation value is given, + # if it is not given tha means we have to use default indentation, + # if it is given we need to check for that value + # + $isindentated = scalar(@words); + + if ($isindentated) { + if ($_ = shift (@words)) + { + $indentation = 1; + last; + } + $indentation = 0; + last; + } + $indentation = 1; + last; + } + + if (/^IP$/ && $List) { + if (!$optlistold) { + $optlistold = 1; + $taglist = 1; + + if ($indentation) { + $retval .= ".Bl -tag -offset indent -compact\n"; + } else { + $retval .= ".Bl -tab -offset 0n -compact\n"; + } + print $retval; + $words[0] =~ s/\\fB/ Nm /; + $words[0] =~ s/\\fI/ Ar /; + $words[0] =~ s/\\fR/ /g; + + print ".It ".$words[0]."\n"; + last; + + } + + if ($optlistold) { + $words[0] =~ s/\\fB/ Nm /; + $words[0] =~ s/\\fI/ Ar /; + $words[0] =~ s/\\fR/ /g; + print ".It ".$words[0]."\n"; + last; + } + } + + if (/^TP$/ && $List) { + if (!$optlistold) + { + $optlistold = 1; + $taglist = 1; + + if ($indentation) { + $retval .= ".Bl -tag -offset indent -compact\n"; + } else { + $retval .= ".Bl -tab -offset 0n -compact\n"; + } + print $retval; + $retval = ; + + $retval =~ s/\\fB/ Nm /; + $retval =~ s/\\fI/ Ar /; + $retval =~ s/\\fR/ /g; + + print ".It ".$retval."\n"; + last; + } + + if ($optlistold) { + $retval = ; + $retval =~ s/\\fB/ Nm /; + $retval =~ s/\\fI/ Ar /; + $retval =~ s/\\fR/ /g; + print ".It ".$retval."\n"; + last; + } + } + + if (/^RE$/) { + $indentation = 0; + $optlistold = 0; + $isindentated = 0; + + $optlistold = 0; + + } + + if (/^IP$/ && !$List) + { + if (!$optlistold && $words[0] =~ /^\\\(bu$/) { + $optlistold = 1; + $retval .= ".Bl -bullet"."\n"; + print $retval; + print ".It \n"; + last; + } + + + if (!$optlistold && $words[0] =~ /^-$/) { + $optlistold = 1; + $retval .= ".Bl -dash \n"; + print $retval; + print ".It \n"; + last; + } + + + if (!$optlistold && $words[0] =~ /^[1-9]\.$/) { + $optlistold = 1; + $retval .= ".Bl -enum \n"; + print $retval; + print ".It \n"; + last; + + } + + if (!$optlistold && $words[0] !~ /[0-9|-|(br]/) { + $optlistold = 1; + $taglist = 1; + $retval .= ".Bl -tag \n"; + print $retval; + print ".It ".$words[0]."\n"; + last; + } + + if (!$optlistold) { + $optlistold = 1; + $retval .= ".Bl -item \n"; + print $retval; + print ".It \n"; + last; + + } + + if ($optlistold) { + print ".It \n"; + last + } + } + + if ($optlistold && ! /^IP$/ ) { + $optlistold = 0; + print ".El \n"; + } + + if (/^TP$/) { + $parafirstval = 1; + + if (!$paraold) { + $retval .= ".Bl -tag \n"; + print $retval; + print ".It "; + $paraold = 1; + last; + } + + if ($paraold) { + print ".It "; + $paraold = 1; + last; + } + } + + #text bolding (mdoc : .Nm ntpq) (man : .B ntpq ) + if (/^RS$/) { + $List = 1; + } + + if (/^B$/) { + $retval .= ".Nm ".join(' ',@words)."\n"; + print $retval; + } + + #text bolding () + if (/\\fB/) { + $retval = $_; + $retval =~ s/[\\fB|\\fP]//g; + print ".Nm ".$retval."\n"; + } + + if (/\\fI/) { + $retval = $_; + $retval =~ s/[\\fI|\\fP]//g; + print ".Em ".$retval."\n"; + } + + if (/^I$/) { + $retval .= ".Em ".join(' ',@words)."\n"; + print $retval; + } + + if (/^PP$/) { + print "\n"; + } + + if (/^LP$/) { + print "\n"; + } + } +} + +sub MakeMacro +{ + my (@words); + @words = split(/\s+/,$line); + while($_ = shift (@words)) + { + if (/\\fB/ or /\\fI/) { + print "\n"; + $_ =~ s/\\fB/\.Nm /; + $_ =~ s/\\fI/\.Ar /; + $_ =~ s/\\fR//g; + + print $_; + print"\n"; + next; + } + + print $_." "; + } +} diff --git a/autoopts/tpl/man2texi.sh b/autoopts/tpl/man2texi.sh new file mode 100755 index 0000000..023e05b --- /dev/null +++ b/autoopts/tpl/man2texi.sh @@ -0,0 +1,27 @@ +#! /bin/sh + +## man2texi.sh -- script to convert man page isms to texi-isms +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +sed \ + -e 's;\\fB\([^\\]*\)\\fP;@var{\1};' \ + -e 's;\\fI\([^\\]*\)\\fP;@i{\1};' diff --git a/autoopts/tpl/mbsd.lic b/autoopts/tpl/mbsd.lic new file mode 100644 index 0000000..408eb43 --- /dev/null +++ b/autoopts/tpl/mbsd.lic @@ -0,0 +1,31 @@ +Copyright (C) , all rights reserved. +This is free software. It is licensed for use, modification and +redistribution under the terms of the +Modified (3 clause) Berkeley Software Distribution License + + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name ``'' nor the name of any other + contributor may be used to endorse or promote products derived + from this software without specific prior written permission. + + IS PROVIDED BY ``AS IS'' AND ANY EXPRESS +OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL OR ANY OTHER CONTRIBUTORS +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +the Modified Berkeley Software Distribution License diff --git a/autoopts/tpl/mdoc2man.pl b/autoopts/tpl/mdoc2man.pl new file mode 100644 index 0000000..2168d0c --- /dev/null +++ b/autoopts/tpl/mdoc2man.pl @@ -0,0 +1,219 @@ +#!/usr/bin/perl + +## mdoc2man.pl -- Convert mdoc tags to man tags +## +## Author: Harlan Stenn +## +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +### ToDo +# Properly implement -columns in the "my %lists" definition... +# +# .Xr requires at least 1 arg, the code here expects at least 2 +# +### + +package mdoc2man; +use strict; +use warnings; +use File::Basename; +use lib dirname(__FILE__); +use Mdoc qw(hs ns pp mapwords son soff stoggle gen_encloser); + +######## +## Basic +######## + +Mdoc::def_macro( '.Sh', sub { '.SH', hs, @_ }, raw => 1); +Mdoc::def_macro( '.Ss', sub { '.SS', hs, @_ }, raw => 1); +Mdoc::def_macro( '.Pp', sub { ".sp \\n(Ppu\n.ne 2\n" } ); +Mdoc::def_macro( '.Nd', sub { "\\- @_" } ); + +# Macros that enclose things +Mdoc::def_macro( '.Brq', gen_encloser(qw({ })) , greedy => 1 ); +Mdoc::def_macro( '.Op' , gen_encloser(qw([ ])) , greedy => 1 ); +Mdoc::def_macro( '.Qq' , gen_encloser(qw(" ")) , greedy => 1 ); +Mdoc::def_macro( '.Dq' , gen_encloser(qw(\*[Lq] \*[Rq])), greedy => 1 ); +Mdoc::def_macro( '.Ql' , gen_encloser(qw(\[oq] \[cq])) , greedy => 1 ); +Mdoc::def_macro( '.Sq' , gen_encloser(qw(\[oq] \[cq])) , greedy => 1 ); +Mdoc::def_macro( '.Pq' , gen_encloser(qw/( )/) , greedy => 1 ); +Mdoc::def_macro( '.D1' , sub { ".in +4\n", ns, @_ , ns , "\n.in -4" } , greedy => 1); + +Mdoc::def_macro( 'Oo', sub { '[', @_ } ); +Mdoc::def_macro( 'Oc', sub { ']', @_ } ); + +Mdoc::def_macro( 'Po', sub { '(', @_} ); +Mdoc::def_macro( 'Pc', sub { ')', @_ } ); + +Mdoc::def_macro( 'Bro', sub { '{', ns, @_ } ); +Mdoc::def_macro( 'Brc', sub { '}', @_ } ); + +Mdoc::def_macro( '.Oo', gen_encloser(qw([ ])), concat_until => '.Oc' ); +Mdoc::def_macro( '.Bro', gen_encloser(qw({ })), concat_until => '.Brc' ); +Mdoc::def_macro( '.Po', gen_encloser(qw/( )/), concat_until => '.Pc' ); + +Mdoc::def_macro( '.Ev', sub { @_ } ); +Mdoc::def_macro( '.An', sub { ".NOP ", @_, "\n.br" }, raw => 1 ); +Mdoc::def_macro( '.Li', sub { mapwords {"\\f[C]$_\\f[]"} @_ } ); +Mdoc::def_macro( '.Cm', sub { mapwords {"\\f\\*[B-Font]$_\\f[]"} @_ } ); +Mdoc::def_macro( '.Ic', sub { mapwords {"\\f\\*[B-Font]$_\\f[]"} @_ } ); +Mdoc::def_macro( '.Fl', sub { mapwords {"\\f\\*[B-Font]\\-$_\\f[]"} @_ } ); +Mdoc::def_macro( '.Ar', sub { mapwords {"\\f\\*[I-Font]$_\\f[]"} @_ } ); +Mdoc::def_macro( '.Em', sub { mapwords {"\\fI$_\\f[]"} @_ } ); +Mdoc::def_macro( '.Va', sub { mapwords {"\\fI$_\\f[]"} @_ } ); +Mdoc::def_macro( '.Sx', sub { mapwords {"\\fI$_\\f[]"} @_ } ); +Mdoc::def_macro( '.Xr', sub { "\\fC".(shift)."\\f[]\\fR(".(shift).")\\f[]", @_ } ); +Mdoc::def_macro( '.Fn', sub { "\\f\\*[B-Font]".(shift)."\\f[]\\fR()\\f[]" } ); +Mdoc::def_macro( '.Fn', sub { "\\fB".(shift)."\\f[]\\fR()\\f[]" } ); +Mdoc::def_macro( '.Fx', sub { "FreeBSD", @_ } ); +Mdoc::def_macro( '.Ux', sub { "UNIX", @_ } ); + +Mdoc::def_macro( '.No', sub { ".NOP", map { ($_, ns) } @_ } ); +Mdoc::def_macro( '.Pa', sub { mapwords {"\\fI$_\\f[]"} @_; } ); +{ + my $name; + Mdoc::def_macro('.Nm', sub { + $name = shift if (!$name); + "\\f\\*[B-Font]$name\\fP", @_ + } ); +} + +######## +## lists +######## + +my %lists = ( + bullet => sub { + Mdoc::def_macro('.It', sub { '.IP \fB\(bu\fP 2' }); + }, + + column => sub { + Mdoc::def_macro('.It', sub { '.IP \fB\(bu\fP 2' }); + }, + + tag => sub { + my (%opts) = @_; + + my $width = ''; + + if (exists $opts{width}) { + $width = ' '.((length $opts{width})+1); + } + + if (exists $opts{compact}) { + my $dobrns = 0; + Mdoc::def_macro('.It', sub { + my @ret = (".TP$width\n.NOP", hs); + if ($dobrns) { + ".br\n.ns\n", ns, @ret, @_; + } + else { + $dobrns = 1; + @ret, @_; + } + }, raw => 1); + } + else { + Mdoc::def_macro('.It', sub { + ".TP$width\n.NOP", hs, @_ + }, raw => 1); + } + }, +); + +Mdoc::set_Bl_callback(do { my $nested = 0; sub { + my $type = shift; + my %opts = Mdoc::parse_opts(@_); + if (defined $type && $type =~ /-(\w+)/ && exists $lists{$1}) { + + # Wrap nested lists with .RS and .RE + Mdoc::set_El_callback(sub { + return '.RE' if $nested-- > 1; + return '.PP'; + }); + + $lists{$1}->(%opts); + + if ($nested++) { + return ".RS"; + } + else { + return (); + } + } + else { + die "Invalid list type <$type>"; + } +}}, raw => 1); + +# don't bother with arguments for now and do what mdoc2man'.sh' did + +Mdoc::def_macro('.Bd', sub { ".br\n.in +4\n.nf" } ); +Mdoc::def_macro('.Ed', sub { ".in -4\n.fi" } ); + +Mdoc::set_Re_callback(sub { + my ($reference) = @_; + <<"REF"; +$reference->{authors}, +\\fI$reference->{title}\\fR, +$reference->{optional}\n.PP +REF +}); + +# Define all macros which have the same sub for inline and standalone macro +for (qw(Xr Em Ar Fl Ic Cm Qq Op Nm Pa Sq Li Va Brq Pq Fx Ux)) { + my $m = Mdoc::get_macro(".$_"); + Mdoc::def_macro($_, delete $m->{run}, %$m); +} + +sub print_line { + print shift; + print "\n"; +} + +sub run { + print <<'DEFS'; +.de1 NOP +. it 1 an-trap +. if \\n[.$] \,\\$*\/ +.. +.ie t \ +.ds B-Font [CB] +.ds I-Font [CI] +.ds R-Font [CR] +.el \ +.ds B-Font B +.ds I-Font I +.ds R-Font R +DEFS + + while (my ($macro, @args) = Mdoc::parse_line(\*STDIN, \&print_line)) { + my @ret = Mdoc::call_macro($macro, @args); + print_line(Mdoc::to_string(@ret)) if @ret; + } + return 0; +} + +exit run(@ARGV) unless caller; + +1; +__END__ diff --git a/autoopts/tpl/mdoc2texi.pl b/autoopts/tpl/mdoc2texi.pl new file mode 100644 index 0000000..570d18b --- /dev/null +++ b/autoopts/tpl/mdoc2texi.pl @@ -0,0 +1,185 @@ +#! /usr/bin/perl + +## mdoc2texi.pl -- Convert mdoc tags to texi tags +## +## Author: Harlan Stenn +## +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +### To Do: + +# the Bl -column command needs work: +# - support for "-offset" +# - support for the header widths + +### + +package mdoc2texi; +use strict; +use warnings; +use File::Basename qw(dirname); +use lib dirname(__FILE__); +use Mdoc qw(ns pp hs mapwords gen_encloser nl); + +# Ignore commments +Mdoc::def_macro( '.\"', sub { () } ); + +# Enclosers +Mdoc::def_macro( '.An', sub { @_, ns, '@*' } ); +Mdoc::def_macro( '.Aq', gen_encloser(qw(< >)), greedy => 1); +Mdoc::def_macro( '.Bq', gen_encloser(qw([ ])), greedy => 1); +Mdoc::def_macro( '.Brq', gen_encloser(qw(@{ @})), greedy => 1); +Mdoc::def_macro( '.Pq', gen_encloser(qw/( )/), greedy => 1); +Mdoc::def_macro( '.Qq', gen_encloser(qw(" ")), greedy => 1); +Mdoc::def_macro( '.Op', gen_encloser(qw(@code{[ ]})), greedy => 1); +Mdoc::def_macro( '.Ql', gen_encloser(qw(@quoteleft{} @quoteright{})), + greedy => 1); +Mdoc::def_macro( '.Sq', gen_encloser(qw(@quoteleft{} @quoteright{})), + greedy => 1); +Mdoc::def_macro( '.Dq', gen_encloser(qw(@quotedblleft{} @quotedblright{})), + greedy => 1); +Mdoc::def_macro( '.Eq', sub { + my ($o, $c) = (shift, pop); + gen_encloser($o, $c)->(@_) +}, greedy => 1); +Mdoc::def_macro( '.D1', sub { "\@example\n", ns, @_, ns, "\n\@end example" }, + greedy => 1); +Mdoc::def_macro( '.Dl', sub { "\@example\n", ns, @_, ns, "\n\@end example" }, + greedy => 1); + +Mdoc::def_macro( '.Oo', gen_encloser(qw(@code{[ ]})), concat_until => '.Oc'); +Mdoc::def_macro( 'Oo', sub { '@code{[', ns, @_ } ); +Mdoc::def_macro( 'Oc', sub { @_, ns, pp(']}') } ); + +Mdoc::def_macro( '.Bro', gen_encloser(qw(@code{@{ @}})), concat_until => '.Brc'); +Mdoc::def_macro( 'Bro', sub { '@code{@{', ns, @_ } ); +Mdoc::def_macro( 'Brc', sub { @_, ns, pp('@}}') } ); + +Mdoc::def_macro( '.Po', gen_encloser(qw/( )/), concat_until => '.Pc'); +Mdoc::def_macro( 'Po', sub { '(', @_ } ); +Mdoc::def_macro( 'Pc', sub { @_, ')' } ); + +Mdoc::def_macro( '.Ar', sub { mapwords {"\@kbd{$_}"} @_ } ); +Mdoc::def_macro( '.Fl', sub { mapwords {"\@code{-$_}"} @_ } ); +Mdoc::def_macro( '.Cm', sub { mapwords {"\@code{-$_}"} @_ } ); +Mdoc::def_macro( '.Ic', sub { mapwords {"\@code{$_}"} @_ } ); +Mdoc::def_macro( '.Cm', sub { mapwords {"\@code{$_}"} @_ } ); +Mdoc::def_macro( '.Li', sub { mapwords {"\@code{$_}"} @_ } ); +Mdoc::def_macro( '.Va', sub { mapwords {"\@code{$_}"} @_ } ); +Mdoc::def_macro( '.Em', sub { mapwords {"\@emph{$_}"} @_ } ); +Mdoc::def_macro( '.Fn', sub { '@code{'.(shift).'()}' } ); +Mdoc::def_macro( '.Ss', sub { "\@subsubsection", hs, @_ }); +Mdoc::def_macro( '.Sh', sub { + my $name = "@_"; + "\@node", hs, "$name\n", ns, "\@subsection", hs, $name + }); +Mdoc::def_macro( '.Ss', sub { "\@subsubsection", hs, @_ }); +Mdoc::def_macro( '.Xr', sub { '@code{'.(shift).'('.(shift).')}', @_ } ); +Mdoc::def_macro( '.Sx', gen_encloser(qw(@ref{ })) ); +Mdoc::def_macro( '.Ux', sub { '@sc{unix}', @_ } ); +Mdoc::def_macro( '.Fx', sub { '@sc{freebsd}', @_ } ); +{ + my $name; + Mdoc::def_macro('.Nm', sub { + $name = shift || $ENV{AG_DEF_PROG_NAME} || 'XXX' if (!$name); + "\@code{$name}" + } ); +} +Mdoc::def_macro( '.Pa', sub { mapwords {"\@file{$_}"} @_ } ); +Mdoc::def_macro( '.Pp', sub { '' } ); + +# Setup references + +Mdoc::def_macro( '.Rs', sub { "\@*\n", @_ } ); +Mdoc::set_Re_callback(sub { + my ($reference) = @_; + "@*\n", ns, $reference->{authors}, ',', "\@emph{$reference->{title}}", + ',', $reference->{optional} + }); + +# Set up Bd/Ed + +my %displays = ( + literal => [ '@verbatim', '@end verbatim' ], +); + +Mdoc::def_macro( '.Bd', sub { + (my $type = shift) =~ s/^-//; + die "Not supported display type <$type>" + if not exists $displays{ $type }; + + my $orig_ed = Mdoc::get_macro('.Ed'); + Mdoc::def_macro('.Ed', sub { + Mdoc::def_macro('.Ed', delete $orig_ed->{run}, %$orig_ed); + $displays{ $type }[1]; + }); + $displays{ $type }[0] + }); +Mdoc::def_macro('.Ed', sub { die '.Ed used but .Bd was not seen' }); + +# Set up Bl/El + +my %lists = ( + bullet => [ '@itemize @bullet', '@end itemize' ], + tag => [ '@table @asis', '@end table' ], + column => [ '@table @asis', '@end table' ], +); + +Mdoc::set_Bl_callback(sub { + my $type = shift; + die "Specify a list type" if not defined $type; + $type =~ s/^-//; + die "Not supported list type <$type>" if not exists $lists{ $type }; + Mdoc::set_El_callback(sub { $lists{ $type }[1] }); + $lists{ $type }[0] + }); +Mdoc::def_macro('.It', sub { '@item', hs, @_ }); + +for (qw(Aq Bq Brq Pq Qq Ql Sq Dq Eq Ar Fl Ic Pa Op Cm Li Fx Ux Va)) { + my $m = Mdoc::get_macro(".$_"); + Mdoc::def_macro($_, delete $m->{run}, %$m); +} + +sub print_line { + my $s = shift; + $s =~ s/\\&//g; + print "$s\n"; +} + +sub preprocess_args { + $_ =~ s/([{}])/\@$1/g for @_; +} + +sub run { + while (my ($macro, @args) = Mdoc::parse_line(\*STDIN, \&print_line, + \&preprocess_args) + ) { + my @ret = Mdoc::call_macro($macro, @args); + if (@ret) { + my $s = Mdoc::to_string(@ret); + print_line($s); + } + } + return 0; +} + +exit run(@ARGV) unless caller; diff --git a/autoopts/tpl/optcode.tlib b/autoopts/tpl/optcode.tlib new file mode 100644 index 0000000..f6b4dc6 --- /dev/null +++ b/autoopts/tpl/optcode.tlib @@ -0,0 +1,869 @@ +[= autogen5 template + +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +=][= + +;;; +;;; Compute the usage line. It is complex because we are trying to +;;; encode as much information as we can and still be comprehensible. +;;; +;;; The rules are: If any options have a "value" attribute, then +;;; there are flags allowed, so include "-" on the usage line. +;;; If the program has the "long-opts" attribute set, then we must +;;; have "" or "--" on the line, depending on +;;; whether or not there are flag options. If any options take +;;; arguments, then append "[]" to the flag description and +;;; "[{=| }]" to the option-name/name descriptions. We will not +;;; worry about being correct if every option has a required argument. +;;; Finally, if there are no minimum occurrence counts (i.e. all +;;; options are optional), then we put square brackets around the +;;; syntax. +;;; +;;; Compute the option arguments +;;; +(define tmp-val "") +(if (exist? "flag.arg-type") + (set! tmp-val "[{=| }]")) + +(define usage-line (string-append "Usage: %s " + + ;; If at least one option has a minimum occurrence count + ;; we use curly brackets around the option syntax. + ;; + (if (not (exist? "flag.min")) "[ " "{ ") + + (if (exist? "flag.value") + (string-append "-" + (if (exist? "flag.arg-type") " []" "") + (if (exist? "long-opts") " | " "") ) + (if (not (exist? "long-opts")) + (string-append "" tmp-val) "" ) ) + + (if (exist? "long-opts") + (string-append "--" tmp-val) "" ) + + (if (not (exist? "flag.min")) " ]..." " }...") +) ) + +(if (exist? "argument") + (set! usage-line (string-append usage-line + + ;; the USAGE line plus the program name plus the argument goes + ;; past 80 columns, then break the line, else separate with space + ;; + (if (< 80 (+ (string-length usage-line) + (len "argument") + (string-length prog-name) )) + " \\\n\t\t" + " " + ) + + (get "argument") + )) +) + +(define usage-text (string-append prog-name + (if (exist? "package") + (string-append " (" (get "package") ")") + "" ) + " - " (get "prog-title") + (if (and (exist? "version") (not (exist? "gnu-usage"))) + (string-append " - Ver. " (get "version")) + "" ) + "\n" usage-line "\n" +)) =][= # + +// # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +INCLUDE "optmain.tlib" + +=] +#ifndef __doxygen__ +#define OPTION_CODE_COMPILE 1 +#include "[= (define lib-externs "") header-file=]" +#include +#include +[= + + (if (== (get "main.main-type" "") "for-each") + (emit "\n#include ") ) + +=] +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif +extern FILE * option_usage_fp;[= + +IF (not (exist? "copyright")) + +=] +#define zCopyright NULL +#define zLicenseDescrip NULL[= +ELSE =][= + CASE (define cright-owner (get "copyright.owner" (get "copyright.author"))) + (get "copyright.type") =][= + + = note =][= + (set! tmp-text (get "copyright.text")) + (define ext-text tmp-text) =][= + + ~~* . =][= + (define ext-text + (license-description (get "copyright.type") + prog-name "" cright-owner ) ) + + (set! tmp-text + (license-info (get "copyright.type") + prog-name "" cright-owner (get "copyright.date") ) ) + =][= + + * =][= + (set! tmp-text (sprintf + "Copyright (C) %s %s, all rights reserved" + (get "copyright.date") cright-owner )) + (define ext-text tmp-text) =][= + + ESAC =][= + +(set! tmp-text (string-append version-text "\n" tmp-text)) +(if (not omit-nls-code) + (put-xget "pzCopyright" tmp-text)) + +(string-append "\n#define zCopyright (" + (string-table-add-ref opt-strs tmp-text) + ")\n#define zLicenseDescrip (" + + (if (= tmp-text ext-text) + "zCopyright" + (begin + (set! ext-text (string-append (shell (string-append + "${CLexe} --fill -I0 -W75 <<_EOF_\n" ext-text "\n_EOF_" )) "\n" )) + + (if (not omit-nls-code) + (put-xget "pzCopyNotice" ext-text)) + (string-table-add-ref opt-strs ext-text) + ) ) + ")\n" ) =][= + +ENDIF "copyright" =][= + + (define usage-proc (get "usage")) + (if (< 1 (string-length usage-proc)) + (emit (string-append "\nextern tUsageProc " usage-proc ";")) + (set! usage-proc "optionUsage") + ) + +=] +[= INVOKE join-or-expand join-type = "include" =] +#ifndef NULL +# define NULL 0 +#endif + +/** + * static const strings for [= prog-name =] options + */[= + (out-resume "home-list") \=][= + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +FOR flag "\n" =][= + (define flag-index (for-index)) =][= + INVOKE emit-opt-strs =][= + + (if (exist? "lib-name") (begin + (set! lib-opt-ptr (string->c-name! (string-append + (get "lib-name") "_" (get "name") "_optDesc_p"))) + (set! lib-externs (string-append lib-externs + (sprintf "tOptDesc * const %-16s = optDesc + %d;\n" + lib-opt-ptr (for-index) ) )) + ) ) =][= + +ENDFOR flag =][= + +INVOKE help-strs =][= +INVOKE decl-callbacks =][= + +IF (exist? "version") =][= + + IF (exist? "version-proc") =] +#define VER_PROC [= (get "version-proc") =][= + ELIF (. guarded-test-main) =] +#ifdef [=(. main-guard) =] +# define VER_PROC optionVersionStderr +#else +# define VER_PROC optionPrintVersion +#endif /* [=(. main-guard)=] */[= + ELSE =] +#define VER_PROC optionPrintVersion[= + ENDIF guarded-test-main =][= + +ENDIF there is a version + +=] +[= INVOKE emit-option-desc-table =] +[= (. lib-externs) =] +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** Reference to the upper cased version of [= prog-name =]. */ +#define zPROGNAME ([= (string-table-add-ref opt-strs pname-up) =]) +/** Reference to the title line for [= prog-name =] usage. */ +#define zUsageTitle ([= + (define homerc-ct 0) + (define homerc-txt "") + (if (not omit-nls-code) + (put-xget "pzUsageTitle" usage-text)) + + (string-table-add-ref opt-strs usage-text) =]) +[= +FOR homerc =][= + (set! tmp-text (get "homerc")) + (if (> (string-length tmp-text) 0) (begin + (set! homerc-ct (+ 1 homerc-ct)) + (set! homerc-txt (string-append homerc-txt + "\n " (string-table-add-ref opt-strs tmp-text) "," )) + ) ) =][= +ENDFOR homerc =][= +IF (> homerc-ct 0) \=] +/** [= prog-name =] configuration file name. */ +#define zRcName ([= + (set! tmp-text (get "rcfile" + (string-append "." pname-down "rc") )) + (string-table-add-ref opt-strs tmp-text) =]) +/** Directories to search for [= prog-name =] config files. */ +static char const * const apzHomeList[= + (sprintf "[%u] = {%s\n NULL };" (+ 1 homerc-ct) homerc-txt) =][= + +ELSE \=] +/** There is no [= prog-name =] configuration file. */ +#define zRcName NULL +/** There are no directories to search for [= prog-name =] config files. */ +#define apzHomeList NULL[= +ENDIF =] +/** The [= prog-name =] program bug email address. */ +#define zBugsAddr ([= +(out-push-new) \=] +s/@[a-z]*{\([^{@}]*\)}/'\1'/g +s=@@=[= prog-name =]=g +/^@\(end *\)*example/d +s/^@item *$/\ +/[= + +(define patch-text-sed + (sprintf "sed %s <<\\_EODetail_ | ${CLexe} --fill -I0 -W75\n" + (raw-shell-str (out-pop #t)) ) ) + +(define patch-text (lambda (t-name) + (set! tmp-text (string-append + + (shell (string-append + patch-text-sed + (get t-name) + "\n_EODetail_" )) + "\n" )) )) + +(if (exist? "copyright.eaddr") + (string-table-add-ref opt-strs (get "copyright.eaddr")) + (if (exist? "eaddr") + (string-table-add-ref opt-strs (get "eaddr")) + "NULL" +) ) =]) +/** Clarification/explanation of what [= prog-name =] does. */ +#define zExplain ([= + +(if (or (exist? "explain") (== (get "main.main-type") "for-each")) + (begin + (if (exist? "explain") + (patch-text "explain") + (set! tmp-text "") ) + + (if (== (get "main.main-type") "for-each") + (set! tmp-text (string-append tmp-text +"\nIf no arguments are provided, input arguments are read from stdin, +one per line; blank and '" +(if (exist? "main.comment-char") (get "main.comment-char") "#") +"'-prefixed lines are comments.\n" +(if (exist? "main.interleaved") + "Options may appear in the input interspersed with the 'normal' input.\n" + "") +"'stdin' may not be a terminal (tty).\n" )) ) + + (if (not omit-nls-code) + (put-xget "pzExplain" tmp-text)) + (string-table-add-ref opt-strs tmp-text) + ) + "NULL" +) =]) +/** Extra detail explaining what [= prog-name =] does. */ +#define zDetail ([= + +(if (exist? "detail") + (begin + (patch-text "detail") + (if (not omit-nls-code) + (put-xget "pzDetail" tmp-text)) + (string-table-add-ref opt-strs tmp-text) + ) + "NULL" +) =]) +/** The full version string for [= prog-name =]. */ +#define zFullVersion ([= + +(if (exist? "version") (begin + (if (not omit-nls-code) + (put-xget "pzFullVersion" version-text)) + (string-table-add-ref opt-strs version-text) ) + "NULL") =])[= +(tpl-file-line extract-fmt) +=][= + + IF (. omit-nls-code) =] +#define OPTPROC_BASE OPTPROC_NONE +#define translate_option_strings NULL +[= ELSE =] +#if defined(ENABLE_NLS) +# define OPTPROC_BASE OPTPROC_TRANSLATE[= +CASE no-xlate =][= +!E =][= += opt-cfg =] | OPTPROC_NXLAT_OPT_CFG[= += opt =] | OPTPROC_NXLAT_OPT[= +* =][= (error "invalid value for 'no-xlate'") =][= +ESAC no-xlate =] + static tOptionXlateProc translate_option_strings; +#else +# define OPTPROC_BASE OPTPROC_NONE +# define translate_option_strings NULL +#endif /* ENABLE_NLS */ +[= ENDIF no-nls =][= + IF (exist? "resettable") =] +#ifndef optArgBucket_t +#define opt_arg_union_t optArgBucket_t +#endif +/** Compiled-in initial values for [= prog-name =] options. */ +static opt_arg_union_t const original_[=(. pname-down)=]_defaults[ [= +(. UP-prefix) =]OPTION_CT ] = { +[= (shell (string-append + "sed '$s@},@} @' <<\\_EOF_" default-text "\n_EOF_\n")) =] +}; +/** Compiled-in initial values for [= prog-name =] option cookies. */ +static void * const original_[=(. pname-down)=]_cookies[ [= +(. UP-prefix) =]OPTION_CT ] = { +[= + (shell (string-append "${CLexe} -I4 -S, <<\\_EOF_\n" default-cookie "_EOF_")) +=] +}; +[= ENDIF resettable=] +[= INVOKE emit-help-text help-type = full \=] +[= INVOKE emit-help-text help-type = short =] +#endif /* not defined __doxygen__ */ +[= INVOKE emit-option-callbacks =] +/** + * The directory containing the data associated with [= prog-name =]. + */ +#ifndef PKGDATADIR +# define PKGDATADIR "" +#endif + +/** + * Information about the person or institution that packaged [= prog-name =] + * for the current distribution. + */ +#ifndef WITH_PACKAGER +# define [=(. pname)=]_packager_info NULL +#else +/** Packager information for [= prog-name =]. */ +static char const [=(. pname)=]_packager_info[] = + "Packaged by " WITH_PACKAGER + +# ifdef WITH_PACKAGER_VERSION + " ("WITH_PACKAGER_VERSION")" +# endif + +# ifdef WITH_PACKAGER_BUG_REPORTS + "\nReport [=(. pname)=] bugs to " WITH_PACKAGER_BUG_REPORTS +# endif + "\n"; +#endif +#ifndef __doxygen__ +[= + (out-suspend "home-list") + (emit-string-table opt-strs) + (out-resume "home-list") + (define put-shell-main (== (get "main.main-type") "shell-process")) + (out-pop #t) +=] +#endif /* __doxygen__ */ +/** + * The option definitions for [= prog-name =]. The one structure that + * binds them all. + */ +tOptions [=(. pname)=]Options = { + OPTIONS_STRUCT_VERSION, + 0, NULL, /* original argc + argv */ + ( OPTPROC_BASE[= + (define tmp-val "\n + OPTPROC_") + (if (not (exist? "allow-errors")) (emit tmp-val "ERRSTOP")) + (if (exist? "flag.value") (emit tmp-val "SHORTOPT")) + (if (exist? "long-opts") (emit tmp-val "LONGOPT")) + (if (not (exist? "flag.min")) (emit tmp-val "NO_REQ_OPT")) + (if (exist? "flag.disable") (emit tmp-val "NEGATIONS")) + (if (>= number-opt-index 0) (emit tmp-val "NUM_OPT")) + (if (exist? "environrc") (emit tmp-val "ENVIRON")) + (if (not (exist? "argument")) (emit tmp-val "NO_ARGS") + (if (not (==* (get "argument") "[")) (emit tmp-val "ARGS_REQ"))) + (if (exist? "reorder-args") (emit tmp-val "REORDER")) + (if (exist? "gnu-usage") (emit tmp-val "GNUUSAGE")) + (if (exist? "no-misuse-usage") (emit tmp-val "MISUSE")) + (if (exist? "vendor-opt") (emit tmp-val "VENDOR_OPT")) + (if put-shell-main (emit tmp-val "SHELL_OUTPUT")) + =] ), + 0, NULL, /* current option index, current option */ + NULL, NULL, zPROGNAME, + zRcName, zCopyright, zLicenseDescrip, + zFullVersion, apzHomeList, zUsageTitle, + zExplain, zDetail, optDesc, + zBugsAddr, /* address to send bugs to */ + NULL, NULL, /* extensions/saved state */ + [= (. usage-proc) =], /* usage procedure */ + translate_option_strings, /* translation procedure */ + /* + * Indexes to special options + */ + { [= (if (exist? "no-libopts") "NO_EQUIVALENT" + (string-append INDEX-pfx "MORE_HELP")) + =], /* more-help option index */ + [=IF (and (exist? "homerc") (not (exist? "disable-save"))) + =][= (. INDEX-pfx) =]SAVE_OPTS[= + ELSE =]NO_EQUIVALENT[= + ENDIF=], /* save option index */ + [= (if (>= number-opt-index 0) number-opt-index "NO_EQUIVALENT") + =], /* '-#' option index */ + [= (if (>= default-opt-index 0) default-opt-index "NO_EQUIVALENT") + =] /* index of default opt */ + }, + [= (. option-ct) =] /* full option count */, [= + (count "flag")=] /* user option count */, + [= (. pname) =]_full_usage, [= (. pname) =]_short_usage, +[= IF (exist? "resettable") \=] + original_[=(. pname-down)=]_defaults, original_[=(. pname-down)=]_cookies, +[= ELSE \=] + NULL, NULL, +[= ENDIF \=] + PKGDATADIR, [=(. pname)=]_packager_info +}; +[= + +FOR lib-name + +=] +tOptDesc* [= (string->c-name! (get "lib-name")) =]_optDesc_p = NULL;[= + +ENDFOR =][= + +IF (not omit-nls-code) =][= + INVOKE emit-nls-code =][= +ENDIF + +=] +#ifdef __cplusplus +} +#endif[= # + +// # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE emit-nls-code + +=] +#if ENABLE_NLS +/** + * This code is designed to translate translatable option text for the + * [= prog-name =] program. These translations happen upon entry + * to optionProcess(). + */ +#include +#include +#include +#include +#ifdef HAVE_DCGETTEXT +# include +#endif +#include + +static char * AO_gettext(char const * pz); +static void coerce_it(void ** s); + +/** + * AutoGen specific wrapper function for gettext. It relies on the macro _() + * to convert from English to the target language, then strdup-duplicates the + * result string. It tries the "libopts" domain first, then whatever has been + * set via the \a textdomain(3) call. + * + * @param[in] pz the input text used as a lookup key. + * @returns the translated text (if there is one), + * or the original text (if not). + */ +static char * +AO_gettext(char const * pz) +{ + char * res; + if (pz == NULL) + return NULL; +#ifdef HAVE_DCGETTEXT + /* + * While processing the option_xlateable_txt data, try to use the + * "libopts" domain. Once we switch to the option descriptor data, + * do *not* use that domain. + */ + if (option_xlateable_txt.field_ct != 0) { + res = dgettext("libopts", pz); + if (res == pz) + res = (char *)VOIDP(_(pz)); + } else + res = (char *)VOIDP(_(pz)); +#else + res = (char *)VOIDP(_(pz)); +#endif + if (res == pz) + return res; + res = strdup(res); + if (res == NULL) { + fputs(_("No memory for duping translated strings\n"), stderr); + exit([=(. nomem-exit-code)=]); + } + return res; +} + +/** + * All the pointers we use are marked "* const", but they are stored in + * writable memory. Coerce the mutability and set the pointer. + */ +static void coerce_it(void ** s) { *s = AO_gettext(*s); +} + +/** + * Translate all the translatable strings in the [=(. pname)=]Options + * structure defined above. This is done only once. + */ +static void +translate_option_strings(void) +{ + tOptions * const opts = &[=(. pname)=]Options; + + /* + * Guard against re-translation. It won't work. The strings will have + * been changed by the first pass through this code. One shot only. + */ + if (option_xlateable_txt.field_ct != 0) { + /* + * Do the translations. The first pointer follows the field count + * field. The field count field is the size of a pointer. + */ + char ** ppz = (char**)VOIDP(&(option_xlateable_txt)); + int ix = option_xlateable_txt.field_ct; + + do { + ppz++; /* skip over field_ct */ + *ppz = AO_gettext(*ppz); + } while (--ix > 0); + /* prevent re-translation and disable "libopts" domain lookup */ + option_xlateable_txt.field_ct = 0; +[= + FOR field IN pzCopyright pzCopyNotice pzFullVersion =] + coerce_it(VOIDP(&(opts->[= field =])));[= + ENDFOR =][= + + IF (not (exist? "full-usage"))=][= + FOR field IN pzUsageTitle pzExplain pzDetail =] + coerce_it(VOIDP(&(opts->[= field =])));[= + ENDFOR =] + { + tOptDesc * od = opts->pOptDesc; + for (ix = opts->optCt; ix > 0; ix--, od++) + coerce_it(VOIDP(&(od->pzText))); + }[= + ENDIF =] + } +} +#endif /* ENABLE_NLS */ + +#ifdef DO_NOT_COMPILE_THIS_CODE_IT_IS_FOR_GETTEXT +/** I18N function strictly for xgettext. Do not compile. */ +static void bogus_function(void) { + /* TRANSLATORS: + + The following dummy function was crated solely so that xgettext can + extract the correct strings. These strings are actually referenced + by a field name in the [=(. pname)=]Options structure noted in the + comments below. The literal text is defined in [=(. pname)=]_opt_strs. + + NOTE: the strings below are segmented with respect to the source string + [=(. pname)=]_opt_strs. The strings above are handed off for translation + at run time a paragraph at a time. Consequently, they are presented here + for translation a paragraph at a time. + + ALSO: often the description for an option will reference another option + by name. These are set off with apostrophe quotes (I hope). Do not + translate option names. + */[= + +(out-resume "xget") +(emit (out-pop #t)) + +(out-push-new) \=] +test "X${CDPATH}" = X || CDPATH='' +incdir=[= (if (defined? 'inc-dir) inc-dir "") ;;' 4emacs =] +test -d "$incdir" || incdir=`dirname [=(tpl-file #t)=]`/.. +incdir=`cd $incdir/autoopts && pwd` +test -f ${incdir}/usage-txt.h && { + sedcmd='/LIBOPTS-MESSAGES:/,/END-[= + + (if (and (exist? "full-usage") (exist? "short-usage")) + "LIBOPTS-MESSAGES" + "USAGE-TEXT" ) =]/p' + sed -n "$sedcmd" ${incdir}/usage-txt.h +} +[= (shell (out-pop #t)) =] +} +#endif /* uncompilable code */[= + +ENDDEF emit-nls-code + +=][= + +DEFINE emit-option-desc-table + +=] +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Define the [= prog-name =] Option Descriptions. + * This is an array of [=(. UP-prefix)=]OPTION_CT entries, one for each + * option that the [= prog-name =] program responds to. + */ +static tOptDesc optDesc[[= +(define default-text "") +(define default-cookie "") +UP-prefix +=]OPTION_CT] = {[= + +FOR flag "\n" =][= + (define flag-index (for-index)) =][= + + INVOKE emit-opt-desc =][= + +ENDFOR flag + +=][= + +IF (exist? "resettable") + +=] + + { /* entry idx, value */ [= + (set! default-text (string-append default-text + "\n { NULL }, /* resettable */" )) + (set! default-cookie (string-append default-cookie "NULL\n" )) + INDEX-pfx =]RESET_OPTION, [= (. VALUE-pfx) =]RESET_OPTION, + /* equiv idx value */ NO_EQUIVALENT, [= (. VALUE-pfx) =]RESET_OPTION, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ RESET_FLAGS, AOUSE_RESET_OPTION, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ optionResetOpt, + /* desc, NAME, name */ RESET_DESC, NULL, RESET_name, + /* disablement strs */ NULL, NULL },[= + +ENDIF + +=][= + +IF (exist? "version") =] + + { /* entry idx, value */ [= + (set! default-text (string-append default-text + "\n { NULL }, /* version */" )) + (set! default-cookie (string-append default-cookie "NULL\n" )) + INDEX-pfx =]VERSION, [= (. VALUE-pfx) =]VERSION, + /* equiv idx value */ NO_EQUIVALENT, [= (. VALUE-pfx) =]VERSION, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ VER_FLAGS, AOUSE_VERSION, + /* last opt argumnt */ { [=(if (exist? "version-type") + (string-append "(char const*)\"" (get "version-type") "\"") + "NULL")=] }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ VER_PROC, + /* desc, NAME, name */ VER_DESC, NULL, VER_name, + /* disablement strs */ NULL, NULL }, + +[= + +ENDIF =] + + { /* entry idx, value */ [= + (set! default-text (string-append default-text + "\n { NULL }, /* help */" )) + (set! default-cookie (string-append default-cookie "NULL\n" )) + INDEX-pfx =]HELP, [= (. VALUE-pfx) =]HELP, + /* equiv idx value */ NO_EQUIVALENT, [= (. VALUE-pfx) =]HELP, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ OPTST_IMM | OPTST_NO_INIT, AOUSE_HELP, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ doUsageOpt, + /* desc, NAME, name */ HELP_DESC, NULL, HELP_name, + /* disablement strs */ NULL, NULL }[= + +IF (not (exist? "no-libopts")) =], + + { /* entry idx, value */ [= + (set! default-text (string-append default-text + "\n { NULL }, /* more-help */" )) + (set! default-cookie (string-append default-cookie "NULL\n" )) + INDEX-pfx =]MORE_HELP, [= (. VALUE-pfx) =]MORE_HELP, + /* equiv idx value */ NO_EQUIVALENT, [= (. VALUE-pfx) =]MORE_HELP, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ MORE_HELP_FLAGS, AOUSE_MORE_HELP, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ optionPagedUsage, + /* desc, NAME, name */ MORE_HELP_DESC, NULL, MORE_HELP_name, + /* disablement strs */ NULL, NULL }[= + +ENDIF not have no-libopts =][= + +IF (exist? "usage-opt") =], + + { /* entry idx, value */ [= + (set! default-text (string-append default-text + "\n { NULL }, /* usage-opt */" )) + (set! default-cookie (string-append default-cookie "NULL\n" )) + INDEX-pfx =]USAGE, [= (. VALUE-pfx) =]USAGE, + /* equiv idx value */ NO_EQUIVALENT, [= (. VALUE-pfx) =]USAGE, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ OPTST_IMM | OPTST_NO_INIT, AOUSE_USAGE, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ doUsageOpt, + /* desc, NAME, name */ USAGE_DESC, NULL, USAGE_name, + /* disablement strs */ NULL, NULL }[= + +ENDIF have usage-opt =][= + +IF (exist? "homerc") =][= + IF (not (exist? "disable-save")) =], + + { /* entry idx, value */ [= + (set! default-text (string-append default-text + "\n { NULL }, /* save-opts */" )) + (set! default-cookie (string-append default-cookie "NULL\n" )) + INDEX-pfx =]SAVE_OPTS, [= + (if (not (exist? "disable-save")) + (string-append VALUE-pfx "SAVE_OPTS") + "0") =], + /* equiv idx value */ NO_EQUIVALENT, [= (. VALUE-pfx) =]SAVE_OPTS, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ OPTST_SET_ARGTYPE(OPARG_TYPE_STRING) + | OPTST_ARG_OPTIONAL | OPTST_NO_INIT, AOUSE_SAVE_OPTS, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ SAVE_OPTS_DESC, NULL, SAVE_OPTS_name, + /* disablement strs */ NULL, NULL }[= + + ENDIF disable-save does not exist =], + + { /* entry idx, value */ [= + (set! default-text (string-append default-text + "\n { NULL }, /* load-opts */" )) + (set! default-cookie (string-append default-cookie "NULL\n" )) + INDEX-pfx =]LOAD_OPTS, [= + (if (not (exist? "disable-load")) + (string-append VALUE-pfx "LOAD_OPTS") + "0") =], + /* equiv idx value */ NO_EQUIVALENT, [= (. VALUE-pfx) =]LOAD_OPTS, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, NOLIMIT, 0, + /* opt state flags */ OPTST_SET_ARGTYPE(OPARG_TYPE_STRING) + | OPTST_DISABLE_IMM[= + (if (exist? "disable-load") "| OPTST_NO_COMMAND") =], AOUSE_LOAD_OPTS, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ optionLoadOpt, + /* desc, NAME, name */ [= + (if (exist? "disable-load") "NULL, NULL, NULL" + "LOAD_OPTS_DESC, LOAD_OPTS_NAME, LOAD_OPTS_name")=], + /* disablement strs */ [= + (if (exist? "disable-load") "NULL, NULL" + "NO_LOAD_OPTS_name, LOAD_OPTS_pfx")=] }[= + +ENDIF have homerc =][= + +IF (exist? "vendor-opt") =], + + { /* entry idx, value */ [= + (set! default-text (string-append default-text + "\n { NULL }, /* vendor-opt */" )) + (set! default-cookie (string-append default-cookie "NULL\n" )) + INDEX-pfx =]VENDOR_OPT, [= (. VALUE-pfx) =]VENDOR_OPT, + /* equiv idx value */ NO_EQUIVALENT, [= (. VALUE-pfx) =]VENDOR_OPT, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, NOLIMIT, 0, + /* opt state flags */ OPTST_SET_ARGTYPE(OPARG_TYPE_STRING) + | OPTST_IMM | OPTST_TWICE, AOUSE_VENDOR_OPT, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ optionVendorOption, + /* desc, NAME, name */ VEND_DESC, NULL, VEND_name, + /* disablement strs */ NULL, NULL }[= + +ENDIF have vendor-opt =] +}; +[= + +ENDDEF emit-option-desc-table + +/* + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * opthead.tpl ends here */ \=] diff --git a/autoopts/tpl/opthead.tlib b/autoopts/tpl/opthead.tlib new file mode 100644 index 0000000..5b024b4 --- /dev/null +++ b/autoopts/tpl/opthead.tlib @@ -0,0 +1,709 @@ +[= autogen5 template -*- Mode: C -*- + +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +=] +/** + * This file contains the programmatic interface to the Automated + * Options generated for the [=prog-name=] program. + * These macros are documented in the AutoGen info file in the + * "AutoOpts" chapter. Please refer to that doc for usage help. + */ +[= + (emit (make-header-guard "autoopts")) + (if (exist? "config-header") + (ag-fprintf 0 "\n#include \"%s\"" (get "config-header")) ) + + (emit "\n#include \n" + "#include \n" + "#include \n") + + (define option-ct 0) + (define index-sep-str "") + + (set! max-name-len (+ max-name-len 2)) + (define index-fmt (sprintf "%%s\n %s%%-%ds=%%3d" INDEX-pfx max-name-len)) + + (define add-opt-index (lambda (opt-nm) (begin + (ag-fprintf 0 index-fmt index-sep-str opt-nm option-ct) + (set! option-ct (+ option-ct 1)) + (set! index-sep-str ",") + ) ) ) =][= + +IF (not (exist? "library")) =] +/** + * Ensure that the library used for compiling this generated header is at + * least as new as the version current when the header template was released + * (not counting patch version increments). Also ensure that the oldest + * tolerable version is at least as old as what was current when the header + * template was released. + */ +#define AO_TEMPLATE_VERSION [=(. ao-template-ver)=] +#if (AO_TEMPLATE_VERSION < OPTIONS_MINIMUM_VERSION) \ + || (AO_TEMPLATE_VERSION > OPTIONS_STRUCT_VERSION) +# error option template version mismatches autoopts/options.h header + Choke Me. +#endif +[= ENDIF not a library =] +#if GCC_VERSION > 40400 +#define NOT_REACHED __builtin_unreachable(); +#else +#define NOT_REACHED +#endif + +/** + * Enumeration of each option type for [= prog-name =] + */ +typedef enum {[= +FOR flag =][= + (if (exist? "documentation") + (set! option-ct (+ option-ct 1)) + (add-opt-index (get-up-name "name")) + ) + =][= +ENDFOR flag =][= + +IF (exist? "library") =], + LIBRARY_OPTION_COUNT[= + +ELSE not exists library =][= + + (if (exist? "resettable") (add-opt-index "RESET_OPTION")) + (if (exist? "version") (add-opt-index "VERSION")) + (add-opt-index "HELP") + (if (not (exist? "no-libopts")) (add-opt-index "MORE_HELP")) + (if (exist? "usage-opt") (add-opt-index "USAGE")) + (if (exist? "vendor-opt") (add-opt-index "VENDOR_OPT")) + + (if (exist? "homerc") (begin + (if (not (exist? "disable-save")) (add-opt-index "SAVE_OPTS")) + (add-opt-index "LOAD_OPTS") + ) ) =][= +ENDIF not exist library =] +} te[=(. Cap-prefix)=]OptIndex; +/** count of all options for [= prog-name =] */ +#define [=(. UP-prefix)=]OPTION_CT [= (. option-ct) =][= +IF (exist? "version") =] +/** [= prog-name =] version */ +#define [=(. pname-up)=]_VERSION [=(c-string (get "version"))=] +/** Full [= prog-name =] version text */ +#define [=(. pname-up)=]_FULL_VERSION [=(c-string version-text) =][= +ENDIF (exist? version) =] + +/** + * Interface defines for all options. Replace "n" with the UPPER_CASED + * option name (as in the te[=(. Cap-prefix)=]OptIndex enumeration above). + * e.g. HAVE_[=(. UP-prefix)=]OPT([= (get-up-name "flag[].name") =]) + */[= + +IF (exist? "library") + +=] +/** pointer to the library handling procedure. */ +extern tOptDesc * const [= (. lib-opt-ptr) =];[= + +ENDIF is a library =][= + +CASE guard-option-names =][= +!E =][= + (set! tmp-val (string-append "[" INDEX-pfx "## n]")) + =][= + += full-enum =][= + (set! tmp-val "[n]") =][= + +=* no-warn =][= + (set! tmp-val (string-append "[" INDEX-pfx "## n]")) + =][= + +* =][= + (set! tmp-val (string-append "[" INDEX-pfx "## n]")) + =][= + +ESAC =][= + +(if (exist? "library") + (set! tmp-val (string-append "(" lib-opt-ptr tmp-val ")")) + (set! tmp-val (string-append "(" pname "Options.pOptDesc" tmp-val ")")) ) + +(ag-fprintf 0 "\n#define %8sDESC(n) " UP-prefix) +(emit tmp-val) +(out-push-new) + +=] +/** 'true' if an option has been specified in any way */ +#define HAVE_

OPT(n) (! UNUSED_OPT(&

DESC(n))) +/** The string argument to an option. The argument type must be \"string\". */ +#define

OPT_ARG(n) (

DESC(n).optArg.argString) +/** Mask the option state revealing how an option was specified. + * It will be one and only one of \a OPTST_SET, \a OPTST_PRESET, + * \a OPTST_DEFINED, \a OPTST_RESET or zero. + */ +#define STATE_

OPT(n) (

DESC(n).fOptState & OPTST_SET_MASK) +/** Count of option's occurrances *on the command line*. */ +#define COUNT_

OPT(n) (

DESC(n).optOccCt) +/** mask of \a OPTST_SET and \a OPTST_DEFINED. */ +#define ISSEL_

OPT(n) (SELECTED_OPT(&

DESC(n))) +/** 'true' if \a HAVE_OPT would yield 'false'. */ +#define ISUNUSED_

OPT(n) (UNUSED_OPT(&

DESC(n))) +/** 'true' if OPTST_DISABLED bit not set. */ +#define ENABLED_

OPT(n) (! DISABLED_OPT(&

DESC(n))) +/** number of stacked option arguments. + * Valid only for stacked option arguments. */ +#define STACKCT_

OPT(n) (((tArgList*)(

DESC(n).optCookie))->useCt) +/** stacked argument vector. + * Valid only for stacked option arguments. */ +#define STACKLST_

OPT(n) (((tArgList*)(

DESC(n).optCookie))->apzArgs) +/** Reset an option. */ +#define CLEAR_

OPT(n) STMTS( \ +

DESC(n).fOptState &= OPTST_PERSISTENT_MASK; \ + if ((

DESC(n).fOptState & OPTST_INITENABLED) == 0) \ +

DESC(n).fOptState |= OPTST_DISABLED; \ +

DESC(n).optCookie = NULL )[= + +(set! tmp-val (if (> (string-length UP-prefix) 1) UP-prefix "")) +(string-substitute (out-pop #t) "

" tmp-val) + +=][= + +INVOKE emit-exit-codes =][= +INVOKE emit-option-guards + +=] +/** + * Interface defines for specific options. + * @{ + */[= + +FOR flag =][= + (define flag-index (for-index)) =][= + + INVOKE save-name-morphs =][= + + IF (set! opt-name (string-append OPT-pfx UP-name)) + (set! descriptor (string-append UP-prefix "DESC(" UP-name ")" )) + + (exist? "documentation") + + =][= + IF (hash-ref have-cb-procs flg-name) +=] +/** call the handler procedure for setting the [= name =] option. */ +#define SET_[= (string-append OPT-pfx UP-name) =] STMTS( \ + (*([=(. descriptor)=].pOptProc))(&[=(. pname)=]Options, \ + [=(. pname)=]Options.pOptDesc + [=(for-index)=])[= + + ENDIF =][= + ELSE =][= + INVOKE option-defines =][= + ENDIF =][= +ENDFOR flag =][= +INVOKE emit-opt-values =][= + +IF (and (exist? "homerc") (not (exist? "disable-save"))) + +=] +#define SET_[=(. OPT-pfx)=]SAVE_OPTS(a) STMTS( \ + [=(. UP-prefix)=]DESC(SAVE_OPTS).fOptState &= OPTST_PERSISTENT_MASK; \ + [=(. UP-prefix)=]DESC(SAVE_OPTS).fOptState |= OPTST_SET; \ + [=(. UP-prefix)=]DESC(SAVE_OPTS).optArg.argString = (char const*)(a))[= +ENDIF + +// # # # # # # # # # # # # # # # # # # # # # # =][= + +IF (not (exist? "library")) =][= + INVOKE emit-program-externs =][= +ENDIF + +=] +#endif /* [=(. header-guard)=] */ +[= # +// # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE emit-program-externs + +=][= +(tpl-file-line extract-fmt) +(out-push-new) +=] +/* + * Interface defines not associated with particular options + */ +#define ERRSKIP_OPTERR STMTS(Options.fOptSet &= ~OPTPROC_ERRSTOP) +#define ERRSTOP_OPTERR STMTS(Options.fOptSet |= OPTPROC_ERRSTOP) +#define RESTART_OPT(n) STMTS( \ + Options.curOptIdx = (n); \ + Options.pzCurOpt = NULL ) +#define START_OPT RESTART_OPT(1) +#define USAGE(c) (*Options.pUsageProc)(&Options, c) +[= + +(set! tmp-val (if (> (string-length UP-prefix) 1) UP-prefix "")) +(string-substitute (out-pop #t) + (list "" "") + (list tmp-val pname) ) + +=] +#ifdef __cplusplus +extern "C" { +#endif +[= +INVOKE join-or-expand join-type = "export" =][= +INVOKE nls-header-code =] +[= + + IF + (define no-return-str (string-append + "noreturn extern void" "\n" lc-prefix)) + + (exist? "usage-message") + +=] +[=(. no-return-str)=]vusage_message(char const * fmt, va_list ap); +[=(. no-return-str)=]usage_message(char const * fmt, ...);[= + ENDIF have usage-message =][= + + IF (exist? "die-code") =] +[=(. no-return-str)=]vdie( int exit_code, char const * fmt, va_list); +[=(. no-return-str)=]die( int exit_code, char const * fmt, ...); +[=(. no-return-str)=]fserr(int exit_code, char const * op, char const * fn);[= + + IF (. no-mem-func) =] + +/** + * Print a [=(. nomem-exit-code)=] fatal error message and die. + * + * @param[in] sz the object size that was not allocated + * @param[in] what what that object was going to be + * @noreturn + */ +noreturn static inline void nomem_err(size_t sz, char const * what) +{ + char const * fmt = _("could not allocate %zu bytes for %s\n"); + die([=(. nomem-exit-code)=], fmt, sz, what); +}[= + + ENDIF no-memory failure =][= + + ENDIF die-code exists =][= + + IF (exist? "warn-code") =] +extern void [=(. lc-prefix)=]vwarning_msg( char const * fmt, va_list); +extern void [=(. lc-prefix)=]warning_msg( char const * fmt, ...);[= + ENDIF have warn-code =] +#ifdef __cplusplus +} +#endif[= + +ENDDEF emit-program-externs + +// # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE emit-exit-codes + +=] +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Enumeration of [= prog-name =] exit codes + */ +typedef enum {[= + + (define exit-name-len 15) =][= + + FOR exit-name =][= + + (set! tmp-val (string-length (get "exit-name"))) + (if (> tmp-val exit-name-len) + (set! exit-name-len tmp-val)) =][= + + ENDFOR exit-name =][= + #/* + ;; Assume no definitions for exit-name[0] and [1]. If not true, + ;; then change the strings associated with the ones defined to the + ;; specified name. If the assumption is correct, we'll need to + ;; emit the a default value into the enumeration.. + =][= ;; */ + (set! tmp-val "") + (define no-mem-func #f) + (define need-ex-noinput (exist? "homerc")) + (define noinput-err-name "") + (define need-ex-software #t) + (define need-ex-usage #t) + (define usage-err-name "") + (define exit-code-fmt (sprintf + "\n %s_EXIT_%%-%us = %%d" pname-up exit-name-len )) + + (define succ-exit-code (string-append pname-up "_EXIT_SUCCESS")) + (if (exist? "exit-name[0]") + (set! succ-exit-code (string-append + pname-up "_EXIT_" (get-up-name "exit-name[0]") )) + + (set! tmp-val (sprintf exit-code-fmt "SUCCESS" 0)) + ) + + (define fail-exit-code (string-append pname-up "_EXIT_FAILURE")) + (if (exist? "exit-name[1]") + (set! fail-exit-code (string-append + pname-up "_EXIT_" (get-up-name "exit-name[1]") )) + + (set! tmp-val (string-append tmp-val + (if (> (string-length tmp-val) 1) "," "") + (sprintf exit-code-fmt "FAILURE" 1) )) + ) + + (define nomem-exit-code fail-exit-code) + (set! exit-code-fmt (string-append "," exit-code-fmt)) + + tmp-val =][= + + FOR exit-name =][= + (define err-name (get-up-name "exit-name")) + (if (~~ err-name "(NO_MEM|NOMEM)") (begin + (set! no-mem-func #t) + (set! nomem-exit-code (string-append + pname-up "_EXIT_" err-name)) )) + (sprintf exit-code-fmt err-name (for-index)) + =][= + + CASE (for-index) =][= + == 64 =][= (set! need-ex-usage #f) + (set! usage-err-name err-name) =][= + == 66 =][= (set! need-ex-noinput #f) + (set! noinput-err-name err-name) =][= + == 70 =][= (set! need-ex-software #f) =][= + ESAC (for-index) =][= + ENDFOR =][= + + (if need-ex-usage (begin + (set! usage-err-name (string-append pname-up "_EXIT_USAGE_ERROR")) + (ag-fprintf 0 exit-code-fmt "USAGE_ERROR" 64) )) + + (if need-ex-noinput (begin + (set! tmp-val (string-append pname-up "_EXIT_NO_CONFIG_INPUT")) + (ag-fprintf 0 exit-code-fmt "NO_CONFIG_INPUT" 66))) + + (define file-fail-exit-code + (if (exist? "file-fail-code") + (string-append pname-up "_EXIT_" (get-up-name "file-fail-code")) + (if need-ex-noinput + (string-append pname-up "_EXIT_NO_CONFIG_INPUT") + fail-exit-code ))) + + (if need-ex-software (begin + (set! need-ex-software (string-append pname-up "_EXIT_LIBOPTS_FAILURE")) + (ag-fprintf 0 exit-code-fmt "LIBOPTS_FAILURE" 70))) +=] +} [= (. pname-down) =]_exit_code_t;[= + +ENDDEF emit-exit-codes + +// # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE emit-opt-values + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +Autoopts maintained option values. + +If *any* option flag value is specified, +then we provide flag characters for our options. +Otherwise, we will use the INDEX_* values for the option value. + +There are no documentation strings because these defines +are used identically to the user-generated VALUE defines. + +*/ =][= + +IF (exist? "flag.value") =][= + + INVOKE set-std-value + val-name = "help-value" + val-UPNAME = "HELP" + std-value = "?" =][= + + IF (not (exist? "no-libopts")) =][= + INVOKE set-std-value + val-name = "more-help-value" + val-UPNAME = "MORE_HELP" + std-value = "!" =][= + ENDIF don't have no-libopts ' =][= + + IF (exist? "resettable") =][= + INVOKE set-std-value + val-name = "reset-value" + val-UPNAME = "RESET_OPTION" + std-value = "R" =][= + ENDIF have "reset" =][= + + IF (exist? "version") =][= + INVOKE set-std-value + val-name = "version-value" + val-UPNAME = "VERSION" + std-value = "v" =][= + ENDIF have "version" =][= + + IF (exist? "usage-opt") =][= + INVOKE set-std-value + val-name = "usage-value" + val-UPNAME = "USAGE" + std-value = "u" =][= + ENDIF have "usage-opt" =][= + + IF (exist? "vendor-opt") =][= + INVOKE set-std-value + val-name = "vendor-value" + val-UPNAME = "VENDOR_OPT" + std-value = "W" =][= + ENDIF have "vendor-opt" =][= + + IF (exist? "homerc") =][= + + IF (not (exist? "disable-save")) =][= + INVOKE set-std-value + val-name = "save-opts-value" + val-UPNAME = "SAVE_OPTS" + std-value = ">" =][= + ELSE =] +#define [= (sprintf "%-23s 0" (string-append VALUE-pfx "SAVE_OPTS")) + =][= + ENDIF =][= + IF (not (exist? "disable-load")) =][= + INVOKE set-std-value + val-name = "load-opts-value" + val-UPNAME = "LOAD_OPTS" + std-value = "<" =][= + ELSE =] +#define [= (sprintf "%-23s 0" (string-append VALUE-pfx "LOAD_OPTS")) + =][= + ENDIF =][= + ENDIF have "homerc" =][= + +ELSE NO "flag.value" =] +[= +(set! index-fmt (string-append + "\n/** option value for %s option */" + "\n#define " VALUE-pfx "%-16s %s")) + (define std-vals (lambda (std-nm) + (ag-fprintf 0 index-fmt (string-downcase std-nm) std-nm (get-value-idx)) + ) ) + +(if (exist? "resettable") (std-vals "RESET_OPTION")) +(if (exist? "version") (std-vals "VERSION")) +(std-vals "HELP") +(if (not (exist? "no-libopts")) (std-vals "MORE_HELP")) +(if (exist? "usage-opt") (std-vals "USAGE")) +(if (exist? "homerc") (begin + (if (not (exist? "disable-save")) + (std-vals "SAVE_OPTS")) + (if (not (exist? "disable-load")) + (std-vals "LOAD_OPTS")) +) ) =][= + +ENDIF have flag.value/not =][= + +ENDDEF emit-opt-values + +// # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE emit-option-guards + +=][= + +CASE guard-option-names =][= +!E =][= += full-enum =][= + + +=* no-warn =] +/** + * Make sure there are no #define name conflicts with the option names + * @{ + */[= + FOR flag =] +#undef [= (get-up-name "name") =][= + ENDFOR flag + +// # # # # # # # # # # # # # # # # # =][= + +* =][= + + (define undef-list "\n#else /* NO_OPTION_NAME_WARNINGS */") + (define conf-warn-fmt (string-append + "\n# ifdef %1$s" + "\n# warning undefining %1$s due to option name conflict" + "\n# undef %1$s" + "\n# endif" )) + +=] +/** @} */ +/** + * Make sure there are no #define name conflicts with the option names + */ +#ifndef NO_OPTION_NAME_WARNINGS[= + + FOR flag =][= + + (set! opt-name (get-up-name "name")) + (set! undef-list (string-append undef-list "\n# undef " opt-name)) + (sprintf conf-warn-fmt opt-name) + =][= + + ENDFOR flag =][= + + (. undef-list)=] +#endif /* NO_OPTION_NAME_WARNINGS */ +[= + +ESAC =][= + +ENDDEF emit-option-guards + +// # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE set-std-value + +=] +/** option flag (value) for [= (get "val-name") =] option */ +#define [= (sprintf "%-23s " (string-append VALUE-pfx (get "val-UPNAME"))) =][= + CASE (define tmp-val (get "val-name")) + (get tmp-val) =][= + + == "" =][= + (if (exist? tmp-val) + (if (not (exist? "long-opts")) + (error (sprintf "'%s' may not be empty" tmp-val)) + (get-value-idx) + ) + + (sprintf "'%s'" (get "std-value")) + ) =][= + + == "'" =]'\''[= + ~~ . =]'[=(get tmp-val)=]'[= + * =][= (error (sprintf "option %s has multiple character flag value" + (get "val-name"))) =][= + ESAC =][= + +ENDDEF set-std-value + +// # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE join-or-expand + +=][= + IF (define join-type (get "join-type")) + (exist? join-type) \=] +/* + * global [=(string-append join-type (if (==* join-type "inc") "d" "ed")) + =] definitions + */ +[= + IF + (set! tmp-text (join "\n\n" (stack join-type))) + (~* (get join-type) "^[^a-z0-9_]{2,}[ \t]+autogen5[ \t]+template") + =][= + INCLUDE (begin + (set! tmp-val (string-append tmp-dir "/" join-type "-text")) + (out-push-new tmp-val) + (emit tmp-text) + (out-pop) + tmp-val + ) =][= + ELSE text is not template =][= + (. tmp-text) =][= + ENDIF text is template =] +[=ENDIF join-type =][= +ENDDEF join-or-expand + +// # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE nls-header-code + +=] + +/* * * * * * + * + * Declare the [=prog-name=] option descriptor. + */ +extern tOptions [=(. pname)=]Options;[= + + (if (> (string-length added-hdr) 0) + (begin + (emit "\n") + (shellf "sort -u <<_EOF_\n%s_EOF_" added-hdr) + ) ) =][= + + IF (not omit-nls-code) =] + +#if defined(ENABLE_NLS) +# ifndef _ +# include +# ifndef HAVE_GETTEXT + extern char * gettext(char const *); +# else +# include +# endif + +# ifndef ATTRIBUTE_FORMAT_ARG +# define ATTRIBUTE_FORMAT_ARG(_a) +# endif + +static inline char* aoGetsText(char const* pz) ATTRIBUTE_FORMAT_ARG(1); +static inline char* aoGetsText(char const* pz) { + if (pz == NULL) return NULL; + return (char*)gettext(pz); +} +# define _(s) aoGetsText(s) +# endif /* _() */ + +# define OPT_NO_XLAT_CFG_NAMES STMTS([=(. pname)=]Options.fOptSet |= \ + OPTPROC_NXLAT_OPT_CFG;) +# define OPT_NO_XLAT_OPT_NAMES STMTS([=(. pname)=]Options.fOptSet |= \ + OPTPROC_NXLAT_OPT|OPTPROC_NXLAT_OPT_CFG;) + +# define OPT_XLAT_CFG_NAMES STMTS([=(. pname)=]Options.fOptSet &= \ + ~(OPTPROC_NXLAT_OPT|OPTPROC_NXLAT_OPT_CFG);) +# define OPT_XLAT_OPT_NAMES STMTS([=(. pname)=]Options.fOptSet &= \ + ~OPTPROC_NXLAT_OPT;) + +#else /* ENABLE_NLS */[= + ENDIF no-nls-support =] +# define OPT_NO_XLAT_CFG_NAMES +# define OPT_NO_XLAT_OPT_NAMES + +# define OPT_XLAT_CFG_NAMES +# define OPT_XLAT_OPT_NAMES + +# ifndef _ +# define _(_s) _s +# endif[= + +(if (not omit-nls-code) (emit "\n#endif /* ENABLE_NLS */")) =] +[= +ENDDEF nls-header-code + +/* + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * opthead.tpl ends here */ \=] diff --git a/autoopts/tpl/options.tpl b/autoopts/tpl/options.tpl new file mode 100644 index 0000000..a02acab --- /dev/null +++ b/autoopts/tpl/options.tpl @@ -0,0 +1,73 @@ +[= Autogen5 Template -*- Mode: scheme -*- + +h +c + +=][= +# This file contains the templates used to generate the +# option descriptions for client programs, and it declares +# the macros used in the templates. + +# This file is part of AutoOpts, a companion to AutoGen. +# AutoOpts is free software. +# AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +# +# AutoOpts is available under any one of two licenses. The license +# in use must be one of these two and the choice is under the control +# of the user of the license. +# +# The GNU Lesser General Public License, version 3 or later +# See the files "COPYING.lgplv3" and "COPYING.gplv3" +# +# The Modified Berkeley Software Distribution License +# See the file "COPYING.mbsd" +# +# These files have the following sha256 sums: +# +# 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +# 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +# 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd +=][= +;;# START-BUILDTREE-ISMS +;; +(shell "CLexe=${AGexe%/agen5/*}/columns/columns + test -x \"${CLexe}\" || { + CLexe=${AGexe%/autogen}/columns + test -x \"${CLexe}\" || die 'columns program is not findable' + }" +) +=][= # END-BUILDTREE-ISMS + +(shell "CLexe=`echo ${AGexe} | sed 's@/autogen@/columns@'` + test -x \"${CLexe}\" || CLexe=`which columns`") + +# END-INSTALL-ONLY-CODE =][= + + (dne " * " "/* ") =][= + +CASE (suffix) =][= + +== h =][= + + INCLUDE "optlib.tlib" =][= + INVOKE init-and-validate =][= + INVOKE option-copyright =][= + INCLUDE "opthead.tlib" =][= + +== c =][= + + (if (exist? "library") + (out-delete)) =][= + + INVOKE option-copyright =][= + INCLUDE "optcode.tlib" =][= + + (if (exist? "flag.extract-code") + (shellf "test -f %1$s.c && rm -f %1$s.c.save" (base-name))) =][= + +ESAC =][= +IF (exist? "addtogroup") =] +/** @} */[= ENDIF =] +/* [= (out-name) =] ends here */[= + +# options.tpl ends here =] diff --git a/autoopts/tpl/optlib.tlib b/autoopts/tpl/optlib.tlib new file mode 100644 index 0000000..8bbea3b --- /dev/null +++ b/autoopts/tpl/optlib.tlib @@ -0,0 +1,1344 @@ +[= AutoGen5 Template Library -*- Mode: scheme -*- + +# This file is part of AutoOpts, a companion to AutoGen. +# AutoOpts is free software. +# AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +# +# AutoOpts is available under any one of two licenses. The license +# in use must be one of these two and the choice is under the control +# of the user of the license. +# +# The GNU Lesser General Public License, version 3 or later +# See the files "COPYING.lgplv3" and "COPYING.gplv3" +# +# The Modified Berkeley Software Distribution License +# See the file "COPYING.mbsd" +# +# These files have the following sha256 sums: +# +# 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +# 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +# 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +=][= + +INCLUDE "tpl-config.tlib" =][= + +DEFINE init-and-validate =][= + +(if (not (exist? "flag.name")) + (error "No options have been defined" )) + +(if (> (count "flag") 100) + (error (sprintf "%d options are too many - limit of 100" + (count "flag")) )) + +(if (not (and (exist? "prog-name") (exist? "prog-title"))) + (error "prog-name and prog-title are required")) +(define prog-name (get "prog-name")) +(if (> (string-length prog-name) 16) + (error (sprintf "prog-name limited to 16 characters: %s" + prog-name)) ) + +(make-tmp-dir) +(define have-proc #f) +(define proc-name "") +(define test-name "") +(define tmp-text "") +(define is-extern #t) +(define is-lib-cb #f) +(define have-cb-procs (make-hash-table 31)) +(define is-ext-cb-proc (make-hash-table 31)) +(define is-lib-cb-proc (make-hash-table 31)) +(define cb-proc-name (make-hash-table 31)) +(define test-proc-name (make-hash-table 31)) +(define disable-name (make-hash-table 31)) +(define disable-prefix (make-hash-table 31)) +(define ifdef-ed (make-hash-table 31)) +(define tmp-ct 0) +(define extract-fmt "\n/* extracted from %s near line %d */\n") +(define make-callback-procs #f) +(define omit-nls-code (~ (get "no-xlate") "(any|no)thing")) +(define xlate-desc-p (and (not omit-nls-code) (not (exist? "full-usage")))) +(define alt-value-idx 4096) +(define get-value-idx (lambda() (begin + (set! alt-value-idx (+ 1 alt-value-idx)) + (sprintf "0x%X" alt-value-idx )))) + +(define have-noret-funcs + (or (exist? "usage-message") (exist? "die-code")) ) + +(define need-stacking (lambda() + (if (not (exist? "max")) + #f + (> (string->number (get "max")) 1) +) ) ) + +(define get-text (lambda (nm) (shell + "{ sed 's/@[a-z]*{\\([^}]*\\)}/\\1/g' | " + "${CLexe} --fill -I0 -W72\n}<<\\_EODesc_\n" + (get nm) "\n_EODesc_" ))) + +(define do-ifdefs (or (exist? "flag.ifdef") (exist? "flag.ifndef"))) + +;; IF long options are disallowed +;; AND at least one flag character (value) is supplied +;; THEN every option must have a 'value' attribute +;; +(define flag-options-only + (and (not (exist? "long-opts")) (exist? "flag.value"))) + +(if (exist? "vendor-opt") (begin + ;; except the 'vendor-opt' attribute allows long options that do + ;; not have flag values, but it conflicts with 'long-opts' and requires + ;; at least one 'flag.value' + ;; + (if (or (exist? "long-opts") (not (exist? "flag.value"))) + (error "'vendor-opt' and 'long-opts' conflict. flag values required") + (set! flag-options-only #f)) + (if (exist? "library") + (error "'vendor-opt' conflicts with 'library'")) +) ) + +(if (and (exist? "reorder-args") (not (exist? "argument")) ) + (error + "Reordering arguments requires operands (the 'argument' attribute)")) + +(if (and flag-options-only (exist? "flag.disable")) + (error "options can be disabled only with a long option name")) + +(if (exist? "flag.extract-code") + (shellf "f=%s.c ; test -s $f && mv -f $f $f.save" + (base-name))) + +(if (and (exist? "usage") (exist? "gnu-usage")) + (error "'usage' and 'gnu-usage' conflict." )) + +(if (> (count "flag.default") 1) + (error "Too many default options")) + +(if (exist? "library") (begin + (if (not (exist? "flag[0].documentation")) (error + "The first option of a library must be a documentation option")) + (if (not (exist? "flag[0].lib-name")) + (error "The first option of a library must specify 'lib-name'")) + (if (< 1 (count "flag.lib-name")) + (error "a library must only have one 'flag.lib-name'")) +) ) + +(if (exist? "main") (begin + (if (> (count "main") 1) + (error "too many main procedures")) + (if (not (exist? "main.main-type")) + (error "main procedure does not have a type") ) )) + +;; Establish a number of variations on the spelling of the +;; program name. Use these Scheme defined values throughout. +;; +(define pname (get-c-name "prog-name")) +(define pname-cap (string-capitalize pname)) +(define pname-up (string-upcase pname)) +(define pname-down (string-downcase pname)) +(define number-opt-index -1) +(define default-opt-index -1) + +(define guarded-test-main (or (exist? "test-main") + (string? (getenv "TEST_MAIN")))) +(if guarded-test-main + (warn "'test-main' is obsolete and should not be used any more. Use 'main'.")) + +(define main-guard (string-append "TEST_" pname-up "_OPTS" )) +(define make-main-proc + (if (exist? "main") + (~~ (get "main[].main-type" "") "shell-process|shell-parser|main") + guarded-test-main ) ) +(if (not make-main-proc) (set! guarded-test-main #f)) + +(define descriptor "") +(define opt-name "") +(define tmp-val "") +(define added-hdr "") + +(define flg-name "") +(define UP-name "") +(define cap-name "") +(define low-name "") +(define enum-pfx "") + +(define set-flag-names (lambda () (begin + (set! flg-name (get "name")) + (set! UP-name (get-up-name "name")) + (set! cap-name (string-capitalize UP-name )) + (set! low-name (string-downcase UP-name )) + (set! enum-pfx (if (exist? ".prefix-enum") + (string-append (get-up-name "prefix-enum") "_") + (string-append UP-prefix UP-name "_") )) +) ) ) + +(define UP-prefix "") +(define lc-prefix "") +(define Cap-prefix "") +(define OPT-pfx "OPT_") +(define INDEX-pfx "INDEX_OPT_") +(define VALUE-pfx "VALUE_OPT_") + +(if (exist? "prefix") + (begin + (set! UP-prefix (string-append (get-up-name "prefix") "_")) + (set! lc-prefix (string-downcase UP-prefix)) + (set! Cap-prefix (string-capitalize UP-prefix)) + (set! OPT-pfx (string-append UP-prefix "OPT_")) + (set! INDEX-pfx (string-append "INDEX_" OPT-pfx)) + (set! VALUE-pfx (string-append "VALUE_" OPT-pfx)) + ) ) + +(define cap-c-name (lambda (ag-name) + (string-capitalize! (get-c-name ag-name)) )) + +(define index-name (lambda (i-name) + (string-append INDEX-pfx (get-up-name i-name)) )) + +(define optname-from "A-Z_^") +(define optname-to "a-z--") +(if (exist? "preserve-case") + (begin + (set! optname-from "_^") + (set! optname-to "--") +) ) + +(define version-text (string-append prog-name + (if (exist? "package") + (string-append " (" (get "package") ")") + "" ) + (if (exist? "version") + (string-append " " (get "version")) + "" ) )) + +(if (exist? "flag.value") + (shellf " + + list=`echo '%s' | sort` + ulst=`echo \"${list}\" | sort -u` + test `echo \"${ulst}\" | wc -l` -ne %d && { + echo \"${list}\" > ${tmp_dir}/sort + echo \"${ulst}\" > ${tmp_dir}/uniq + df=`diff ${tmp_dir}/sort ${tmp_dir}/uniq | sed -n 's/< *//p'` + die 'duplicate option value characters:' ${df} + }" + + (join "\n" (stack "flag.value")) + (count "flag.value") ) ) + +(define temp-idx 0) +(define no-flag-ct 0) +(define lib-opt-ptr "") +(define max-name-len 10) =][= + + +FOR flag =][= + + (set! tmp-ct (len "name")) + (if (> tmp-ct 32) + (error (sprintf "Option %d name exceeds 32 characters: %s" + (for-index) (get "name")) )) + (if (> tmp-ct max-name-len) + (set! max-name-len tmp-ct)) + + (if (exist? "value") + (if (< 1 (count "value")) + (error (sprintf "Option %s has too many `value's" (get "name")))) + (set! no-flag-ct (+ 1 no-flag-ct)) + ) + + (if (and flag-options-only + (not (exist? "documentation")) + (not (exist? "value"))) + (error (sprintf "Option %s needs a `value' attribute" (get "name")))) + + (set! tmp-val + (+ (if (exist? "call-proc") 1 0) + (if (exist? "extract-code") 1 0) + (if (exist? "flag-proc") 1 0) + (if (exist? "unstack-arg") 1 0) + (if (exist? "stack-arg") 1 0) )) + + ;; IF there is one of the above callback proc types AND there is an + ;; option argument of type non-string, THEN oops. Conflict. + ;; + (if (and (> tmp-val 0) (exist? "arg-type") + (not (=* (get "arg-type") "str")) ) + (error (sprintf + "Option %s has a %s argument and a callback procedure" + (get "name") (get "arg-type") ) + ) ) + + ;; Count up the ways a callback procedure was specified. Must be 0 or 1 + ;; + (if (< 1 (+ (if (exist? "arg-range") 1 0) + (if (~* (get "arg-type") "key|set") 1 0) tmp-val)) + (error (sprintf "Option %s has multiple callback specifications" + (get "name")) )) + + (if (< 1 (+ (count "ifdef") (count "ifndef") )) + (error (sprintf "Option %s has multiple 'ifdef-es'" (get "name") )) ) + + (if (and (exist? "stack-arg") (not (exist? "arg-type"))) + (error (sprintf "Option %s has stacked args, but no arg-type" + (get "name")))) + + (if (and (exist? "min") (exist? "must-set")) + (error (sprintf "Option %s has both 'min' and 'must-set' attributes" + (get "name")))) + + (if (and (exist? "omitted-usage") + (not (exist? "ifdef")) + (not (exist? "ifndef")) ) + (error (string-append "Option " (get "name") " has 'omitted-usage' " + "but neither 'ifdef' nor 'ifndef'" )) ) + + (if (and (exist? "equivalence") + (exist? "aliases")) + (error (string-append "Option " (get "name") " has both " + "'equivalence' and 'aliases'" )) ) + + (if (exist? "lib-name") + (set! lib-opt-ptr (string->c-name! (string-append + (get "lib-name") "_" (get "name") "_optDesc_p"))) ) +=][= + +ENDFOR flag + +=][= +(if (and (exist? "vendor-opt") (= no-flag-ct 0)) + (error "'vendor-opt' requires that there be options without flag values")) + +(define opt-strs (string-append pname "_opt_strs")) +(string-table-new opt-strs) +(out-push-new) (out-suspend "home-list") +(if (not omit-nls-code) (begin + (out-push-new) + (out-suspend "xget") +) ) +(define field-name-fmt (string-append + "\n /* referenced via " pname "Options.%s */\n")) +(define put-xget (lambda (nm st) (begin + (out-resume "xget") + (ag-fprintf 0 field-name-fmt nm) + (mk-gettextable st) + (out-suspend "xget") +) ) ) +=][= + +ENDDEF init-and-validate + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE save-name-morphs + + Save the various flag name morphs into hash tables + + Every option descriptor has a pointer to a handler procedure. That + pointer may be NULL. We generate a procedure for keyword, + set-membership and range checked options. "optionStackArg" is called + if "stack-arg" is specified. The specified procedure is called if + "call-proc" is specified. Finally, we insert the specified code for + options with "flag-code" or "extract-code" attributes. + + =][= + + IF + + (set-flag-names) + (hash-create-handle! ifdef-ed flg-name + (and do-ifdefs (or (exist? "ifdef") (exist? "ifndef"))) ) + (set! proc-name (string-append "doOpt" cap-name)) + (set! is-lib-cb #f) + + (exist? "call-proc") + + =][= # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + + (set! have-proc #t) + (set! is-extern #t) + (set! proc-name (get "call-proc")) + (set! test-name (if need-stacking "optionStackArg" "NULL")) + =][= + + ELIF (or (exist? "extract-code") + (exist? "flag-code") + (exist? "aliases") + (exist? "arg-range")) + =][= + + (set! have-proc #t) + (set! is-extern #f) + (set! test-name (if (or (exist? "arg-range") (exist? "aliases")) + proc-name + (if need-stacking "optionStackArg" "NULL") )) + =][= + + ELIF (exist? "flag-proc") =][= + + (set! have-proc #t) + (set! proc-name (string-append "doOpt" (cap-c-name "flag-proc"))) + (set! test-name (if need-stacking "optionStackArg" "NULL")) + (set! is-extern #f) + =][= + + ELIF (exist? "stack-arg") =][= + + (if (not (exist? "max")) + (error (string-append flg-name + " has a stacked arg, but can only appear once")) ) + + (set! have-proc #t) + (set! proc-name "optionStackArg") + (set! is-lib-cb #t) + (set! test-name (if need-stacking proc-name "NULL")) + (set! is-extern #t) + =][= + + ELIF (exist? "unstack-arg") =][= + + (set! have-proc #t) + (set! proc-name "optionUnstackArg") + (set! is-lib-cb #t) + (set! test-name (if need-stacking proc-name "NULL")) + (set! is-extern #t) + =][= + + ELSE =][= + + CASE arg-type =][= + =* bool =][= + (set! proc-name "optionBooleanVal") + (set! is-lib-cb #t) + (set! test-name proc-name) + (set! is-extern #t) + (set! have-proc #t) =][= + + =* num =][= + (set! proc-name "optionNumericVal") + (set! is-lib-cb #t) + (set! test-name proc-name) + (set! is-extern #t) + (set! have-proc #t) =][= + + = time-date =][= + (set! proc-name "optionTimeDate") + (set! is-lib-cb #t) + (set! test-name proc-name) + (set! is-extern #t) + (set! have-proc #t) =][= + + =* time =][= + (set! proc-name "optionTimeVal") + (set! is-lib-cb #t) + (set! test-name proc-name) + (set! is-extern #t) + (set! have-proc #t) =][= + + ~* key|set|fil =][= + (set! test-name proc-name) + (set! is-extern #f) + (set! have-proc #t) =][= + + ~* hier|nest =][= + (set! proc-name "optionNestedVal") + (set! is-lib-cb #t) + (set! test-name proc-name) + (set! is-extern #t) + (set! have-proc #t) =][= + + * =][= + (set! have-proc #f) =][= + ESAC =][= + + ENDIF =][= + + ;; If these are different, then a #define name is inserted into the + ;; option descriptor table. Never a need to mess with it if we are + ;; not building a "test main" procedure. + ;; + (if (not guarded-test-main) + (set! test-name proc-name)) + + (if have-proc + (begin + (hash-create-handle! have-cb-procs flg-name #t) + (hash-create-handle! cb-proc-name flg-name proc-name) + (hash-create-handle! test-proc-name flg-name test-name) + (hash-create-handle! is-ext-cb-proc flg-name is-extern) + (hash-create-handle! is-lib-cb-proc flg-name is-lib-cb) + (set! make-callback-procs #t) + ) + (begin + (hash-create-handle! have-cb-procs flg-name #f) + (hash-create-handle! cb-proc-name flg-name "NULL") + (hash-create-handle! test-proc-name flg-name "NULL") + ) + ) + + (if (exist? "default") + (set! default-opt-index (. flag-index)) ) + +=][= + +ENDDEF save-name-morphs + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +Emit the "#define SET_OPT_NAME ..." and "#define DISABLE_OPT_NAME ..." =][= + +DEFINE set-defines + +=] +#define SET_[=(. opt-name)=][= (if (exist? "arg-type") "(a)") + =] STMTS( \ + [=set-desc=].optActualIndex = [=(. flag-index)=]; \ + [=set-desc=].optActualValue = VALUE_[=(. opt-name)=]; \ + [=set-desc=].fOptState &= OPTST_PERSISTENT_MASK; \ + [=set-desc=].fOptState |= [=opt-state=][= + CASE arg-type =][= + ~* str|fil =]; \ + [=set-desc=].optArg.argString = (a)[= + =* num =]; \ + [=set-desc=].optArg.argInt = (a)[= + =* time =]; \ + [=set-desc=].optArg.argInt = (a)[= + =* bool =]; \ + [=set-desc=].optArg.argBool = (a)[= + =* key =]; \ + [=set-desc=].optArg.argEnum = (a)[= + =* set =]; \ + [=set-desc=].optArg.argIntptr = (a)[= + ~* hier|nest =]; \ + [=set-desc=].optArg.argString = (a)[= + + ESAC arg-type =][= + + IF (hash-ref have-cb-procs flg-name) =]; \ + (*([=(. descriptor)=].pOptProc))(&[=(. pname)=]Options, \ + [=(. pname)=]Options.pOptDesc + [=set-index=]);[= + ENDIF "callout procedure exists" =] )[= + + IF (exist? "disable") =][= + IF (~* (get "arg-type") "hier|nest") =] +#define DISABLE_[=(. opt-name)=](a) STMTS( \ + [=set-desc=].fOptState &= OPTST_PERSISTENT_MASK; \ + [=set-desc=].fOptState |= OPTST_SET | OPTST_DISABLED; \ + [=set-desc=].optArg.argString = (a); \ + optionNestedVal(&[=(. pname)=]Options, \ + [=(. pname)=]Options.pOptDesc + [=set-index=]);)[= + + ELSE =] +#define DISABLE_[=(. opt-name)=] STMTS( \ + [=set-desc=].fOptState &= OPTST_PERSISTENT_MASK; \ + [=set-desc=].fOptState |= OPTST_SET | OPTST_DISABLED; \ + [=set-desc=].optArg.argString = NULL[= + IF (hash-ref have-cb-procs flg-name) =]; \ + (*([=(. descriptor)=].pOptProc))(&[=(. pname)=]Options, \ + [=(. pname)=]Options.pOptDesc + [=set-index=]);[= + ENDIF "callout procedure exists" =] )[= + ENDIF =][= + ENDIF disable exists =][= + +ENDDEF set-defines + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +Emit the copyright comment =][= + +DEFINE option-copyright =] + * + * Generated from AutoOpts [=(. ao-version)=] templates. + * + * AutoOpts is a copyrighted work. This [= + (if (= "h" (suffix)) "header" "source") =] file is not encumbered + * by AutoOpts licensing, but is provided under the licensing terms chosen + * by the [= prog-name =] author or copyright holder. AutoOpts is + * licensed under the terms of the LGPL. The redistributable library + * (``libopts'') is licensed under the terms of either the LGPL or, at the + * users discretion, the BSD license. See the AutoOpts and/or libopts sources + * for details.[= + +IF (exist? "copyright") =] + * + * The [= prog-name =] program is copyrighted and licensed + * under the following terms: + * +[= + CASE copyright.type =][= + == "" =][= + (sprintf " * %s Copyright (C) %s %s - all rights reserved\n * %s" + prog-name (get "copyright.date") (get "copyright.owner") + "licensing type not specified" ) =][= + + = note =][= (prefix " * " (get "copyright.text")) =][= + + * =][= (license-full (get "copyright.type") prog-name " * " + (get "copyright.owner") (get "copyright.date")) =][= + ESAC =][= +ENDIF "copyright exists" =] + */ +[= + +IF (exist? "addtogroup") \=] +/** \file [= (out-name) =] + * \addtogroup [= addtogroup =] + * @{ + */ +[= +ENDIF =][= + +ENDDEF option-copyright + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +Emit usage text =][= + +DEFINE emit-help-text \=] +#define [= + (set! tmp-val (string-append (get "help-type") "-usage")) + (string->c-name! (string-append pname "_" tmp-val)) =] ([= + + CASE (set! tmp-val (get tmp-val "<<>>")) + tmp-val =][= + + == "<<>>" =]NULL[= + + == "" =][= + + (out-push-new) =][= + INCLUDE "usage.tlib" =][= + (define tmp-val (out-pop #t)) =][= + (string-table-add-ref opt-strs tmp-val) =][= + + ~ "[a-z][a-z0-9_]*" =][= (. tmp-val) =][= + + * anything else must be plain text =][= + (string-table-add-ref opt-strs tmp-val) =][= + ESAC flavor of usage text. =]) +[= +(if (not omit-nls-code) (begin + (set! tmp-text (string-append + "pz" (string-capitalize (get "help-type")) "Usage")) + (put-xget tmp-text tmp-val) )) =][= + +ENDDEF emit-help-text + +;; # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE emit-keyword-enum =] +typedef enum {[= + (if (not (exist? "arg-default")) + (string-append " " enum-pfx "UNDEFINED = 0,")) =] +[=(shellf +"for f in %s ; do echo %s${f} ; done | \ + ${CLexe} -I4 --spread=3 --sep=, +test $? -eq 0 || die ${CLexe} failed" + (string-upcase! (string->c-name! (join " " (stack "keyword")))) + enum-pfx )=] +} te_[=(string-append Cap-prefix cap-name)=]; +#define [= (sprintf "%-24s" (string-append OPT-pfx UP-name "_VAL2STR(_v)")) + =] optionKeywordName(&[=(. value-desc)=], (_v)) +#define [=(. OPT-pfx)=]VALUE_[=(sprintf "%-14s" UP-name) + =] ([=(. value-desc)=].optArg.argEnum)[= + +ENDDEF emit-keyword-enum + +;; # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE emit-member-mask =][= + + (define setmember-fmt (string-append "\n#define %-24s 0x%0" + (shellf "expr '(' %d + 4 ')' / 4" (count "keyword")) "XUL" + (if (> (count "keyword") 32) "L" "") )) + (define full-prefix (string-append UP-prefix UP-name) ) =][= + + FOR keyword =][= + + (sprintf setmember-fmt + (string->c-name! (string-append + full-prefix "_" (string-upcase! (get "keyword")) )) + (ash 1 (for-index)) ) =][= + + ENDFOR keyword =][= + + (ag-fprintf 0 setmember-fmt (string->c-name! (string-append + full-prefix "_MEMBERSHIP_MASK")) + (- (ash 1 (count "keyword")) 1) ) =] +#define [=(sprintf "%sVALUE_%-14s ((uintptr_t)%s.optCookie)" + OPT-pfx UP-name value-desc) + =] +#define [=(sprintf "%1$sMEMLST_%2$-13s optionMemberList(&%3$s)" + OPT-pfx UP-name value-desc) + =][= + +ENDDEF emit-member-mask + +;; # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE emit-value-defines =][= + + CASE arg-type =][= + + =* num =] +#define [=(. OPT-pfx)=]VALUE_[=(sprintf "%-14s" UP-name) + =] ([=(. value-desc)=].optArg.argInt)[= + + =* time =] +#define [=(. OPT-pfx)=]VALUE_[=(sprintf "%-14s" UP-name) + =] ([=(. value-desc)=].optArg.argInt)[= + + =* key =][= + INVOKE emit-keyword-enum =][= + + =* set =][= + INVOKE emit-member-mask =][= + + =* bool =] +#define [=(. OPT-pfx)=]VALUE_[=(sprintf "%-14s" UP-name) + =] ([=(. value-desc)=].optArg.argBool)[= + + =* fil =][= + CASE open-file =][= + == "" =][= + =* desc =] +#define [=(. OPT-pfx)=]VALUE_[=(sprintf "%-14s" UP-name) + =] ([=(. value-desc)=].optArg.argFd)[= + * =] +#define [=(. OPT-pfx)=]VALUE_[=(sprintf "%-14s" UP-name) + =] ([=(. value-desc)=].optArg.argFp)[= + ESAC =][= + + ESAC =][= + +ENDDEF emit-value-defines + +;; # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE set-option-define =][= + + IF (exist? "unstack-arg") =][= + + set-defines + set-desc = (string-append UP-prefix "DESC(" + (get-up-name "unstack-arg") ")" ) + set-index = (index-name "unstack-arg") + opt-state = "OPTST_SET | OPTST_EQUIVALENCE" =][= + + ELIF (and (exist? "equivalence") + (not (== (get-up-name "equivalence") UP-name))) =][= + + set-defines + set-desc = (string-append UP-prefix "DESC(" + (get-up-name "equivalence") ")" ) + set-index = (index-name "equivalence") + opt-state = "OPTST_SET | OPTST_EQUIVALENCE" =][= + + ELSE "is equivalenced" =][= + + set-defines + set-desc = (string-append UP-prefix "DESC(" UP-name ")" ) + set-index = (. flag-index) + opt-state = OPTST_SET =][= + + ENDIF is/not equivalenced =][= + +ENDDEF set-option-define + +;; # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +;; +;; #define's for a single option +;; +;; First, emit defines that are always required. Then start collecting +;; defines in a diverted output. If there is any output, there will +;; be well more than 2 bytes of it. If so, actually emit it, but first +;; see if it needs to be enclused in a #ifdef/#endif pair. +;; =][= +DEFINE option-defines =] +#define VALUE_[= + (define value-desc (string-append UP-prefix "DESC(" + (if (exist? "equivalence") + (get-up-name "equivalence") + UP-name) ")" )) + (sprintf "%-18s" opt-name)=] [= + + CASE value =][= + !E =][= (get-value-idx) =][= + == "'" =]'\''[= + == "\\" =]'\\'[= + ~~ "[ -~]" =]'[=value=]'[= + + =* num =][= + (if (>= number-opt-index 0) + (error "only one number option is allowed") ) + (set! number-opt-index flag-index) + (get-value-idx) =][= + + * =][=(error (sprintf + "Error: value for opt %s is `%s'\nmust be single char or 'NUMBER'" + (get "name") (get "value")))=][= + + ESAC =][= + (out-push-new) =][= + INVOKE emit-value-defines =][= + + IF (== (get-up-name "equivalence") UP-name) =] +/** Define the option value [= name =] is equivalenced to */ +#define WHICH_[=(sprintf "%-18s" opt-name) + =] ([=(. descriptor)=].optActualValue) +/** Define the index of the option [= name =] is equivalenced to */ +#define WHICH_[=(. UP-prefix)=]IDX_[=(sprintf "%-14s" UP-name) + =] ([=(. descriptor)=].optActualIndex)[= + ENDIF =][= + + IF (exist? "settable") =][= + INVOKE set-option-define =][= + ENDIF settable =][= + + IF (define tmp-val (out-pop #t)) + (if (defined? 'tmp-val) + (> (string-length tmp-val) 2) + #f ) =][= + + IF (hash-ref ifdef-ed flg-name) =] +#if[=ifndef "n"=]def [= ifdef =][= ifndef \=] +[= (. tmp-val) =] +#endif /* [= ifdef =][= ifndef =] */[= + + ELSE =] +[= (. tmp-val) =][= + ENDIF =][= + ENDIF =][= + +ENDDEF Option_Defines + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE emit-alias-option + +=] +/** Descriptive text for the [= name =] option */ +#define [= (. UP-name) =]_DESC ([= + (set! tmp-val (string-append + "an alias for the '" (get "aliases") "' option")) + (if (exist? "deprecated") + (set! tmp-val (string-append tmp-val " (deprecated)")) ) + (if xlate-desc-p + (put-xget "pOptDesc->pzText" tmp-val) ) + (string-table-add-ref opt-strs tmp-val) =]) +#define [= (. UP-name) =]_NAME NULL +/** Unmodified name string for the [= name =] option */ +#define [= (. UP-name) =]_name ([= + (string-table-add-ref opt-strs (get "name")) =]) +/** Compiled in flag settings for the [= name =] option */ +#define [=(. UP-name)=]_FLAGS ([= + (get-up-name "aliases") =]_FLAGS | OPTST_ALIAS[= + (if (exist? "deprecated") " | OPTST_DEPRECATED") =])[= + +ENDDEF emit-alias-option " + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +Define the arrays of values associated with an option (strings, etc.) =][= + +DEFINE emit-nondoc-option =][= + (if (exist? "translators") + (string-append "\n" (shell + "${CLexe} -I16 --fill --first='/* TRANSLATORS:' <<\\_EOF_\n" + (get "translators") "\n_EOF_") + " */" ) ) =] +/** Descriptive text for the [= name =] option */ +#define [= (. UP-name) =]_DESC ([= + (define tmp-val (get-text "descrip")) + (if (exist? "deprecated") + (set! tmp-val (string-append tmp-val " (deprecated)")) ) + (if xlate-desc-p + (put-xget "pOptDesc->pzText" tmp-val) ) + (string-table-add-ref opt-strs tmp-val) =]) +/** Upper-cased name for the [= name =] option */ +#define [= (. UP-name) =]_NAME ([= + (string-table-add-ref opt-strs UP-name) =])[= + + # IF this option can be disabled, + # THEN we must create the string for the disabled version + # =][= + IF (> (len "disable") 0) =] +/** disablement name for the [= name =] option */ +#define NOT_[= (. UP-name) =]_name ([= + (hash-create-handle! disable-name flg-name (string-append + "NOT_" UP-name "_name" )) + (hash-create-handle! disable-prefix flg-name (string-append + "NOT_" UP-name "_PFX" )) + (string-table-add-ref opt-strs + (string-tr! (string-append (get "disable") "-" flg-name) + optname-from optname-to)) =]) +/** disablement prefix for the [= name =] option */ +#define NOT_[= (. UP-name) =]_PFX ([= + (string-table-add-ref opt-strs (string-downcase! (get "disable"))) =]) +/** Name string for the [= name =] option */ +#define [= (. UP-name) =]_name ([= + (if (> (len "enable") 0) + (string-table-add-ref opt-strs + (string-tr! (string-append (get "enable") "-" flg-name) + optname-from optname-to) ) + (sprintf "NOT_%s_name + %d" + UP-name (+ (string-length (get "disable")) 1 )) + ) =])[= + + ELSE No disablement of this option: =][= + + (hash-create-handle! disable-name flg-name "NULL") + (hash-create-handle! disable-prefix flg-name "NULL") "" + =] +/** Name string for the [= name =] option */ +#define [= (. UP-name) =]_name ([= + (string-table-add-ref opt-strs + (string-tr! (string-append + (if (exist? "enable") (string-append (get "enable") "-") "") + (get "name")) + optname-from optname-to)) =])[= + + ENDIF (> (len "disable") 0) + + # Check for special attributes: a default value + # and conflicting or required options + =][= + IF (define def-arg-name (sprintf "%-28s " + (string-append UP-name "_DFT_ARG" ))) + (exist? "arg-default") =] +/** The compiled in default value for the [= name =] option argument */ +#define [= (. UP-name) =]_DFT_ARG ([= + CASE arg-type =][= + =* num =](char const*)[= arg-default =][= + + =* time =](char const*)[= + (time-string->number (get "arg-default")) =][= + + =* bool =][= + CASE arg-default =][= + ~ n.*|f.*|0 =](char const*)false[= + * =](char const*)true[= + ESAC =][= + + =* key =](char const*)[= + (emit (if (=* (get "arg-default") enum-pfx) "" enum-pfx)) + (get-up-name "arg-default") =][= + + =* set =]NULL) +#define [=(sprintf "%-28s " (string-append cap-name "CookieBits"))=]VOIDP([= + IF (not (exist? "arg-default")) =]0[= + ELSE =][= + FOR arg-default | =][= + (string->c-name! (string-append UP-prefix UP-name "_" + (get-up-name "arg-default") )) =][= + ENDFOR arg-default =][= + ENDIF =][= + + =* str =][= + (string-table-add-ref opt-strs (get "arg-default")) =][= + + =* file =][= + (string-table-add-ref opt-strs (get "arg-default")) =][= + + * =][= + (error (string-append cap-name + " has arg-default, but no valid arg-type")) =][= + ESAC =])[= + ENDIF =][= + + + IF (exist? "flags-must") =] +/** Other options that are required by the [= name =] option */ +static int const a[=(. cap-name)=]MustList[] = {[= + FOR flags-must =] + [= (index-name "flags-must") =],[= + ENDFOR flags_must =] NO_EQUIVALENT };[= + ENDIF =][= + + + IF (exist? "flags-cant") =] +/** Other options that appear in conjunction with the [= name =] option */ +static int const a[=(. cap-name)=]CantList[] = {[= + FOR flags-cant =] + [= (index-name "flags-cant") =],[= + ENDFOR flags-cant =] NO_EQUIVALENT };[= + ENDIF =] +/** Compiled in flag settings for the [= name =] option */ +#define [= (. UP-name) =]_FLAGS ([= + ? enabled "OPTST_INITENABLED" + "OPTST_DISABLED" =][= + stack-arg " | OPTST_STACKED" =][= + must-set " | OPTST_MUST_SET" =][= + no-preset " | OPTST_NO_INIT" =][= + no-command " | OPTST_NO_COMMAND" =][= + deprecated " | OPTST_DEPRECATED" =][= + + CASE immediate =][= + = also =] | OPTST_IMM | OPTST_TWICE[= + +E =] | OPTST_IMM[= + ESAC immediate =][= + + CASE immed-disable =][= + = also =] | OPTST_DISABLE_IMM | OPTST_DISABLE_TWICE[= + +E =] | OPTST_DISABLE_IMM[= + ESAC immed-disable =][= + + IF (exist? "arg-type") =][= + CASE arg-type =][= + + =* num =] \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_NUMERIC)[= + IF (exist? "scaled") =] \ + | OPTST_SCALED_NUM[= ENDIF =][= + + =* time =] \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_TIME)[= + + =* bool =] \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_BOOLEAN)[= + + =* key =] \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_ENUMERATION)[= + + =* set =] \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_MEMBERSHIP)[= + + ~* hier|nest =] \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_HIERARCHY)[= + + =* str =] \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)[= + + =* fil =] \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_FILE)[= + + * =][= + (error (string-append "unknown arg type '" + (get "arg-type") "' for " flg-name)) =][= + ESAC arg-type =][= + (if (exist? "arg-optional") " | OPTST_ARG_OPTIONAL") =][= + ENDIF arg-type exists =])[= + +ENDDEF emit-nondoc-option + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +Define the arrays of values associated with an option (strings, etc.) =][= + +DEFINE emit-opt-strs + +=] +/** + * [= (set-flag-names) flg-name =] option description[= + IF (or (exist? "flags_must") (exist? "flags_cant")) =] with + * "Must also have options" and "Incompatible options"[= + ENDIF =]: + */[= + IF (hash-ref ifdef-ed flg-name) =] +#if[=ifndef "n"=]def [= (define if-def-name (get "ifdef" (get "ifndef"))) + if-def-name =][= + ENDIF ifdef-ed =][= + + IF (exist? "documentation") =] +/** [= name =] option separation text */ +#define [= (. UP-name) =]_DESC ([= + (define tmp-val (string-append (get-text "descrip") ":")) + (if xlate-desc-p + (put-xget "pOptDesc->pzText" tmp-val) ) + (string-table-add-ref opt-strs tmp-val) =]) +#define [= (. UP-name) =]_FLAGS (OPTST_DOCUMENT | OPTST_NO_INIT)[= + ELIF (exist? "aliases") =][= + INVOKE emit-alias-option =][= + ELSE =][= + INVOKE emit-nondoc-option =][= + ENDIF (exist? "documentation") =][= + + IF (hash-ref ifdef-ed flg-name) =] + +#else /* disable [= (. flg-name)=] */ +#define [= (. UP-name) =]_FLAGS (OPTST_OMITTED | OPTST_NO_INIT)[= + + IF (exist? "arg-default") =] +#define [= (. UP-name) =]_DFT_ARG NULL[= + ENDIF =][= + + IF (exist? "flags-must") =] +#define a[=(. cap-name)=]MustList NULL[= + ENDIF =][= + + IF (exist? "flags-cant") =] +#define a[=(. cap-name)=]CantList NULL[= + ENDIF =] +#define [= (. UP-name) =]_NAME NULL[= + + IF (exist? "omitted-usage") =] +/** Descriptive text for the [= name =] option */ +#define [= (. UP-name) =]_DESC ([= + (set! tmp-text (get "omitted-usage")) + (if (> (string-length tmp-text) 1) (begin + (if xlate-desc-p + (put-xget "pOptDesc->pzText" tmp-text) ) + (string-table-add-ref opt-strs tmp-text) ) + "NULL") =]) +#define [= (. UP-name) =]_name ([= + (string-table-add-ref opt-strs (get "name")) =])[= + + ELSE =] +#define [= (. UP-name) =]_DESC NULL +#define [= (. UP-name) =]_name NULL[= + ENDIF =][= + + IF (> (len "disable") 0) =] +#define NOT_[= (. UP-name) =]_name NULL +#define NOT_[= (. UP-name) =]_PFX NULL[= + ENDIF =] +#endif /* [= (. if-def-name) =] */[= + ENDIF ifdef-ed =][= + +ENDDEF opt-strs + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +Define the arrays of values associated with help/version/etc. =][= + +DEFINE help-strs + +=] + +/* + * Help[= (string-append + (if (exist? "no-libopts") "" "/More_Help") + (if (exist? "version") "/Version" "")) =] option descriptions: + */ +#define HELP_DESC ([= + (define tmp-text "display extended usage information and exit") + (if xlate-desc-p + (put-xget "pOptDesc->pzText" tmp-text) ) + (string-table-add-ref opt-strs tmp-text)=]) +#define HELP_name ([= + (string-table-add-ref opt-strs "help")=])[= + + IF (not (exist? "no-libopts")) + +=] +#ifdef HAVE_WORKING_FORK +#define MORE_HELP_DESC ([= + (define tmp-text "extended usage information passed thru pager") + (if xlate-desc-p + (put-xget "pOptDesc->pzText" tmp-text) ) + (string-table-add-ref opt-strs tmp-text)=]) +#define MORE_HELP_name ([= + (string-table-add-ref opt-strs "more-help")=]) +#define MORE_HELP_FLAGS (OPTST_IMM | OPTST_NO_INIT) +#else +#define MORE_HELP_DESC HELP_DESC +#define MORE_HELP_name HELP_name +#define MORE_HELP_FLAGS (OPTST_OMITTED | OPTST_NO_INIT) +#endif[= + + ENDIF (not (exist? "no-libopts")) =][= + + IF (exist? "version") + +=][= + CASE version-type =][= + ~* [vcn] =] +#define VER_FLAGS (OPTST_SET_ARGTYPE(OPARG_TYPE_STATIC) | \ + OPTST_IMM | OPTST_NO_INIT)[= + * =] +#ifdef NO_OPTIONAL_OPT_ARGS +# define VER_FLAGS (OPTST_IMM | OPTST_NO_INIT) +#else +# define VER_FLAGS (OPTST_SET_ARGTYPE(OPARG_TYPE_STRING) | \ + OPTST_ARG_OPTIONAL | OPTST_IMM | OPTST_NO_INIT) +#endif[= + ESAC =] +#define VER_DESC ([= + (define tmp-text "output version information and exit") + (if xlate-desc-p + (put-xget "pOptDesc->pzText" tmp-text) ) + (string-table-add-ref opt-strs tmp-text)=]) +#define VER_name ([= + (string-table-add-ref opt-strs "version")=])[= + + ENDIF (exist? "version") =][= + + IF (exist? "resettable") + +=] +#define RESET_DESC ([= + (define tmp-text "reset an option's state") + (if xlate-desc-p + (put-xget "pOptDesc->pzText" tmp-text) ) + (string-table-add-ref opt-strs tmp-text)=]) +#define RESET_name ([= + (string-table-add-ref opt-strs "reset-option")=]) +#define RESET_FLAGS (OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)|OPTST_NO_INIT)[= + + ENDIF (exist? "resettable") =][= + + IF (exist? "usage-opt") + +=] +#define USAGE_DESC ([= + (define tmp-text "abbreviated usage to stdout") + (if xlate-desc-p + (put-xget "pOptDesc->pzText" tmp-text) ) + (string-table-add-ref opt-strs tmp-text)=]) +#define USAGE_name ([= + (string-table-add-ref opt-strs "usage")=])[= + + ENDIF (exist? "usage-opt") =][= + + IF (exist? "vendor-opt") + +=] +#define VEND_DESC ([= + (define tmp-text "vendor supported additional options") + (if xlate-desc-p + (put-xget "pOptDesc->pzText" tmp-text) ) + (string-table-add-ref opt-strs tmp-text)=]) +#define VEND_name ([= + (string-table-add-ref opt-strs "vendor-option")=])[= + + ENDIF (exist? "vendor-opt") =][= + + IF (exist? "homerc") =][= + + IF (not (exist? "disable-save")) =] +#define SAVE_OPTS_DESC ([= + (define tmp-text "save the option state to a config file") + (if xlate-desc-p + (put-xget "pOptDesc->pzText" tmp-text) ) + (string-table-add-ref opt-strs tmp-text)=]) +#define SAVE_OPTS_name ([= + (string-table-add-ref opt-strs "save-opts")=])[= + + ENDIF no disable-save =][= + + IF (not (exist? "disable-load")) =] +#define LOAD_OPTS_DESC ([= + (define tmp-text "load options from a config file") + (if xlate-desc-p + (put-xget "pOptDesc->pzText" tmp-text) ) + (string-table-add-ref opt-strs tmp-text)=]) +#define LOAD_OPTS_NAME ([= + (string-table-add-ref opt-strs "LOAD_OPTS")=]) +#define NO_LOAD_OPTS_name ([= + (string-table-add-ref opt-strs "no-load-opts")=]) +#define LOAD_OPTS_pfx ([= + (string-table-add-ref opt-strs "no")=]) +#define LOAD_OPTS_name (NO_LOAD_OPTS_name + 3)[= + + ENDIF no disable-load =][= + + ENDIF (exist? "homerc") =][= + +ENDDEF help-strs + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +Define the values for an option descriptor =][= + +DEFINE emit-opt-desc =][= + IF + (set-flag-names) + + (exist? "documentation") + +=] + { /* entry idx, value */ 0, 0, + /* equiv idx, value */ 0, 0, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 0, 0, + /* opt state flags */ [=(. UP-name)=]_FLAGS, 0, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ [= + IF (exist? "call-proc") =][=call-proc=][= + ELIF (or (exist? "extract-code") + (exist? "flag-code")) =]doOpt[=(. cap-name)=][= + ELSE =]NULL[= + ENDIF =], + /* desc, NAME, name */ [= + (set! default-text (string-append default-text + "\n { NULL }, /* doc opt */" )) + (set! default-cookie (string-append default-cookie "NULL\n" )) + UP-name =]_DESC, NULL, NULL, + /* disablement strs */ NULL, NULL },[= + + ELSE + +=] + { /* entry idx, value */ [=(. flag-index)=], [= + (string-append VALUE-pfx UP-name)=], + /* equiv idx, value */ [= + IF (== (get-up-name "equivalence") UP-name) + =]NO_EQUIVALENT, 0[= + ELIF (or (exist? "equivalence") (exist? "unstack-arg")) + =]NOLIMIT, NOLIMIT[= + ELSE + =][=(. flag-index)=], [=(string-append VALUE-pfx UP-name)=][= + ENDIF=], + /* equivalenced to */ [= + (if (exist? "unstack-arg") + (index-name "unstack-arg") + (if (and (exist? "equivalence") + (not (== (get-up-name "equivalence") UP-name)) ) + (index-name "equivalence") + "NO_EQUIVALENT" + ) ) =], + /* min, max, act ct */ [= + (if (exist? "min") (get "min") + (if (exist? "must-set") "1" "0" )) =], [= + (if (=* (get "arg-type") "set") "NOLIMIT" + (if (exist? "max") (get "max") "1") ) =], 0, + /* opt state flags */ [=(. UP-name)=]_FLAGS, 0, + /* last opt argumnt */ [= + (set! tmp-val (if (exist? "arg-default") + (string-append "{ " UP-name "_DFT_ARG },") + (string-append "{ NULL }, /* --" flg-name " */" ) )) + (set! default-text (string-append default-text "\n " tmp-val)) + tmp-val =] + /* arg list/cookie */ [= + (set! tmp-val (if (and (=* (get "arg-type") "set") (exist? "arg-default")) + (string-append cap-name "CookieBits") "NULL")) + (set! default-cookie (string-append default-cookie tmp-val "\n" )) + tmp-val =], + /* must/cannot opts */ [= + (if (exist? "flags-must") + (string-append "a" cap-name "MustList, ") + "NULL, " ) =][= + (if (exist? "flags-cant") + (string-append "a" cap-name "CantList") + "NULL" ) =], + /* option proc */ [= + + ;; If there is a difference between what gets invoked under test and + ;; what gets invoked "normally", then there must be a #define name + ;; for the procedure. There will only be such a difference if + ;; guarded-test-main is #t + ;; + (if (= (hash-ref cb-proc-name flg-name) + (hash-ref test-proc-name flg-name)) + + (hash-ref test-proc-name flg-name) + (string-append UP-name "_OPT_PROC") ) =], + /* desc, NAME, name */ [= + (sprintf "%1$s_DESC, %1$s_NAME, %1$s_name," UP-name) =] + /* disablement strs */ [=(hash-ref disable-name flg-name)=], [= + (hash-ref disable-prefix flg-name)=] },[= + ENDIF =][= + +ENDDEF opt-desc + +## Local Variables: +## mode: text +## indent-tabs-mode: nil +## End: + +optlib.tlib ends here \=] diff --git a/autoopts/tpl/optmain.tlib b/autoopts/tpl/optmain.tlib new file mode 100644 index 0000000..729fca5 --- /dev/null +++ b/autoopts/tpl/optmain.tlib @@ -0,0 +1,1441 @@ +[= AutoGen5 Template -*- Mode: C -*- + +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +=][= + +(out-push-new) =] +ck_flag_code() { + addon_txt='' + txt1=`[=(. grep-prog)=] -w pOptDesc ${tmp_dir}/flag-code` + test -z "$txt1" && addon_txt=' (void)pOptDesc;\n' + txt2=`[=(. grep-prog)=] -w pOptions ${tmp_dir}/flag-code` + test -z "$txt2" && addon_txt=${addon_txt}' (void)pOptions;\n' + cat ${tmp_dir}/flag-code + test -z "$addon_txt" || printf "\n$addon_txt" + rm -f ${tmp_dir}/flag-code +}[= +(shell (out-pop #t)) =][= + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + + BUILD TEST MAIN + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE build-test-main =][= + + IF (emit (tpl-file-line extract-fmt)) + (define end-test-main-guard "") + guarded-test-main +=] +#if defined([=(set! end-test-main-guard (string-append + "\n#endif /* " main-guard " END-TEST-MAIN-PROCEDURE */")) + main-guard=]) /* TEST-MAIN-PROCEDURE: */[= + + ENDIF guarded-test-main =][= + + IF (= (get "test-main") "optionParseShell") + +=] + +extern tOptions genshelloptOptions; +extern void optionParseShell(tOptions*); +extern tOptions* optionParseShellOptions;[= + + ELIF (not (exist? "main-text")) =][= + + (define option-emitter-proc (get "test-main")) + (if (<= (string-length option-emitter-proc) 3) + (set! option-emitter-proc "optionPutShell")) +=] + +extern void [= (. option-emitter-proc) =](tOptions*);[= + + ENDIF + +=] + +/** + * Generated main procedure. This will emit text that a Bourne shell can + * process to handle its command line arguments. + * + * @param[in] argc argument count + * @param[in] argv argument vector + * @returns program exit code + */ +int +main(int argc, char ** argv) +{ + int res = [=(. succ-exit-code)=];[= + + IF (= (get "test-main") "optionParseShell") =] + /* + * Stash a pointer to the options we are generating. + * `genshellUsage()' will use it. + */ + optionParseShellOptions = &[=(. pname)=]Options; + (void)optionProcess(&genshelloptOptions, argc, argv); + optionParseShell(&[=(. pname)=]Options);[= + + ELSE =][= + INVOKE emit-option-code =][= + INVOKE emit-main-text =][= + ENDIF =] + return res; +}[=(. end-test-main-guard) =][= + +ENDDEF build-test-main + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + + BUILD FOR-EACH MAIN + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE for-each-main =][= + + (if (not (==* (get "argument") "[" )) + (error "command line arguments must be optional for a 'for-each' main")) + + (if (not (exist? "handler-proc")) + (error "'for-each' mains require a handler proc") ) + + (define handler-arg-type "") + (tpl-file-line extract-fmt) =][= + +INVOKE emit-handler-proc =][= + +IF (exist? "handler-type") =][= + INVOKE emit-file-dispatcher =][= +ENDIF handler-type exists =][= + +(tpl-file-line extract-fmt) + +=][= + +IF (not (exist? "stdin-input")) =][= + INVOKE emit-trim-input =][= +ENDIF + +=] +/** + * Generated main procedure. This will call the [=(. handler-proc)=] procedure + * for every operand on the command line. If there are no operands, then stdin + * is read for a list of file names to process. stdin must not be a terminal. + * It must be a pipe or a file. + * + * @param[in] argc argument count + * @param[in] argv argument vector + * @returns program exit code + */ +int +main(int argc, char ** argv) +{ + int res = 0; + int proc_ct = 0; + int arg_ix = optionProcess(&[=(. pname)=]Options, argc, argv);[= + + (if (exist? "main-init") (string-append + "\n " (def-file-line "main-init" extract-fmt) "\n" (get "main-init"))) + + =][= (tpl-file-line extract-fmt) =] + /* + * IF the input list is from the command line... + */ + if (arg_ix < argc) { + for (; arg_ix < argc; arg_ix++) { + char * arg = argv[arg_ix];[= + IF (exist? "interleaved") =] + if (*arg == '-') { + RESTART_OPT(arg_ix); + arg_ix = optionProcess(&[=(. pname)=]Options, argc, argv) - 1; + continue; + }[= + ENDIF interleaved =] + res |= [= (. handler-proc) =](arg); + proc_ct++; + }[= + IF (exist? "interleaved") =] + + if (proc_ct == 0) + fputs(_("[=(. prog-name) + =] Warning: no command operands were processed\n"), stderr);[= + ENDIF interleaved =] + }[= + +IF (exist? "stdin-input") =][= + INVOKE stdin-as-input =][= +ELSE =][= + INVOKE files-from-stdin =][= +ENDIF =][= + + (if (exist? "main-fini") (string-append + "\n " (def-file-line "main-fini" extract-fmt) "\n" (get "main-fini"))) + + =] + return res; +}[= + +ENDDEF for-each-main + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE emit-file-dispatcher =][= + +(tpl-file-line extract-fmt) =] +/** + * validate file name and dispach callout procedure. + * This procedure is generated by AutoOpts. + * It will make sure that the input file name refers to a file[= + + CASE handler-type =][= +=* name =] + * that exists.[= +=* file =] + * that exists and has been opened for [= + CASE + (define open-mode (shellf "echo '%s' | sed 's/.*-//'" + (get "handler-type"))) + open-mode =][= + *~~* '[rwa]\+' =]reading and writing[= + *~~* [wa] =]writing[= + *~~* r =]reading[= + ESAC =].[= + +*=* text =] + * that has been read into memory as text.[= + ESAC =] + * + * @param fname the name of the file to process + * @returns program exit code flag + */ +static [= + +(define emit-failing-printf (not (= (get "file-fail-code") "success"))) + + pname-down =]_exit_code_t +validate_fname(char const * fname) +{ + static char const * err_str = NULL;[= + + IF (*=* (get "handler-type") "text") =] + char* file_text; + size_t text_size; + int res;[= + ENDIF =] + + if (err_str == NULL) + err_str = _("fs error %d (%s) %s-ing %s\n");[= + + IF (== (get "handler-type") "file-r") =] + if ((fname[0] == '-') && (fname[1] == '\0')) + return [= handler-proc =](_("standard input"), stdin);[= + ENDIF file-r handler type =] + { + struct stat sb; + if (stat(fname, &sb) < 0) {[= + IF (. emit-failing-printf) =] + fprintf(stderr, err_str, errno, strerror(errno), "stat", + fname);[= + ENDIF =] + return [= (. file-fail-exit-code) =]; + }[= + + IF (*=* (get "handler-type") "text") =] + + if (! S_ISREG(sb.st_mode)) {[= + IF (. emit-failing-printf) =] + fprintf(stderr, err_str, EINVAL, strerror(EINVAL), + _("not regular file:"), fname);[= + ENDIF =] + return [= (. file-fail-exit-code) =]; + }[= + + IF (=* (get "handler-type") "some-text") =] + + if (sb.st_size == 0) {[= + IF (. emit-failing-printf) =] + fprintf(stderr, err_str, EINVAL, strerror(EINVAL), + _("empty file:"), fname);[= + ENDIF =] + return [= (. file-fail-exit-code) =]; + }[= + + ENDIF =] + + text_size = sb.st_size;[= + + ENDIF =] + }[= + +CASE handler-type =][= +=* name =][= (tpl-file-line extract-fmt) =] + + return [= handler-proc =](fname);[= + +=* file =][= (tpl-file-line extract-fmt) =] + { + int res; + FILE* fp = fopen(fname, "[= + (shellf "echo '%s' | sed 's/.*-//'" + (get "handler-type")) =]"); + if (fp == NULL) { + fprintf(stderr, err_str, errno, strerror(errno), "fopen", + fname); + return [= (. file-fail-exit-code) =]; + } + res = [= handler-proc =](fname, fp); + fclose(fp); + return res; + }[= + +*=* text =][= (tpl-file-line extract-fmt) =] + file_text = malloc(text_size + 1); + if (file_text == NULL) { + fprintf(stderr, _("cannot allocate %u bytes for %s file text\n"), + (unsigned int)text_size+1, fname); + exit([=(. nomem-exit-code)=]); + } + + { + char* pz = file_text; + size_t sz = text_size; + int fd = open(fname, O_RDONLY); + int try_ct = 0; + + if (fd < 0) { + fprintf(stderr, err_str, errno, strerror(errno), "open", fname); + free(file_text); + return [= (. file-fail-exit-code) =]; + } + + while (sz > 0) { + ssize_t rd_ct = read(fd, pz, sz); + /* + * a read count of zero is theoretically okay, but we've already + * checked the file size, so we shoud be reading more. + * For us, a count of zero is an error. + */ + if (rd_ct <= 0) { + /* + * Try retriable errors up to 10 times. Then bomb out. + */ + if ( ((errno == EAGAIN) || (errno == EINTR)) + && (++try_ct < 10) ) + continue; + + fprintf(stderr, err_str, errno, strerror(errno), "read", fname); + exit([=(. file-fail-exit-code)=]); + } + pz += rd_ct; + sz -= rd_ct; + } + close(fd); + } + + /* + * Just in case it is a text file, we have an extra byte to NUL + * terminate the thing. + */ + file_text[ text_size ] = '\0'; + res = [= handler-proc =](fname, file_text, text_size);[= + IF (not (exist? "handler-frees")) =] + free(file_text);[= + ENDIF =] + return res;[= +ESAC =] +}[= +ENDDEF emit-file-dispatcher + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE stdin-as-input =][= + IF (=* (get "handler-type") "file-") =] + else + /* + * process standard input as input file + */ + res = [= handler-proc =](_("standard input"), stdin);[= + ELSE =][= + (error "'stdin-input' specified for non-file handler type") =][= + ENDIF =][= +ENDDEF stdin-as-input + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE emit-handler-proc =][= + +CASE handler-type =][= +=* name =][= (set! handler-arg-type "char const * fname") + (define handler-proc "validate_fname") =][= +=* file =][= + (set! handler-arg-type "char const * fname, FILE * entry_fp") + (define handler-proc "validate_fname") =][= +*=* text =][= + (set! handler-arg-type + "char const * fname, char * file_text, size_t text_size") + (define handler-proc "validate_fname") =][= +!E =][= (set! handler-arg-type "char const* pz_entry") + (define handler-proc (get "handler-proc")) =][= +* =][= (error) =][= +ESAC =] + +[= + +IF (set! tmp-text (string-append (get "handler-proc") "-code")) + (exist? tmp-text) + +\=] +static int +[= handler-proc =]([=(. handler-arg-type)=]) +{ + int res = 0;[= + (string-append + (def-file-line tmp-text extract-fmt) + (get tmp-text) ) =] + return res; +}[= + +ELSE + +\=] +extern int [= handler-proc =]([=(. handler-arg-type)=]);[= + +ENDIF + +=][= + +ENDDEF emit-handler-proc + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE emit-trim-input =] +/** + * strip (destructively) the leading and trailing white space. + * Trailing white space is trimmed with a NUL byte. + * The returned address is that of the first character after the + * leading white space. Characters are not moved. + * + * @param[in,out] pz_s source text pointer + * @returns pointer to the same text buffer, but after skipping over the + * leading white space characters. + */ +static char * +trim_input_line(char * src_str) +{ + while ((unsigned int)isspace(*src_str)) + src_str++; + + { + char * end = src_str + strlen(src_str); + while ((end > src_str) && isspace((unsigned int)end[-1])) + end--; + *end = '\0'; + } + + switch (*src_str) { + case '\0':[= + (define comment-char (substring (get "comment-char" "#") 0 1)) + (if (> (string-length comment-char) 0) (begin + (if (or (== comment-char "\\") (== comment-char "'")) + (set! comment-char (string-append "\\" comment-char)) ) + (string-append "\n case '" comment-char "':") + ) ) =] + return NULL; + default: + return src_str; + } +} +[= +ENDDEF emit-trim-input + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE files-from-stdin =] + /* + * Input list from tty input + */ + else if (isatty(STDIN_FILENO)) { + fputs(_("[=(. prog-name)=] ERROR: input list is a tty\n"), stderr); + [= (. UP-prefix) =]USAGE([=(. file-fail-exit-code)=]); + /* NOTREACHED */ + } + + /* + * Input list from a pipe or file or some such + */ + else { + long pg_size = sysconf(_SC_PAGESIZE); + char * buf = malloc((size_t)pg_size); + if (buf == NULL) { + fputs(_("[=(. prog-name) + =] ERROR: no memory for input list\n"), stderr); + return [=(. nomem-exit-code)=]; + } + + for (;;) { + char * pz = fgets(buf, (ssize_t)pg_size, stdin); + if (pz == NULL) + break; + + pz = trim_input_line(pz); + if (pz == NULL) + continue;[= + IF (= (get "handler-type") "file-r") =] + if ((pz[0] == '-') && (pz[1] == '\0')) + continue; /* disallowed when reading operands from stdin */[= + ENDIF file-r handler type =][= + IF (exist? "interleaved") =] + if (*pz == '-') { + optionLoadLine(&[=(. pname)=]Options, pz); + continue; + }[= + ENDIF interleaved =] + res |= [= (. handler-proc) =](pz); + proc_ct++; + } + + if (proc_ct == 0) + fputs(_("[=(. prog-name) + =] Warning: no input lines were read\n"), stderr); + free(buf); + } +[= + +ENDDEF files-from-stdin + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + + BUILD MAIN + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE build-main =][= FOR main[] =][= + + CASE main-type =][= + == shell-process =][= + INVOKE build-test-main test-main = "optionPutShell" =][= + + == shell-parser =][= + INVOKE build-test-main test-main = "optionParseShell" =][= + + == main =][= + INVOKE build-test-main =][= + + == include =] +[= INCLUDE tpl =][= + + == invoke =][= + INVOKE (get "func") =][= + + == for-each =][= + INVOKE for-each-main =][= + + * =][= + (error (sprintf "unknown/invalid main-type: '%s'" (get "main-type"))) =][= + + ESAC =][= ENDFOR first-main =][= + +ENDDEF build-main + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + + DECLARE OPTION CALLBACK PROCEDURES + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE decl-callbacks + + This is the test for whether or not to emit callback handling code: + +=] +/** + * Declare option callback procedures + */[= + (define undef-proc-names "") + (define decl-type "") + (define extern-proc-list (string-append + (if (exist? "version-proc") + (get "version-proc") + "optionPrintVersion") "\n" + "optionBooleanVal\n" + "optionNestedVal\n" + "optionNumericVal\n" + "optionResetOpt\n" + "optionStackArg\n" + "optionTimeDate\n" + "optionTimeVal\n" + "optionUnstackArg\n" + "optionVendorOption\n" + + ) ) + + (define extern-test-list "") + + (define emit-decl-list (lambda(txt-var is-extern) + (if (> (string-length txt-var) 1) (begin + + (emit (if is-extern "\nextern tOptProc\n" "\nstatic tOptProc\n")) + (set! txt-var (shellf " + (%s -v '^%s$' | sed '/^$/d' | sort -u | \ + sed 's@$@,@;$s@,$@;@' ) <<_EOProcs_\n%s_EOProcs_" + egrep-prog + (if is-extern "NULL" "(NULL|optionStackArg|optionUnstackArg)") + txt-var )) + + (emit (shellf (if (< (string-length txt-var) 72) + "f='%s' ; echo \" \" $f" + "${CLexe} --spread=1 -I4 <<_EOProcs_\n%s\n_EOProcs_" ) + txt-var )) + )) + )) + + (define static-proc-list "doUsageOpt\n") + (define static-test-list static-proc-list) + (define ifdef-fmt (string-append + "\n#if%1$sdef %2$s" + "\n %3$s tOptProc %4$s;" + "\n#else /* not %2$s */" + "\n# define %4$s NULL" + "\n#endif /* def/not %2$s */")) + + (define make-proc-decl #t) + + (define set-ifdef (lambda(n-or-def ifdef-cb ifdef-name) (begin + (set! decl-type (if (hash-ref is-ext-cb-proc flg-name) "extern" "static")) + (set! make-proc-decl #f) + (ag-fprintf 0 ifdef-fmt n-or-def ifdef-name decl-type ifdef-cb ) + ))) + + (define set-cb-decl (lambda() (begin + + (set! make-proc-decl #t) + (set! tmp-val (hash-ref cb-proc-name flg-name)) + + (if (exist? "ifdef") + (set-ifdef "" tmp-val (get "ifdef")) + + (if (exist? "ifndef") + (set-ifdef "n" tmp-val (get "ifndef")) + + (if (hash-ref is-ext-cb-proc flg-name) + (set! extern-proc-list (string-append + extern-proc-list tmp-val "\n" )) + + (set! static-proc-list (string-append + static-proc-list tmp-val "\n" )) + ) ) ) + + (if guarded-test-main (begin + (set! tmp-val (hash-ref test-proc-name flg-name)) + (if (hash-ref is-ext-cb-proc flg-name) + (set! extern-test-list (string-append extern-test-list + tmp-val "\n" )) + + (if make-proc-decl + (set! static-test-list + (string-append static-test-list tmp-val "\n") ) ) ) + ) ) + + ))) + =][= + + FOR flag =][= + + ;; Fill in four strings with names of callout procedures: + ;; extern-test-list - external callouts done IFF test main is built + ;; static-test-list - static callouts done IFF test main is built + ;; extern-proc-list - external callouts for normal compilation + ;; static-proc-list - static callouts for normal compilation + ;; + ;; Anything under the control of "if[n]def" has the declaration or + ;; #define to NULL emitted immediately. + ;; + (set! flg-name (get "name")) + + (if (and (hash-ref have-cb-procs flg-name) + (not (hash-ref is-lib-cb-proc flg-name)) ) + (set-cb-decl) + ) =][= + + ENDFOR flag =][= + + IF (. guarded-test-main) =][= + INVOKE emit-testing-defines =][= + ENDIF guarded-test-main =][= + + (if (not (exist? "no-libopts")) + (set! extern-proc-list (string-append extern-proc-list + "optionPagedUsage\n")) ) + + (emit-decl-list extern-proc-list #t) + (emit-decl-list static-proc-list #f) + (set! static-proc-list "") =][= + + FOR flag =][= + + (set! flg-name (get "name")) + (if (not (= (hash-ref cb-proc-name flg-name) + (hash-ref test-proc-name flg-name))) + (set! static-proc-list (string-append static-proc-list + "#define " (get-up-name "name") "_OPT_PROC " + (hash-ref cb-proc-name flg-name) "\n")) ) + =][= + ENDFOR flag =][= + + IF (> (string-length static-proc-list) 0) =] + +/** + * #define map the "normal" callout procs + */ +[= (. static-proc-list) =][= + + ENDIF have some #define mappings + +=][= + + (if guarded-test-main + (emit "\n#endif /* " main-guard " */") ) + + undef-proc-names =][= + +ENDDEF decl-callbacks + +// # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE emit-testing-defines + +=][= + (set! extern-proc-list (string-append extern-proc-list + "optionVersionStderr\n")) + (tpl-file-line extract-fmt) =] +#if defined([=(. main-guard)=]) +/* + * Under test, omit argument processing, or call optionStackArg, + * if multiple copies are allowed. + */[= + + (emit-decl-list extern-test-list #t) + (emit-decl-list static-test-list #f) + (set! static-test-list "") =][= + + FOR flag =][= + + (set! flg-name (get "name")) + (if (not (= (hash-ref cb-proc-name flg-name) + (hash-ref test-proc-name flg-name))) + (set! static-test-list (string-append static-test-list + "#define " (get-up-name "name") "_OPT_PROC " + (hash-ref test-proc-name flg-name) "\n")) ) + =][= + ENDFOR flag =][= + + IF (> (string-length static-test-list) 0) =] + +/* + * #define map the "normal" callout procs to the test ones... + */ +[= (. static-test-list) =][= + + ENDIF have some #define mappings + +=] + +#else /* NOT defined [=(. main-guard)=] */ +/* + * When not under test, there are different procs to use + */[= + +ENDDEF emit-testing-defines + +// # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + + DEFINE OPTION CALLBACKS + +// # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE callback-proc-header =] + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Code to handle the [=name=] option[= # */ =][= + + IF (exist? "ifdef") + +=], when [= ifdef =] is #define-d[= + (define ifdef-text (string-append "\n#ifdef " (get "ifdef"))) + (set! endif-test-main (string-append + (sprintf "\n#endif /* defined %s */" (get "ifdef")) + endif-test-main + )) =][= + + ELIF (exist? "ifndef") + +=], when [= ifndef =] is *not* #define-d[= + (define ifdef-text (string-append "\n#ifndef " (get "ifndef"))) + (set! endif-test-main (string-append + (sprintf "\n#endif /* ! defined %s */" (get "ifndef")) + endif-test-main + )) =][= + + ELSE unconditional code: + +=][= (define ifdef-text "") =][= + + ENDIF ifdef / ifndef + +=]. +[= (prefix " * " (get "doc")) =] + * @param[in] pOptions the [=(. prog-name)=] options data structure + * @param[in,out] pOptDesc the option descriptor for this option. + */[= (. ifdef-text) =] +static void +doOpt[= (set! endif-test-main (string-append "\n}" endif-test-main)) + cap-name =](tOptions* pOptions, tOptDesc* pOptDesc) +{ +[= + +ENDDEF callback-proc-header + +// # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE reset-clause =][= + + (if (exist? "flag-code[0]") + (emit (string-append "\n" (get "flag-code[0]")))) + + (if (exist? "resettable") (emit (string-append + "\n if ((pOptDesc->fOptState & OPTST_RESET) != 0)" + "\n return;" )) ) + + =][= + +ENDDEF reset-clause + +// # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE range-option-code + +=][= + +(define option-arg-type (get "arg-type")) +(define range-count (count "arg-range")) + +\=] + static struct {long rmin, rmax;} const rng[[= + (. range-count) =]] = { +[=(out-push-new) =][= + FOR arg-range ",\n" =]{ [= + + CASE arg-range =][= + *== "->" =][= + (string-substitute (get "arg-range") "->" "") =], LONG_MAX[= + + ==* "->" =]LONG_MIN, [= + (string-substitute (get "arg-range") "->" "") =][= + + *==* "->" =][= + (string-substitute (get "arg-range") "->" ", ") =][= + + ~~ -{0,1}[0-9]+ =][=arg-range=], LONG_MIN[= + + * =][= (error (string-append "Invalid range spec: ``" + (get "arg-range") "''" )) =][= + + ESAC arg-range =] }[= + ENDFOR =][= + + (shellf "${CLexe} -I8 --spread=2 <<_EOF_\n%s\n_EOF_" + (out-pop #t)) =] }; + int ix; + + if (pOptions <= OPTPROC_EMIT_LIMIT) + goto emit_ranges;[= + + INVOKE reset-clause =][= + + CASE (define leave-ok-code "") (define ok-return-code "") + (if (exist? "flag-code[1]") + (begin + (set! leave-ok-code "goto return_okay") + (set! ok-return-code (string-append + "\n return;\n\nreturn_okay:\n" + (get "flag-code[1]") )) + ) + (begin + (set! leave-ok-code "return") + (set! ok-return-code "") + ) ) + + option-arg-type =][= + + =* num =] + optionNumericVal(pOptions, pOptDesc);[= + + = time-date =][= + (error (string-append "time/date option " low-name + " may not be range limited.")) ) + =][= + + =* time =] + optionTimeVal(pOptions, pOptDesc); + if (pOptDesc->optArg.argInt == (long)BAD_TIME) + return;[= + + * =][= + (error (string-append option-arg-type " option " low-name + " may not be range limited.")) ) + =][= + + ESAC =] + + for (ix = 0; ix < [=(. range-count)=]; ix++) { + if (pOptDesc->optArg.argInt < rng[ix].rmin) + continue; /* ranges need not be ordered. */ + if (pOptDesc->optArg.argInt == rng[ix].rmin) + [= (. leave-ok-code) =]; + if (rng[ix].rmax == LONG_MIN) + continue; + if (pOptDesc->optArg.argInt <= rng[ix].rmax) + [= (. leave-ok-code) =]; + } + + option_usage_fp = stderr; + + emit_ranges: +optionShowRange(pOptions, pOptDesc, VOIDP(rng), [= (. range-count) =]);[= + +(. ok-return-code) =][= + +ENDDEF range-option-code + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE alias-option-code \=] + int res = optionAlias(pOptions, pOptDesc, [= + (string-append INDEX-pfx (get-up-name "aliases")) =]); + if ((res != 0) && ((pOptions->fOptSet & OPTPROC_ERRSTOP) != 0)) + [= (. UP-prefix) =]USAGE([=(. usage-err-name)=]); +[= + +ENDDEF alias-option-code + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE keyword-code =][= + (emit (tpl-file-line extract-fmt)) + + (set! tmp-ct (count "keyword")) + (if (not (exist? "arg-default")) + (begin + (set! tmp-ct (+ 1 tmp-ct)) + (emit " static char const zDef[2] = { 0x7F, 0 };\n") + ) ) \=] + static char const * const names[[= (. tmp-ct) =]] = {[= + (emit (if (not (exist? "arg-default")) " zDef,\n" "\n")) + (out-push-new) =][= + FOR keyword =][= + (string-table-add-ref opt-strs (get "keyword")) =] +[= ENDFOR =][= + (shell (string-append + "${CLexe} -S, -I8 --spread=1 <<-\\_EOF_\n" (out-pop #t) "_EOF_\nset +x" )) +=] }; + + if (pOptions <= OPTPROC_EMIT_LIMIT) { + (void) optionEnumerationVal(pOptions, pOptDesc, names, [= + (. tmp-ct)=]); + return; /* protect AutoOpts client code from internal callbacks */ + }[= + + INVOKE reset-clause =][= + + IF (exist? "arg-optional") + +=] + + if (pOptDesc->optArg.argString == NULL) + pOptDesc->optArg.argEnum = [= + (string-append UP-name "_" (if (> (len "arg-optional") 0) + (get-up-name "arg-optional") (if (exist? "arg-default") + (get-up-name "arg-default") + "UNDEFINED" ))) =]; + else + pOptDesc->optArg.argEnum = + optionEnumerationVal(pOptions, pOptDesc, names, [=(. tmp-ct)=]);[= + + ELSE + +=] + + pOptDesc->optArg.argEnum = + optionEnumerationVal(pOptions, pOptDesc, names, [=(. tmp-ct)=]);[= + + ENDIF =][= + + (if (exist? "flag-code[1]") + (emit (string-append "\n" (get "flag-code[1]")))) + + =][= + +ENDDEF keyword-code + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE set-membership-code + +=][= + +(if (not (exist? "keyword")) + (error "set membership requires keywords")) +(set! tmp-ct (count "keyword")) +(emit (tpl-file-line extract-fmt)) +(ag-fprintf 0 " static char const * const names[%d] = {\n" tmp-ct) + +(shell (string-append + + "${CLexe} -I8 --spread=2 --sep=',' -f'\"%s\"' <<_EOF_\n" + (join "\n" (stack "keyword")) + "\n_EOF_\n" )) =] + };[= + + INVOKE reset-clause =] + /* + * This function handles special invalid values for "pOptions" + */ + optionSetMembers(pOptions, pOptDesc, names, [= (. tmp-ct) =]);[= + + (if (exist? "flag-code[1]") + (emit (string-append "\n" (get "flag-code[1]")))) + + =][= + +ENDDEF set-membership-code + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE file-name-code + +\=] + static teOptFileType const type = + [= (set! tmp-val (get "open-file")) =][= + CASE file-exists =][= + == "" =]FTYPE_MODE_MAY_EXIST[= + =* "no" =]FTYPE_MODE_MUST_NOT_EXIST[= + * =]FTYPE_MODE_MUST_EXIST[= + ESAC =] + [= CASE open-file =][= + + == "" =]FTYPE_MODE_NO_OPEN[= + =* "desc" =]FTYPE_MODE_OPEN_FD[= + * =]FTYPE_MODE_FOPEN_FP[= + + ESAC =]; + static tuFileMode mode; +[= IF (or (=* tmp-val "desc") (== tmp-val "")) \=] +[= IF (not (exist? "file-mode")) \=] +#ifndef O_CLOEXEC +# define O_CLOEXEC 0 +#endif +[= (define file-mode "O_CLOEXEC") =][= + ELSE =][= + (define file-mode (get "file-mode")) \=] +[= ENDIF \=] + mode.file_flags = [= (. file-mode) =]; +[= ELSE \=] +#ifndef FOPEN_BINARY_FLAG +# define FOPEN_BINARY_FLAG +#endif + mode.file_mode = [= (c-string (get "file-mode")) =] FOPEN_BINARY_FLAG; +[= ENDIF =][= + + INVOKE reset-clause =] + /* + * This function handles special invalid values for "pOptions" + */ + optionFileCheck(pOptions, pOptDesc, type, mode);[= + + (if (exist? "flag-code[1]") + (emit (string-append "\n" (get "flag-code[1]")))) + + =][= + +ENDDEF file-name-code + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE requested-code =][= + +IF (not (or (exist? "extract-code") (exist? "flag-code"))) + =][= RETURN =][= +ENDIF =][= + +(if guarded-test-main + (begin + (set! endif-test-main + (sprintf "\n#endif /* defined(%s) */" main-guard)) + (emit "\n\n#if ! defined(" main-guard ")") +) ) =][= + +INVOKE callback-proc-header =][= + +IF (out-push-new (string-append tmp-dir "/flag-code")) + (exist? "flag-code") =][= + + IF (exist? "flag-code[0]") \=] + /* + * Be sure the flag-code[0] handles special values for the options pointer + * viz. (poptions <= OPTPROC_EMIT_LIMIT) *and also* the special flag bit + * ((poptdesc->fOptState & OPTST_RESET) != 0) telling the option to + * reset its state. + */[= + (def-file-line "flag-code[0]" "\n /* extracted from %s, line %d */\n") + =][= flag-code[0] =][= + ENDIF =][= + + CASE arg-type =][= + =* bool =] + optionBooleanVal(pOptions, pOptDesc);[= + =* num =] + optionNumericVal(pOptions, pOptDesc);[= + = time-date =] + optionTimeDate(pOptions, pOptDesc);[= + =* time =] + optionTimeVal(pOptions, pOptDesc);[= + ~* hier|nest =] + optionNestedVal(pOptions, pOptDesc);[= + ESAC =][= + + IF (exist? "flag-code[1]") =] +[= flag-code[1] =][= + ENDIF =][= + +ELSE =][= + + (extract (string-append (base-name) ".c.save") (string-append + "/* %s =-= " cap-name " Opt Code =-= %s */")) + =][= +ENDIF =][= +(out-pop) +(shell "ck_flag_code") =][= + +ENDDEF requested-code + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE define-option-callbacks =][= + + FOR flag =][= + (define flag-index (for-index)) + (set-flag-names) + (define endif-test-main "") =][= + +# # # # # # # # # # # # # # # # # # =][= + + IF (exist? "arg-range") =][= + + INVOKE callback-proc-header =][= + INVOKE range-option-code =][= + +# # # # # # # # # # # # # # # # # # =][= + + ELIF (exist? "aliases") =][= + + INVOKE callback-proc-header =][= + INVOKE alias-option-code =][= + +# # # # # # # # # # # # # # # # # # =][= + + ELSE =][= CASE arg-type =][= + + =* key =][= + INVOKE callback-proc-header =][= + INVOKE keyword-code =][= + +# # # # # # # # # # # # # # # # # # =][= + + =* set =][= + + INVOKE callback-proc-header =][= + INVOKE set-membership-code =][= + +# # # # # # # # # # # # # # # # # # =][= + + =* fil =][= + INVOKE callback-proc-header =][= + INVOKE file-name-code =][= + +# # # # # # # # # # # # # # # # # # =][= + + * =][= + INVOKE requested-code =][= + + ESAC =][= + ENDIF =][= + + (. endif-test-main) =][= + + ENDFOR flag =][= + +ENDDEF define-option-callbacks + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE emit-option-callbacks =] +/* + * Create the static procedure(s) declared above. + */ +/** + * The callout function that invokes the [= (. usage-proc) + =] function. + * + * @param[in] opts the AutoOpts option description structure + * @param[in] od the descriptor for the "help" (usage) option. + * @noreturn + */ +static void +doUsageOpt(tOptions * opts, tOptDesc * od) +{ + int ex_code;[= + + IF (define od-used #f) + (exist? "resettable") =] + if ((od->fOptState & OPTST_RESET) != 0) + return;[= (set! od-used #t) =][= + + ENDIF =][= + + IF (exist? "usage-opt") =] + ex_code = (od->optIndex == [= (set! od-used #t) INDEX-pfx =]HELP) + ? [=(. succ-exit-code)=] : AO_EXIT_REQ_USAGE;[= + + ELSE =] + ex_code = [=(. succ-exit-code)=];[= + ENDIF =][= + (string-append "\n " usage-proc "(&" pname "Options, ex_code);") =] + /* NOTREACHED */ + exit([=(. fail-exit-code)=]); + (void)opts;[= + (if od-used "" "\n (void)od;") =] +}[= + +INVOKE define-option-callbacks =][= + +IF (exist? "main") =][= + INVOKE build-main =][= + +ELIF (. guarded-test-main) =][= + INVOKE build-test-main =][= + +ENDIF + +=][= +(tpl-file-line extract-fmt) +=][= + +IF (exist? "usage-message") =] +/** + * Print a usage message with a format and va_list argument. + * The [= (. usage-proc) =] function is then invoked to print + * the error usage text (somewhat abbreviated) and then exit. + * + * @param[in] fmt the message format string + * @param[in] ap the var-arg list. + * @noreturn + */ +[=(. no-return-str)=]vusage_message(char const * fmt, va_list ap) +{ + char const * er_leader = _("[= prog-name =] usage error:\n"); + fputs(er_leader, stderr); + vfprintf(stderr, fmt, ap); + [= (string-append usage-proc "(&" pname "Options, " usage-err-name ")") =]; + /* NOTREACHED, but C11 compilers cannot tell. */ + abort(); +} + +/** + * Print a usage message with a format and a variable argument list. + * [=(. lc-prefix)=]vusage_message() is called to do the work. + * + * @param[in] fmt the message format string + * @param[in] ... the argument list for the message + * @noreturn + */ +[=(. no-return-str)=]usage_message(char const * fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + [=(. lc-prefix)=]vusage_message(fmt, ap); +} +[= + +ENDIF have usage-message =][= + +IF (exist? "die-code") + +=] +/** + * Print a fatal error message and die, \a va_list style. + * + * @param[in] exit_code the value to call exit(3) with + * @param[in] fmt the death rattle message + * @param[in] ap the argument list for the message + * @noreturn + */ +[=(. no-return-str)=]vdie(int exit_code, char const * fmt, va_list ap) +{ + char const * die_leader = _("[= prog-name =] fatal error:\n");[= + (set! tmp-text (get "die-code")) + (if (> (string-length tmp-text) 1) + (string-append "\n\n" tmp-text "\n")) + =] + fputs(die_leader, stderr); + vfprintf(stderr, fmt, ap); + fflush(stderr); + exit(exit_code); +} + +/** + * Print a fatal error message and die, var-arg style. + * + * @param[in] exit_code the value to call exit(3) with + * @param[in] fmt the death rattle message + * @param[in] ... the list of arguments for the message + * @noreturn + */ +[=(. no-return-str)=]die(int exit_code, char const * fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vdie(exit_code, fmt, ap); +} + +/** + * Print a file system error fatal error message and die. + * + * @param[in] exit_code the value to call exit(3) with. + * @param[in] op the operation that failed. + * @param[in] fname the file name the operation was on. + * @noreturn + */ +[=(. no-return-str)=]fserr(int exit_code, char const * op, char const * fname) +{ + char const * fserr_fmt = _("fserr %d (%s) performing '%s' on %s\n"); + die(exit_code, fserr_fmt, errno, strerror(errno), op, fname); +} +[= +ENDIF die-code =][= + +IF (exist? "warn-code") + +=] +/** + * Print a warning message, \a va_list style. + * + * @param[in] fmt the "something awry" message + * @param[in] ap the argument list for the message + */ +void +[=(. lc-prefix)=]vwarning_msg(char const * fmt, va_list ap) +{ + char const * warn_leader = _("[= prog-name =] WARNING:\n");[= + (set! tmp-text (get "warn-code")) + (if (> (string-length tmp-text) 1) + (string-append "\n\n" tmp-text "\n")) + =] + fputs(warn_leader, stderr); + vfprintf(stderr, fmt, ap); + fflush(stderr); +} + +/** + * Print a warning message, var-arg style. + * + * @param[in] fmt the "something awry" message + * @param[in] ... the list of arguments for the message + */ +void +[=(. lc-prefix)=]warning_msg(char const * fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vwarning_msg(fmt, ap); + va_end(ap); +} +[= + +ENDIF have warn-code =][= + +ENDDEF emit-option-callbacks + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE emit-option-code =][= + + IF (exist? "option-code") =][= + (def-file-line "option-code" extract-fmt) =][= + option-code =][= + + ELSE =][= + + IF (and (exist? "no-libopts") (not (exist? "autoopts-usage-tlib"))) =] + (void)process_[=(. pname)=]_opts(argc, argv);[= + ELIF (exist? "main-text") =] + { + int ct = optionProcess(&[=(. pname)=]Options, argc, argv); + argc -= ct; + argv += ct; + }[= + ELSE =] + (void)optionProcess(&[=(. pname)=]Options, argc, argv);[= + ENDIF =][= + + ENDIF =][= + +ENDDEF emit-option-code + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][= + +DEFINE emit-main-text =][= + + IF (exist? "main-text") =][= + + (def-file-line "main-text" extract-fmt) =][= + main-text =][= + + ELSE =][= + + IF (and (exist? "no-libopts") (not (exist? "autoopts-usage-tlib"))) =] + /* When using AutoOpts with getopt(3C) or getopt_long(3GNU) + the main-text attribute of main _must_ be defined. */ +#error autoopts_with_getopt_must_define_main_text_attribute[= + ELSE test-main is not optionParseShell and main-text not exist + Above, we figure out which emitter procedure is to be used. + The default is optionPutShell. +=] + [= (. option-emitter-proc) =](&[=(. pname)=]Options); + res = ferror(stdout); + if (res != 0) + fputs("output error writing to stdout\n", stderr);[= + ENDIF =][= + + ENDIF =][= + +ENDDEF emit-main-text =] diff --git a/autoopts/tpl/perlopt.tpl b/autoopts/tpl/perlopt.tpl new file mode 100644 index 0000000..a5d4599 --- /dev/null +++ b/autoopts/tpl/perlopt.tpl @@ -0,0 +1,188 @@ +[= AutoGen5 template foo=(base-name) -*- Mode: scheme -*-=] +[= + +(emit (dne "# ")) + +(if (not (and (exist? "prog-name") (exist? "prog-title") (exist? "version"))) + (error "prog-name and prog-title are required")) +(define prog-name (get "prog-name")) + +(if (> (string-length prog-name) 16) + (error (sprintf "prog-name limited to 16 characters: %s" + prog-name)) ) +(if (not (exist? "long-opts")) + (error "long-opts is required")) + +;; perl list containing string to initialize the option hash +(define perl_opts "") +;; perl list containing option definitions for Getopt::Long +(define perl_defs " ") +;; usage string +(define perl_usage "") + +(define optname-from "A-Z_^") +(define optname-to "a-z--") +(define counter 0) + +(define q (lambda (s) (string-append "'" s "'"))) +(define qp (lambda (s) (string-append "q{" s "}"))) + +=][= + +FOR flag =][= + +(define optarg "") ;; the option argument for Getopt::Long +(define opttarget "''") ;; the value of a hash key that represents option +(define optargname "") +(define optisarray #f) +(define optname (string-tr! (get "name") optname-from optname-to)) + +=][= # +;; since autoopts doesn't support float we take the combination arg-name = +;; float and arg-type = string as float +=][= + IF arg-type =][= + CASE arg-type =][= + + =* num =][= (set! optarg "=i") =][= + + =* str =][= + (if (and (exist? "arg-name") (== (get "arg-name") "float")) + (set! optarg "=f") + (set! optarg "=s") + ) =][= + + * =][= + (error (string-append "unknown arg type '" + (get "arg-type") "' for " (get "name"))) =][= + ESAC arg-type =][= + ENDIF =][= + +(if (exist? "stack-arg") + ;; set optarget to array reference if can take more than one value + ;; FIXME: if "max" exists, then just presume it is greater than 1 + ;; + (if (and (exist? "max") (== (get "max") "NOLIMIT")) + (begin + (set! opttarget (string-append + "[" + (if (exist? "arg-default") (q (get "arg-default")) "") + "]" + ) + ) + (set! optisarray #t) + ) + (error "If stack-arg then max has to be NOLIMIT") + ) + ;; just scalar otherwise + (if (exist? "arg-default") (set! opttarget (q (get "arg-default")))) +) + +(set! perl_opts (string-append perl_opts + "'" (get "name") "' => " opttarget ",\n ")) + +(define def_add (string-append "'" optname (if (exist? "value") + (string-append "|" (get "value")) "") optarg "',")) + +(define add_len (+ (string-length def_add) counter)) +(if (> add_len 80) + (begin + (set! perl_defs (string-append perl_defs "\n " def_add)) + (set! counter 8) + ) + (begin + (set! perl_defs (string-append perl_defs " " def_add)) + (set! counter (+ counter add_len)) + ) +) + +(if (exist? "arg-type") + (if (and (exist? "arg-name") (== (get "arg-name") "float")) + (set! optargname "=float") + (set! optargname (string-append "=" (substring (get "arg-type") 0 3))) + ) + (set! optargname " ") +) + +(if (not (exist? "deprecated")) + (set! perl_usage (string-append perl_usage + (sprintf "\n %-28s %s" (string-append + (if (exist? "value") (string-append "-" (get "value") ",") " ") + " --" + (get "name") + optargname) + (get "descrip")) +) ) ) +(if optisarray + (set! perl_usage (string-append perl_usage + "\n - may appear multiple times")) +) + +=][= + +ENDFOR each "flag" =] + +use Getopt::Long qw(GetOptionsFromArray); +Getopt::Long::Configure(qw(no_auto_abbrev no_ignore_case_always)); + +my $usage; + +sub usage { + my ($ret) = @_; + print STDERR $usage; + exit $ret; +} + +sub paged_usage { + my ($ret) = @_; + my $pager = $ENV{PAGER} || '(less || more)'; + + open STDOUT, "| $pager" or die "Can't fork a pager: $!"; + print $usage; + + exit $ret; +} + +sub processOptions { + my $args = shift; + + my $opts = { + [= (. perl_opts) =]'help' => '', 'more-help' => '' + }; + my $argument = '[= argument =]'; + my $ret = GetOptionsFromArray($args, $opts, ( +[= (. perl_defs) =] + 'help|?', 'more-help')); + + $usage = <<'USAGE'; +[= prog-name =] - [= prog-title =] - Ver. [= version =] +USAGE: [= prog-name =] [ - [] | --[{=| }] ]... [= argument =] +[= (. perl_usage) =] + -?, --help Display usage information and exit + --more-help Pass the extended usage text through a pager + +Options are specified by doubled hyphens and their name or by a single +hyphen and the flag character. +USAGE + + usage(0) if $opts->{'help'}; + paged_usage(0) if $opts->{'more-help'};[= + +CASE argument =][= +!E =][= +==* "[" =][= +* =] + + if ($argument && $argument =~ /^[^\[]/ && !@$args) { + print STDERR "Not enough arguments supplied (See --help/-?)\n"; + exit 1; + }[= + +ESAC + +=] + $_[0] = $opts; + return $ret; +} + +END { close STDOUT }; diff --git a/autoopts/tpl/rc-sample.tpl b/autoopts/tpl/rc-sample.tpl new file mode 100644 index 0000000..58ba840 --- /dev/null +++ b/autoopts/tpl/rc-sample.tpl @@ -0,0 +1,125 @@ +[= AutoGen5 Template rc + +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +=] +# [= (define prog-name (get "prog-name")) + prog-name =] sample configuration file +#[= + +IF (if (not (exist? "homerc")) + (error "RC file samples only work for rc-optioned programs") ) + + (out-move (string-append "sample-" + (if (exist? "rcfile") (get "rcfile") + (string-append (get "prog-name") "rc") ) + ) ) + + (set-writable) + + (exist? "copyright") +\=] +# This source file is copyrighted and licensed under the following terms: +# +[= + CASE copyright.type =][= + == "" =][= + (sprintf "# %s Copyright (C) %s %s - all rights reserved\n# %s" + prog-name (get "copyright.date") (get "copyright.owner") + "licensing type not specified" ) =][= + + = note =][= (prefix "# " (get "copyright.text")) =][= + + * =][= (license-full (get "copyright.type") prog-name "# " + (get "copyright.owner") (get "copyright.date")) =][= + ESAC =][= + +ENDIF "copyright exists" =][= + +FOR flag =][= + + IF (not (or (exist? "documentation") (exist? "no-preset"))) =] + +# [= name =] -- [= descrip =] +# +[= INVOKE emit-description =] +# Example: +# +#[= name =][= + IF (exist? "arg-type") + =] [= (if (exist? "arg-default") (get "arg-default") + (if (exist? "arg-name") (get "arg-name") + (get "arg-type") )) =][= + ENDIF (exist? "arg-type") =][= + + ENDIF (not (exist? "documentation")) =][= + +ENDFOR flag + += = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][= + +DEFINE emit-description =][= +(out-push-new) =][= + + IF (~* (get "arg-type") "key|set") +=]This configuration value takes a keyword as its argument[= + + IF (=* (get "arg-type") "set") + +=] list. Each entry turns on or off membership bits. The bits are set by [=# +=]name or numeric value and cleared by preceding the name or number with an [=# +=]exclamation character ('!'). [= + + ELSE + +=]. [= + + ENDIF + +=]The available keywords are: [= + (join ", " (stack "keyword")) =]. [= + + ELIF (=* (get "arg-type") "num") + =]This configuration value takes an integer number as its argument. [= + IF (exist? "scaled") =]That number may be scaled with a single letter [=# +=]suffix: k/K/m/M/g/G/t/T These will multiply the value by powers of [=# +=]1000 (lower case) or 1024 (upper case). [= + ENDIF =][= + + ENDIF =][= + + (define fill-txt (out-pop #t)) + (if (defined? 'fill-txt) + (string-append + + (shell (string-append "while read line + do echo ${line} | fold -s -w76 | sed 's/^/# /' + echo '#' + done <<'__EndOfText__'\n" fill-txt "\n__EndOfText__" )) + + "\n#\n" + ) ) =][= + + (if (exist? "doc") (prefix "# " (get "doc"))) =][= + +ENDDEF emit-description + +=] diff --git a/autoopts/tpl/stdoptions.def b/autoopts/tpl/stdoptions.def new file mode 100644 index 0000000..6934fa0 --- /dev/null +++ b/autoopts/tpl/stdoptions.def @@ -0,0 +1,427 @@ + +/* -*- Mode: Text -*- + * + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +#ifndef NO_STD_OPT_DOC +# ifndef HAVE_STD_OPT_DOC +# define HAVE_STD_OPT_DOC 1 +flag = { + name = autoopts_std_options; + documentation; + descrip = <<- _EOF_ + The following options are commonly used and are + provided and supported by AutoOpts + _EOF_; +}; +# endif +#endif + +#ifdef ALL_STD_OPTS +#define BRIEF +#define DEBUG +#define DIRECTORY +#define DRY_RUN +#define INPUT +#define INTERACTIVE +#define OUTPUT +#define QUIET +#define SILENT +#define VERBOSE +#define WARN +#endif + +#ifdef ALL_FLAG_OPTS +#define BRIEF_FLAG +#define DEBUG_FLAG +#define DIRECTORY_FLAG +#define DRY_RUN_FLAG +#define INPUT_FLAG +#define INTERACTIVE_FLAG +#define OUTPUT_FLAG +#define QUIET_FLAG +#define SILENT_FLAG +#define VERBOSE_FLAG +#define WARN_FLAG +#endif + +#ifdef STD_EXITS +exit-name[64] = usage; +exit-desc[64] =<<- _EOExit_ + The command was used incorrectly, e.g., with the wrong number of + arguments, a bad flag, a bad syntax in a parameter. + _EOExit_; + +exit-name[65] = dataerr; +exit-desc[65] =<<- _EOExit_ + The input data was incorrect in some way. + _EOExit_; + +exit-name[66] = noinput; +exit-desc[66] =<<- _EOExit_ + An input file (not a system file) did not exist or was not readable. + _EOExit_; + +exit-name[67] = nouser; +exit-desc[67] =<<- _EOExit_ + The user specified did not exist. + _EOExit_; + +exit-name[68] = nohost; +exit-desc[68] =<<- _EOExit_ + The host specified did not exist. + _EOExit_; + +exit-name[69] = unavailable; +exit-desc[69] =<<- _EOExit_ + A service is unavailable. This can occur if a support program or + file does not exist. This can also be a catchall message when + something doesn't work, and the cause cannot be determined. + _EOExit_; + +exit-name[70] = software; +exit-desc[70] =<<- _EOExit_ + An internal software error has been detected. + _EOExit_; + +exit-name[71] = oserr; +exit-desc[71] =<<- _EOExit_ + An operating system error has been detected. This is used for such + things as "cannot fork", "cannot create pipe", or the similar. + _EOExit_; + +exit-name[72] = osfile; +exit-desc[72] =<<- _EOExit_ + Some system file (e.g., /etc/passwd, /etc/utmp, etc.) does not + exist, cannot be opened, or has some sort of error. + _EOExit_; + +exit-name[73] = cantcreat; +exit-desc[73] =<<- _EOExit_ + A (user specified) output file cannot be created. + _EOExit_; + +exit-name[74] = ioerr; +exit-desc[74] =<<- _EOExit_ + An error occurred while doing I/O on somefile. + _EOExit_; + +exit-name[75] = tempfail; +exit-desc[75] =<<- _EOExit_ + A temporary failure, indicating something that is not really an + error. The request should be reattempted later. + _EOExit_; + +exit-name[76] = protocol; +exit-desc[76] =<<- _EOExit_ + the remote system returned something that was "not possible" during + a protocol exchange. + _EOExit_; + +exit-name[77] = noperm; +exit-desc[77] =<<- _EOExit_ + You did not have sufficient permission to perform the operation. + This is not intended for file system problems, which should use + NOINPUT or CANTCREAT, but rather for higher level permissions. + _EOExit_; + +exit-name[78] = config; +exit-desc[78] = 'configuration error'; +#endif + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * Levels of user entertainment + * + * DEBUG output + */ +#ifdef DEBUG_FLAG +#define DEBUG +#endif + +#ifdef DEBUG +flag = { + name = DEBUG; +#ifdef DEBUG_FLAG + value = D; +#endif +#ifdef DEBUG_LEVEL + arg-type = number; +#endif + descrip = 'run program with debugging info'; + doc = + "Specifying this option will cause the program to display debugging\n" + "information. The information should be helpful to a developer in\n" + "debugging this program."; +}; +#endif + +/* * * * * * * * + * + * VERBOSE output + */ +#ifdef VERBOSE_FLAG +#define VERBOSE 1 +#endif + +#ifdef VERBOSE +flag = { + name = verbose; +#ifdef VERBOSE_FLAG + value = V; +#endif +#ifdef VERBOSE_LEVEL + arg-type = number; +#endif +#ifdef VERBOSE_ENUM + arg-type = keyword; + keyword = silent, quiet, brief, informative, verbose; + arg-default = brief; +#endif + descrip = 'run program with progress info'; + doc = + "Specifying this option will cause the program to display lots of\n" + "progress information. You will be able to see that the program\n" + "is working and it may help you debug your use of the tool."; +}; +#endif + +/* * * * * * * * + * + * WARNING output + */ +#ifdef WARN_LEVEL +#define WARN +#endif +#ifdef WARN_FLAG +#define WARN +#endif + +#ifdef WARN +flag = { + name = warn; +#ifdef WARN_FLAG + value = w; +#endif +#ifdef WARN_LEVEL + arg-type = number; + descrip = 'specify a warning-level threshhold'; + disable = no; + doc = + "Specifying this option will allow you to specify the warning level\n" + "for the messages you want to see. `--no-warn' will disable\n" + "warnings entirely."; +#else + descrip = 'disable warning output'; + doc = + "Specifying this option will cause the program to disable\n" + "warning messages."; +#endif +}; +#endif + +/* * * * * * * * + * + * BRIEF output + */ +#ifdef BRIEF_FLAG +#define BRIEF +#endif + +#ifdef BRIEF +flag = { + name = brief; +#ifdef BRIEF_FLAG + value = b; +#endif + descrip = 'run with minimal info output'; + doc = + "Specifying this option will cause the program to disable most progress\n" + "information."; +}; +#endif + +/* * * * * * * * + * + * QUIET/SILENT output + */ +#ifdef QUIET_FLAG +#define QUIET +#endif +#ifdef SILENT_FLAG +#define SILENT +#endif + +#ifdef QUIET_SILENT +#define QUIET +#define SILENT +#else + +#ifdef QUIET +#ifdef SILENT +#define QUIET_SILENT +#endif +#endif +#endif + +#ifdef QUIET +flag = { + name = quiet; +#ifdef QUIET_FLAG + value = q; +#endif +#ifdef QUIET_SILENT + equivalence = quiet; +#endif +#ifdef QUIET_LEVEL + arg-type = number; +#endif + descrip = 'run without unnecessary output'; + doc = + "Specifying this option will cause the program to disable progress\n" + "information."; +}; +#endif + +#ifdef SILENT +flag = { + name = silent; +#ifdef SILENT_FLAG + value = s; +#endif +#ifdef QUIET_SILENT + equivalence = quiet; +#endif +#ifdef SILENT_LEVEL + arg-type = number; +#endif + descrip = 'run without unnecessary output'; + doc = + "Specifying this option will cause the program to disable progress\n" + "information."; +}; +#endif + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * Operational mode + * + * DRY_RUN + */ +#ifdef DRY_RUN_FLAG +#define DRY_RUN +#endif + +#ifdef DRY_RUN +flag = { + name = DRY_RUN; +#ifdef DRY_RUN_FLAG + value = R; +#endif + descrip = 'program will make no changes'; + doc = + "Specifying this option will cause the program to run without\n" + "altering any of the normal output files. Instead, it will\n" + "display what it would otherwise have done."; +}; +#endif + +/* * * * * * * * + * + * INTERACTIVE OPERATION + */ +#ifdef INTERACTIVE_FLAG +#define INTERACTIVE +#endif + +#ifdef INTERACTIVE +flag = { + name = interactive; + arg-type = string; +#ifdef INTERACTIVE_FLAG + value = I; /* flag style option character */ +#endif + descrip = "prompt for confirmation"; + doc = + "Specifying this option will cause the program to query you for\n" + "confirmation before doing anything destructive."; +}; +#endif + +/* * * * * * * * + * + * INPUT/OUTPUT files + */ +#ifdef INPUT_FLAG +#define INPUT +#endif + +#ifdef INPUT +flag = { + name = input; + arg-type = string; +#ifdef INPUT_FLAG + value = i; /* flag style option character */ +#endif + descrip = "redirect input from file"; + doc = + "This option specifies the file to use for program input."; +}; +#endif + +#ifdef OUTPUT_FLAG +#define OUTPUT +#endif + +#ifdef OUTPUT +flag = { + name = output; + arg-type = string; +#ifdef OUTPUT_FLAG + value = o; /* flag style option character */ +#endif + descrip = "redirect output to file"; + doc = + "This option specifies the file to use for program output."; +}; +#endif + +/* * * * * * * * + * + * INPUT/OUTPUT directory + */ +#ifdef DIRECTORY_FLAG +#define DIRECTORY +#endif + +#ifdef DIRECTORY +flag = { + name = directory; + arg-type = string; +#ifdef DIRECTORY_FLAG + value = d; /* flag style option character */ +#endif + descrip = "use specified dir for I/O"; + doc = + "This option specifies the directory to use for program input and output."; +}; +#endif diff --git a/autoopts/tpl/str2enum.tpl b/autoopts/tpl/str2enum.tpl new file mode 100644 index 0000000..759b1c6 --- /dev/null +++ b/autoopts/tpl/str2enum.tpl @@ -0,0 +1,856 @@ +[= AutoGen5 Template h c -*- Mode: Scheme -*- + +# This file contains the templates used to generate +# keyword parsing code + +## This file is part of AutoGen. +## AutoGen is free software. +## AutoGen is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . +## This file has the following md5sum: +## +## 43b91e8ca915626ed3818ffb1b71248b COPYING.gplv3 + +=][= + +(emit + (dne " * " "/* ") + "\n *\n" + (if (exist? "copyright") + (license-description + (get "copyright.type" "unknown") + (get "package" (shell "basename `pwd`")) + " * " + (get "copyright.owner" (get "copyright.author" "unknown")) ) + (license-description "mbsd" "str2enum" " * " "Bruce Korb") + ) +) + +=][= + +CASE (suffix) =][= # + +;;; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +;;; +;;; H CODE +;;; +;;;=][= +== h =][= +INVOKE init-header =][= + IF (exist? "addtogroup") =] +/** \file [= (out-name) =] + * Header for string to enumeration values and back again. + * @addtogroup [= addtogroup =] + * @{ + */[= + ENDIF addtogroup =] +#include +#ifndef MISSING_INTTYPES_H +# include +#endif + +typedef enum {[= + (if (> enum-val-offset 0) + (string-append "\n " invalid-cmd " = 0,") ) =][= + (shellf "mk_enum_list %d" enum-val-offset) =] + [= (. cmd-count) =][= + (if (= (get "invalid-val") "~0") + (string-append ",\n " invalid-cmd " = ~0") ) =] +} [= (. enum-name) =]; +[= + + FOR add-on-text =][= + IF (= (get "ao-file") "enum-header") =] +[= ao-text =] +[= ENDIF =][= + ENDFOR add-on-text =][= + + IF (if (exist? "no-code") + (if (exist? "dispatch") + (error "dispatch does not work without code") + #f) + #t) +=] +extern [= +(define find-arg-list (string-append "char const * str" len-arg)) +(string-append enum-name "\n" +find-func-name "(" find-arg-list ");\n") +=][= + +IF (not (exist? "no-name")) + +=] +extern char const * +[=(. base-type-name)=]_name([= (. enum-name) =] id); +[= + +ENDIF no-name + +=][= + + IF (define disp-text "") + (exist? "dispatch") =][= + + (out-push-new) + (out-suspend "disp-text") =][= + + FOR dispatch "\n" =] +[= INVOKE mk-dispatch =][= + ENDFOR dispatch =][= + + (out-resume "disp-text") + (set! disp-text (out-pop #t)) + =][= + + ENDIF dispatch exists + +=] +[=ENDIF exist/not "no-code" =][= +(if (exist? "addtogroup") "\n/** @} */") \=] +#endif /* [=(. header-guard) =] */[= # + +;;; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +;;; +;;; C CODE +;;; +;;;=][= +== c + +=] + */ +#include "[= ;;" + (if (exist? "no-code") (out-delete)) + (if move-output-file + (out-move (string-append base-file-name ".c"))) + header-file =]"[=#"=][= + (. extra-c-incl) =][= + IF (exist? "addtogroup") =] +/** \file [= (out-name) =] + * Code for string to enumeration values and back again. + * @addtogroup [= addtogroup =] + * @{ + */ +[=ENDIF addtogroup =][= + + INVOKE run-gperf =][= + INVOKE mk-finder =][= + + IF (not (exist? "no-name")) =][= + INVOKE mk-enum2name =][= + ENDIF dispatch =][= + + (. disp-text) =][= + + FOR add-on-text =][= + IF (= (get "ao-file") "enum-code") =] +[= ao-text =][= + ENDIF correct type =][= + ENDFOR add-on-text =][= +(if (exist? "addtogroup") "\n/** @} */") \=][= + +ESAC suffix c/h + +;;; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +;; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +;;; +;;; Create the function that converts the name into an enum value. +;;; +;;;=][= + +DEFINE init-header =][= + +(define computed-length #f) +(define return-length #f) +(define tmp-str "") +(define extra-c-incl "") +(define len-arg ", size_t len") +(define len-descrip +"\n * @param[in] len the provided length of the keyword at \\a str.") +(define enum-type "cmd") =][= + +INCLUDE "str2init.tlib" =][= + + CASE length =][= + !E =][= + (if (or (exist? "no-case") (exist? "alias")) + (set! extra-c-incl "\n#include ")) =][= + + = provided =][= + (if (or (exist? "no-case") (exist? "alias")) + (set! extra-c-incl "\n#include ")) =][= + + = returned =][= + (set! extra-c-incl "\n#include \n#include ") + (set! len-arg ", size_t * len") + (define len-descrip + "\n * @param[out] len address to store the keyword length from \\a str.") + (set! computed-length #t) + (set! return-length #t) =][= + + * =][= + (set! extra-c-incl "\n#include \n#include ") + (set! computed-length #t) + (set! len-descrip "") + (set! len-arg "") =][= + ESAC =][= + +(define equate-from "") +(define equate-to "") +(out-push-new) + +=] +mk_char_list() { + echo "$1" | sed 's/\(.\)/\1\ +/g' | sort -u | tr -d '\n\t ' +} + +readonly max_cmd_width=[=(. max-cmd-width)=] +readonly max_enm_width=[=(+ max-cmd-width (string-length enum-prefix) 1)=] +readonly min_cmd_width=[=(. min-cmd-width)=] +[= IF (exist? "equate") =] +equate_from='[=(define equate-from (get "equate")) equate-from=]' +equate_to=`echo "$equate_from" | sed "s#.#[=(substring equate-from 0 1)=]#g"` +[= ENDIF =] +mk_enum_list() { + tr '[a-z]' '[A-Z]' < ${tmp_dir}/commands | sort > ${tmp_dir}/commands-UC + exec 3< ${tmp_dir}/commands-UC + declare n c + declare fmt="\n [=(. enum-prefix)=]_%-${max_cmd_width}s = %s," + while read -u3 n c + do + printf "$fmt" $c `expr $n + $1` + done + exec 3<&- +} +[= + +(shell (out-pop #t)) +(if (exist? "equate") + (set! equate-to (shell "echo \"${equate_to}\"")) ) +(define cmd-chars (join "" (stack "cmd"))) + +(if (exist? "no-case") + (set! cmd-chars (string-append + (string-downcase cmd-chars) (string-upcase cmd-chars) )) ) + +(if (exist? "equate") + (set! cmd-chars (string-append cmd-chars (get "equate"))) +) + +(set! cmd-chars (shell "mk_char_list '" cmd-chars "'" )) +(emit "\n *\n * Command/Keyword Dispatcher\n */\n") +(make-header-guard "str2enum") + +=][= + +ENDDEF init-header + +;;; = = = = = = = = = = = = = = = = = = = +;;; +;;; Create the function that converts the name into an enum value. +;;; +;;;=][= + +DEFINE mk-finder =] + +/** + * Convert a command (keyword) to a [= (. enum-name) =] enumeration value.[= + IF (. computed-length) =] + * The length of the command is computed by calling \a strspn() + * on the input argument.[= + ENDIF =][= + IF (exist? "equate") =] + * Within the keyword, the following characters are considered equivalent: + * \a [=(. cmd-chars) =][= + ENDIF =] + * + * @param[in] str a string that should start with a known key word.[= + (. len-descrip) =] + * @returns the enumeration value. + * If not found, that value is [=(. invalid-cmd)=]. + */ +[= (string-append enum-name "\n" find-func-name) +=](char const * str[=(. len-arg)=]) +{[= + IF (exist? "alias") =] + switch (*str) {[= + FOR alias =] + case '[= (define cmd (get "alias")) + (substring cmd 0 1)=]': return [= + (set! cmd (shellf "echo %s" (substring cmd 1))) + (string-append enum-prefix "_" + (string->c-name! (string-upcase! cmd))) =];[= + ENDFOR alias =] + default: + if (! isalpha((unsigned char)*str)) + return [=(. invalid-cmd)=]; + break; + } + + {[= + ENDIF alias =] + [= (. base-type-name) =]_map_t const * map;[= + + IF (define len-param-name (if computed-length "clen" "len")) + (define check-length (if return-length + "\n if (len != NULL)\n\t*len = clen;" "\n")) + computed-length =] + static char const accept[] = + [= (set! check-length (string-append + check-length + "\n if (isalnum((unsigned char)str[clen]))" + "\n return " invalid-cmd ";" )) + + (kr-string cmd-chars) + =]; + unsigned int clen = strspn(str, accept);[= + ENDIF computed-length + +=][= + IF (or (exist? "no-case") (exist? "equate")) =][= + INVOKE cvt-chars =][= + ELSE =][= (. check-length) =][= + ENDIF \=] + + map = find_[=(. base-type-name)=]_name(str, (unsigned int)[= + (. len-param-name) =]);[= + + IF (not (exist? "partial")) =] + return (map == NULL) ? [=(. invalid-cmd)=] : map->[=(. enum-field)=];[= + ELSE =][= + INVOKE find-part-match =][= + ENDIF =][= + (if (exist? "alias") "\n }") =] +} +[= + +ENDDEF mk-finder + +;;; = = = = = = = = = = = = = = = = = = = +;;; +;;; Convert one character to canonical form. If there are equated characters +;;; or case mappings to do, do it here. +;;; +;;;=][= + +DEFINE cvt-chars =][= + +(define min-len (if (and (exist? "partial") (> min-cmd-width 2)) + 2 min-cmd-width)) + +=] + char name_buf[[=(+ 1 max-cmd-width)=]]; + unsigned int ix; + + /* too short, too long or followed immediately by a name char... */ + if ( ([=(sprintf "%s < %u" len-param-name min-len)=]) + || ([=(sprintf "%s > %u" len-param-name max-cmd-width)=]) + || isalnum((unsigned char)str[[=(. len-param-name)=]]) ) + return [=(. invalid-cmd)=]; + + for (ix = 0; ix < [=(. len-param-name)=]; ix++) { + int ch = (unsigned char)str[ix];[= + IF (exist? "equate") =] + switch (ch) { + [= (shell "echo '" (get "equate") "' | " + "sed \"s/\\(.\\)/case '\\1': /g\"") =] + name_buf[ix] = '[= (substring (get "equate") 0 1) =]'; + break; + default:[= + + IF (exist? "no-case") =] + name_buf[ix] = tolower(ch);[= + ELSE =] + name_buf[ix] = ch;[= + ENDIF =] + break; + }[= + + ELSE =] + name_buf[ix] = tolower(ch);[= + ENDIF no-case/equate =] + } + str = name_buf;[= + (if return-length (string-append + "\n if (len != NULL)\n\t*len = clen;")) + =][= + +ENDDEF cvt-chars + +;;; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +;; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +;;; +;;;=][= + +DEFINE mk-dispatch =][= + +(if (not (exist? "d-nam")) + (error "dispatch needs callout procedure name format ('d-nam')")) + +(define disp-type-name (shell + "echo " (get "d-nam") " | sed 's/%s//;s/__*/_/g;s/^_//;s/_$//'" )) +(define handler-type (string-append disp-type-name "_hdl_t")) + +(define disp-proc-name + (string-append disp-type-name "_" base-type-name "_disp" )) + +(define hdlr-arg-list (string-append enum-name " id, char const * str")) +(define disp-arg-list find-arg-list) +(define extra-args "") + +(if (exist? "d-arg") (begin + (set! extra-args (shell "echo '" (get "d-arg") "' | tr '\\n' ' '")) + (set! disp-arg-list (string-append disp-arg-list ",\n\t" extra-args)) + (set! hdlr-arg-list (string-append hdlr-arg-list ",\n\t" extra-args)) +) ) + +(emit (string-append "extern " (get "d-ret") "\n" +disp-proc-name "(" disp-arg-list ");" +"\n\ntypedef " (get "d-ret") " (" handler-type ")(\n\t" + hdlr-arg-list ");\n\n" handler-type "\n")) + +(out-push-new) =][= + +IF (exist? "d-only") =][= + +(out-push-new (string-append tmp-dir "/disp-list")) +(emit (string-downcase (string->c-name! (join "\n" (stack "d-only")))) + "\n" +) +(out-pop) =][= + +ELSE + +=] +rm -f ${tmp_dir}/disp-list +awk '{ print $2 }' ${tmp_dir}/commands[= + + IF (exist? "d-omit") =] | \ + grep -E -v '^([= + (string-downcase (string->c-name! (join " " (stack "d-only")))) +=])$' \ + sed 's/ /|/g'[= + + ENDIF d-omit =] > ${tmp_dir}/disp-list[= + +ENDIF d-only + +=] +{ + echo [=(. invalid-name)=] + cat ${tmp_dir}/disp-list +} | $CLexe -f '[= d-nam =]' -I4 --spread=1 -S, --end ';'[= + +(shell (out-pop #t)) =][= +(out-resume "disp-text") =][= +INVOKE mk-disp-code =][= +(out-suspend "disp-text") =][= + +ENDDEF mk-dispatch + +;;; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +;;; +;;;=][= + +DEFINE mk-disp-code =][= + +(out-push-new) + +=]mk_proc_dispatch() { + declare fmt="\n [[=(. enum-prefix)=]_%-${max_cmd_width}s] = [= + d-nam =]," + exec 3< ${tmp_dir}/disp-list + while read -u3 c + do + C=$(echo $c | tr '[a-z]' '[A-Z]') + printf "$fmt" $C $c + done + exec 3<&- + + printf "\n [%-${max_enm_width}s] = [= d-nam =] };\n" \ + [=(. invalid-cmd)=] [=(. invalid-name)=] +} +mk_lengths() { + exec 3< ${tmp_dir}/commands-UC + declare n=`expr ${max_cmd_width} + 1` + declare c + declare fmt="\n [[=(. enum-prefix)=]_%-${max_cmd_width}s] =" + while read -u3 n c + do + printf "$fmt ${#c}," "$c" + done | sed '$s/,$//' + + exec 3<&- +} +[= +(shell (out-pop #t)) +=] + +/** + * Dispatch a [=(. base-type-name)=] function, based on the keyword. + * + * @param[in] str a string that should start with a known key word.[= + (. len-descrip) =] + * @returns [= d-ret =], returned by the dispatched function. + */ +[= d-ret =] +[=(string-append disp-proc-name "(" disp-arg-list ")")=] +{ + static [=(. handler-type)=] * const dispatch[[= + (+ 2 bit-count)=]] = {[= + (shell "mk_proc_dispatch") =][= + +IF (. return-length) + +=] + [= (define length-value "*len") + enum-name =] id = [=(. find-func-name)=](str, len);[= + +ELIF (> (string-length len-arg) 0) + +=] + [= (define length-value "len") + enum-name =] id = [=(. find-func-name)=](str, len);[= + +ELSE + +=] + static unsigned int keywd_len[] = {[= + (shell "mk_lengths") =] }; + [= (define length-value "klen") + enum-name =] id = [=(. find-func-name)=](str); + unsigned int klen = [= + IF (exist? "alias") =](! isalnum((unsigned char)*str)) ? 1 : [= + ENDIF =]keywd_len[id];[= + +ENDIF + +=] + [=(. handler-type)=] * disp = dispatch[id]; + if (disp == NULL) + disp = dispatch[[=(. invalid-cmd)=]]; + [= + (if (= (get "d-ret") "void") "" "return ") + =]disp(id, str + [= + + IF (emit length-value) + (exist? "d-arg") =], [= + + (out-push-new) \=] + set -- `echo '[=(. extra-args)=]' | tr '*' ' '` + for f in $* + do case "$f" in + ( *, ) printf '%s ' "$f" ;; + esac + done + eval echo "\${$#}"[= + (shell (out-pop #t)) =][= + + ENDIF d-arg =]); +} +[= + +ENDDEF mk-disp-code + +;;; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +;;; +;;; Search through the alphabetized indexes for a unique partial match. +;;; +;;;=][= + +DEFINE find-part-match =] + if (map != NULL) + return map->[=(. enum-field)=]; + /* Check for a partial match */ + { + /* + * Indexes of valid [=(. base-type-name) +=]_table entries in sorted order: + */ + static unsigned int const ix_map[] = { +[= + +(out-push-new) + +=] +for f in `sed 's/:.*//' ${tmp_dir}/table` +do + echo `expr $f - 1` +done | $CLexe --spread=1 -S, -I12 --end ' };'[= + +(shell (out-pop #t)) + +=][= (define cmp-call (string-append + "strncmp(map->" name-field ", str, " len-param-name ")" )) =] + [= (. enum-name) =] res = [=(. invalid-cmd)=]; + static int const HI = (sizeof(ix_map) / sizeof(ix_map[0])) - 1; + int lo = 0; + int hi = HI; + int av; + int cmp; + + for (;;) { + av = (hi + lo) / 2; + map = [=(. base-type-name)=]_table + ix_map[av]; + cmp = [=(. cmp-call)=]; + if (cmp == 0) break; + if (cmp > 0) + hi = av - 1; + else lo = av + 1; + if (lo > hi) + return [=(. invalid-cmd)=]; + } + res = map->[=(. enum-field)=]; + /* + * If we have an exact match, accept it. + */ + if (map->[= (. name-field) =][[= (. len-param-name) =]] == NUL) + return res; + /* + * Check for a duplicate partial match (a partial match + * with a higher or lower index than "av". + */ + if (av < HI) { + map = [=(. base-type-name)=]_table + ix_map[av + 1]; + if ([=(. cmp-call)=] == 0) + return [=(. invalid-cmd)=]; + } + if (av > 0) { + map = [=(. base-type-name)=]_table + ix_map[av - 1]; + if ([=(. cmp-call)=] == 0) + return [=(. invalid-cmd)=]; + } + return res; + }[= + +ENDDEF find-part-match + +;;; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +;;; +;;; Make an enum to name converter. If the input id is valid, we *must* +;;; find an associated name. The table is compact and starts with 0. +;;; +;;;=][= + +DEFINE mk-enum2name + +=] +/** + * Convert an [= (. enum-name) =] value into a string. + * + * @param[in] id the enumeration value + * @returns the associated string, or "[=(. undef-str)=]" if \a id + * is out of range. + */ +char const * +[=(. base-type-name)=]_name([= (. enum-name) =] id) +{ + static char const undef[] = "[= + (if insert-undef "* UNDEFINED *" undef-str) =]"; + static char const * const nm_table[] = { +[= + +(out-push-new) + +=] +exec 4< ${tmp_dir}/table +while IFS='' read -u4 line +do + str=${line%\"*} + line=${line%'}'*} + printf " [%-${max_enm_width}s] = \"%s\",\n" ${line##*,} ${str#*\"} +done | sed '$s/,$/ };/'[= + +(shell (out-pop #t)) + +=] + char const * res = undef; + if (id < [=(. cmd-count)=]) { + res = nm_table[id]; + if (res == NULL) + res = undef; + } + return res; +} +[= + +ENDDEF mk-enum2name + +;;; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +;;; +;;;=][= +DEFINE run-gperf =] +[= +(define table-fmt (string-append + "%-" (number->string (+ max-cmd-width 1)) + "s " enum-prefix "_%s\n" )) +(out-push-new) + +=][= # + +;;; = = = = = = = = = = = = = = = = = = = +;;; +;;; GPERF OPTIONS +;;; +;;;\=] +%struct-type +%language=ANSI-C +%includes +%global-table +%omit-struct-type +%readonly-tables +%compare-strncmp + +%define slot-name [= +(define name-field (string-append pfx-str "_name")) name-field =] +%define hash-function-name [=(. base-type-name)=]_hash +%define lookup-function-name find_[=(. base-type-name)=]_name +%define word-array-name [=(. base-type-name)=]_table +%define initializer-suffix ,[=(. cmd-count)=] +[= + +(define gperf-opts (out-pop #t)) +(out-push-new (string-append tmp-dir "/" base-file-name ".gp")) + +\=][= # + +;;; = = = = = = = = = = = = = = = = = = = +;;; +;;; GPERF DEFINITIONS +;;; +;;;\=] +%{ +# if 0 /* gperf build options: */ +[= (prefix "// " gperf-opts) =] +# endif + +#include "[=(. header-file)=]" +typedef struct { + char const * [=(. name-field)=]; + [= (. enum-name) =] [= (define enum-field (string-append pfx-str "_id")) + enum-field =]; +} [=(. base-type-name)=]_map_t; +%} + +[= (. gperf-opts) =] + +[=(. base-type-name)=]_map_t; +%% +[= +FOR cmd =][= + (define cmd (get "cmd")) + (if (exist? "no-case") + (set! cmd (string-downcase cmd)) ) + (if (exist? "equate") + (set! cmd (string-tr! cmd equate-from equate-to)) ) + + (define tmp-val (string-append + (if (exist? "no-case") (string-downcase cmd) cmd) "," )) + + (sprintf table-fmt tmp-val (string-upcase! (string->c-name! cmd))) =][= +ENDFOR \=] +%% +[= + +(out-pop) +(out-push-new) + +=][= # + +;;; = = = = = = = = = = = = = = = = = = = RUN GPERF +;;; +;;; After running gperf, delete all the "inline" lines, the soure line +;;; numbers, GNUC INLINE hints, attribute inlines, the ASCII text tests and +;;; all the conditional code. These all check for stuff that is not relevant +;;; here. Replace all the #define-s with their defined-to values and strip +;;; out the #define-s themselves. Since we are appending to the output code, +;;; these #define-s interfere with what we need to do. Finally, we also force +;;; the generated find procedure to be static. We don't export it. +;;; +\=] +outdir=$PWD +cd ${tmp_dir} +use_args() { + while IFS='' read line + do + case "$line" in + *ARGSUSED* ) break ;; + * ) echo "$line" ;; + esac + done + + while IFS='' read line + do + case "$line" in + *' return '* ) + printf $' (void)str;\n (void)len;\n%s\n' "$line" + cat + return 0 + ;; + * ) echo "$line" + ;; + esac + done +} + +gperf [= (. base-file-name) =].gp | \ + sed -e '/^_*inline$/d' \ + -e '/^#line /d' \ + -e '/GNUC_.*_INLINE/d' \ + -e '/__attribute__.*inline/d' \ + -e '/^#if.*== *32/,/^#endif/d' \ + -e '/^#ifdef/d' \ + -e '/^#else/d' \ + -e '/^#endif$/d' \ + -e '/key = [=(. base-type-name)=]_hash/s/key = /key = (int)/' \ + -e 's/^\(const [=(. base-type-name)=]_map_t\)/static inline \1/' \ + > baseline + +sed -n -e '1,/_table\[\] =/d' \ + -e '/^ *{$/d' \ + -e '/^ *};/q' \ + -e 's/^ *//' \ + -e 's/}, {/},\ +{/g' \ + -e p baseline | \ + grep -n -v '""' | \ + sort -t: -k2 > table + +sedcmd=` + egrep '^#define ' baseline | \ + while read _ nm val _ + do + echo "/^#define *${nm}/d;s@${nm}@${val}@g" + done` + +grep -q -F '/*ARGSUSED*/' baseline && useargs=true || useargs=false +if $useargs +then + sed "${sedcmd}" baseline | use_args +else + sed "${sedcmd}" baseline +fi +[= +(shell (out-pop #t)) =][= + +ENDDEF run-gperf =] +/* end of [= (out-name) =] */[= + + # + * Local Variables: + * mode: text + * indent-tabs-mode: nil + * End: + * end of str2mask.tpl =] diff --git a/autoopts/tpl/str2init.tlib b/autoopts/tpl/str2init.tlib new file mode 100644 index 0000000..91b2826 --- /dev/null +++ b/autoopts/tpl/str2init.tlib @@ -0,0 +1,149 @@ +[= AutoGen5 Template null -*- Mode: Scheme -*- + +# This file contains the templates used to generate +# keyword parsing and bit map management code + +# This file is part of AutoGen. +# AutoGen is free software. +# AutoGen is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +# +# AutoGen is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# AutoGen is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# This file has the following md5sum: +# +# 43b91e8ca915626ed3818ffb1b71248b COPYING.gplv3 + +=][= +(define move-output-file (exist? "base-name")) +(define base-file-name (if move-output-file (get "base-name") (base-name))) +(define base-type-name (string->c-name! (string-downcase base-file-name))) +(define pfx-str "") +(define tmp-str "") +(define idx 0) + +(if move-output-file + (out-move (string-append base-file-name "." (suffix))) ) + +(if (exist? "prefix") + (set! pfx-str (string->c-name! (get "prefix"))) + (begin + (set! idx (string-index base-type-name (string->char-set "_-^"))) + (if (number? idx) + (set! pfx-str (substring/copy base-type-name 0 idx)) + (set! pfx-str base-type-name) +) ) ) +(define PFX-STR (string-upcase pfx-str)) +(define mask-name (string-append base-type-name "_mask_t")) +(define enum-name (string-append base-type-name "_enum_t")) +(define BASE-TYPE (string-upcase base-type-name)) + +(if (exist? "type") (set! enum-type (string->c-name! (get "type")))) +(define ENUM-TYPE (string-upcase (string-append "_" enum-type))) +(define find-func-name "") + +(if (<= (string-length enum-type) 0) (begin + (set! ENUM-TYPE "") + (set! find-func-name (string-append "find_" base-type-name)) + ) + (set! find-func-name (string-append + "find_" base-type-name "_" enum-type )) +) + +(define enum-prefix (string-append PFX-STR ENUM-TYPE)) +(define cmd-count (string-append PFX-STR "_COUNT" ENUM-TYPE)) +(define enum-val-offset (if (exist? "cmd[0]") 1 0)) +(define insert-undef #t) +(define invalid-name (if (exist? "invalid-name") + (string->c-name! (get "invalid-name")) + "invalid")) +(define INVALID-NAME (string-upcase invalid-name)) +(define max-cmd-width 0) +(define min-cmd-width 99999) +(define bit-count (+ 1 (high-lim "cmd"))) +(define undef-str (if (exist? "undef-str") (get "undef-str") "* UNDEFINED *")) + +(make-tmp-dir) +(out-push-new (string-append tmp-dir "/commands")) +(define finish-commands "chmod a+w ${tmp_dir}/commands") + +;;# START-BUILDTREE-ISMS + +(shell "CLexe=${AGexe%/agen5/*}/columns/columns +test -x \"${CLexe}\" || { + CLexe=${AGexe%/autogen}/columns + test -x \"${CLexe}\" || die 'columns program is not findable' +}") + +=][= # END-BUILDTREE-ISMS + +(shell + "gperf=`command -v gperf` 2>/dev/null\n" + "test -x \"$gperf\" || die 'gperf not installed'\n" + "CLexe=`echo ${AGexe} | sed 's@/autogen@/columns@'` + test -x \"${CLexe}\" || CLexe=`command -v columns`") + +# END-INSTALL-ONLY-CODE + +=][= + +FOR cmd =][= + (set! tmp-str (sprintf "what[%d]" (for-index))) + (if (exist? tmp-str) + (set! finish-commands (string-append finish-commands + "\ndesc_" tmp-str "=" (raw-shell-str (get tmp-str)) )) ) + (set! tmp-str (string-downcase! (string->c-name! (get "cmd")))) + (if (= tmp-str invalid-name) + (error (string-append "You cannot specify a cmd of " invalid-name)) ) + (set! idx (string-length tmp-str)) + (if (> idx max-cmd-width) (set! max-cmd-width idx)) + (if (< idx min-cmd-width) (set! min-cmd-width idx)) + (sprintf "%5u %s\n" (for-index) tmp-str) =][= + +ENDFOR cmd =][= + +(out-pop) +(shell finish-commands) +(if (< max-cmd-width 8) (set! max-cmd-width 8)) + + =][= +CASE invalid-val =][= +!E =][= + (define invalid-cmd (string-append PFX-STR "_" INVALID-NAME ENUM-TYPE)) + =][= + +== "~0" =][= + (set! enum-val-offset 0) + (set! insert-undef #f) + (define invalid-cmd (string-append PFX-STR "_" INVALID-NAME ENUM-TYPE)) + =][= + +== "" =][= + (set! enum-val-offset 0) + (set! insert-undef #f) + (define invalid-cmd cmd-count) + =][= + +* =][= + (error "if invalid-val exists, it is constrained to: + '' (empty) or '~0'.") + =][= + +ESAC + + * Local Variables: + * mode: scheme + * indent-tabs-mode: nil + * End: + * end of str2mask.tpl + +\=] diff --git a/autoopts/tpl/str2mask.tpl b/autoopts/tpl/str2mask.tpl new file mode 100644 index 0000000..87571e3 --- /dev/null +++ b/autoopts/tpl/str2mask.tpl @@ -0,0 +1,458 @@ +[= AutoGen5 Template h c -*- Mode: Scheme -*- + +# This file contains the templates used to generate +# bit map handling code + +## This file is part of AutoGen. +## AutoGen is free software. +## AutoGen is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . +## This file has the following md5sum: +## +## 43b91e8ca915626ed3818ffb1b71248b COPYING.gplv3 + +=][= + +CASE (suffix) =][= # + +;;; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +;;; +;;; H CODE +;;; +;;;=][= +== h =][= + +INVOKE init-header =][= + +INVOKE sizes-n-formats =][= + +(out-push-new) + +=] +hdr_file=[=(string-append tmp-dir "/" base-file-name)=].h +mask_name=[= (. mask-name) =] + +sed '/^#define .*_GUARD/q' ${hdr_file} +cat <<- _EOF_ + #include + #include + + /** integral type for holding [=(. base-type-name)=] masks */ + typedef $mask_type ${mask_name}; +[= +FOR add-on-text =][= + IF (= (get "ao-file") "mask-header") =] +[= ao-text =][= + ENDIF correct type =][= +ENDFOR add-on-text =] + _EOF_ + +echo "/** bits defined for ${mask_name} */" +ix=0 + +declare C +exec 4< ${tmp_dir}/commands +all_mask=0 +while read -u4 n C +do + C=$(echo $C | tr '[a-z]' '[A-Z]') + v=$(( 1 << n )) + desc=${desc_what[$n]} + test -z "$desc" || { + test ${#desc} -gt 72 && \ + desc=$(echo "$desc" | fmt | sed '2,$s/^/ * /') + printf '/** %s */\n' "$desc" + } + printf "$def_fmt" $C $v + (( all_mask += v )) +done +exec 4<&- + +emit_mask_def() { + declare v=0 + declare mname=${1} + shift + declare which_bits='in' + $INVERT && which_bits='omitted from' + if test $# -eq 0 + then + printf "\n/** There are no bits in ${mname}. */\n" + else + printf "\n/** bits $which_bits ${mname%_MASK} mask:\n" + echo $* | tr ' ' '\n' | $CLexe --spread=1 -I' * ' --end=' */' + fi + + for f in $* + do eval f=\${val_$f} + (( v |= f )) + done + $INVERT && (( v ^= all_mask )) + printf "$def_fmt" ${mname} $v + eval $(echo val_${mname}=$v | tr '[A-Z]' '[a-z]') +} +[= + +FOR mask =][= + (set! tmp-str (string-append + (string-upcase! (string->c-name! (get "m-name"))) "_MASK")) + (string-append "INVERT=" (if (exist? "m-invert") "true" "false") + " emit_mask_def " tmp-str " " + (string->c-name! (join " " (stack "m-bit"))) "\n") =][= + +ENDFOR mask + +\=] +printf "\n/** all bits in ${mask_name} masks */\n" +printf "$def_fmt" MASK_ALL $all_mask[= +(define zero-mask-name (string-append "MASK_" )) =][= +IF (define zero-name (get "zero-name" "EMPTY")) + (> (string-length zero-name) 0) =] +printf "\n/** no bits in ${mask_name} */\n" +printf "$def_fmt" [=(string-upcase! (string->c-name! zero-name))=] 0[= +ENDIF have zero-name =][= + +IF (not (exist? "no-code")) =] +cat <<- _EOF_ + + /** buffer size needed to hold all bit names for ${mask_name} masks */ + #define MAX_[=(. BASE-TYPE)=]_NAME_SIZE [= + (+ 1 (string-length (join " " (stack "cmd")))) =] + + extern ${mask_name} + [=(. base-type-name) =]_str2mask(char const * str, ${mask_name} old); +[= + +IF (not (exist? "no-name")) =] + extern size_t + [=(. base-type-name)=]_mask2str([=(. mask-name) + =] mask, char * buf, size_t len); +[= + +ENDIF no name + +=] + _EOF_[= + +ENDIF not exist no-code =] +grep -E '^#endif .*_GUARD ' ${hdr_file} +[= +(emit (shell (out-pop #t))) +=][= + +;;; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +;;; +;;; C CODE +;;; +;;;=][= +== c + +=][= +(if (exist? "no-code") (out-delete)) +(out-move (string-append base-file-name ".c")) +(out-push-new) \=] +exec 4< ${tmp_dir}/[=(. base-file-name)=].c +while IFS='' read -u4 line +do + echo "$line" + case "$line" in + '#include '* ) break ;; + esac +done + +sed '1,/^#define.*_GUARD/d;s/^extern /static /;/^#endif.*_GUARD/,$d' \ + ${tmp_dir}/[=(. base-file-name)=].h + +cat <<\_EOF_ + +#include +#include +#ifndef NUL +#define NUL '\0' +#endif + +_EOF_ + +sed 's/^[=(. enum-name)=]$/static [=(. enum-name)=]/ + s/^char const \*$/static char const */ + /end of .*\.c/d' <&4 +exec 4<&- + +[= +(shell (out-pop #t)) +=] + +/** + * Convert a string to a [= (. mask-name) =] mask. + * Bit names prefixed with a hyphen have the bit removed from the mask. + * If the string starts with a '-', '+' or '|' character, then + * the old value is used as a base, otherwise the result mask + * is initialized to zero. Separating bit names with '+' or '|' + * characters is optional. By default, the bits are "or"-ed into the + * result. + * + * @param[in] str string with a list of bit names + * @param[in] old previous value, used if \a str starts with a '+' or '-'. + * + * @returns an unsigned integer with the bits set. + */ +[= (string-append mask-name "\n" base-type-name) +=]_str2mask(char const * str, [=(. mask-name)=] old) +{ + static char const white[] = ", \t\f"; + static char const name_chars[] = +[= (shell +"name_chars=`echo '" + (string->c-name! (join "" (stack "cmd"))) + "' | sed 's/\\(.\\)/\\1\\\\\n/g' | tr '[A-Z]' '[a-z]' | sort -u` + +alpha=`echo \"$name_chars\" | grep -E '^[a-z]$' | tr -d ' \\n'` +digit=`echo \"$name_chars\" | grep -Ev '^[a-z]$' | tr -d ' \\n'` +fmt=' \"%s\"\\n' +printf \"$fmt\" $alpha +printf \"$fmt\" `echo $alpha | tr '[a-z]' '[A-Z]'` +test -z \"${digit}\" || \ + printf \"$fmt\" ${digit} +") =]; + + [=(. mask-name)=] res = 0; + int have_data = 0; + + for (;;) { + [=(. enum-name)=] val; + unsigned int val_len; + unsigned int invert = 0; + + str += strspn(str, white); + switch (*str) { + case NUL: return res; + case '-': case '~': + invert = 1; + /* FALLTHROUGH */ + + case '+': case '|': + if (have_data == 0) + res = old; + + str += 1 + strspn(str + 1, white); + if (*str == NUL) + return 0; + } + + val_len = strspn(str, name_chars); + if (val_len == 0) + return 0; + val = [=(. find-func-name)=](str, val_len); + if (val == [=(. enum-count)=]) + return 0; + if (invert) + res &= ~(([=(. mask-name)=])1 << val); + else + res |= ([=(. mask-name)=])1 << val; + have_data = 1; + str += val_len; + } +}[= + +IF (not (exist? "no-name")) =] + +/** + * Convert a [=(. mask-name)=] mask to a string. + * + * @param[in] mask the mask with the bits to be named + * @param[out] buf where to store the result. This may be NULL. + * @param[in] len size of the output buffer + * @results The full length of the space needed for the result, + * including the terminating NUL byte. The actual result will not + * overwrite \a len bytes at \a buf. This value will also never + * exceed MAX_[=(. BASE-TYPE)=]_NAME_SIZE. + */ +size_t +[=(. base-type-name)=]_mask2str([=(. mask-name)=] mask, char * buf, size_t len) +{ + [=(. enum-name)=] val = ([=(. enum-name)=])0; + size_t res = 0; + if (buf == NULL) len = 0; + + for (; mask != 0; val++, mask >>= 1) { + char const * p; + size_t l; + + if (val >= [=(. enum-count)=]) + break; + + if ((mask & 1) == 0) + continue; + + p = [=(. base-type-name)=]_name(val); + if (*p == '*') + continue; /* ignore invalid bits */ + + l = strlen(p) + 1; /* includes NUL byte or spacer byte */ + if (l <= len) { + if (res > 0) + *(buf++) = ' '; + memcpy(buf, p, l); + buf += l - 1; + len -= l; + } + res += l; + } + return (res == 0) ? 1 : res; +}[= +ENDIF dispatch=][= + + FOR add-on-text =][= + IF (= (get "ao-file") "mask-code") =] +[= ao-text =][= + ENDIF correct type =][= + ENDFOR add-on-text =][= + +ESAC suffix c/h + +;;; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +;; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +;;; +;;; Create the function that converts the name into an mask value. +;;; +;;;=] +/* end of [= (out-name) =] */ +[= + +DEFINE sizes-n-formats =][= +(out-push-new) =][= + +FOR mask =][= + (set! tmp-str (string-append (get "m-name") "_MASK")) + (set! idx (string-length tmp-str)) + (if (> idx max-cmd-width) (set! max-cmd-width idx)) + =][= +ENDFOR mask + +=] +sfx=U +bits=[=(. bit-count)=] +hex_width=$(( (bits + 3) / 4 )) +(( hex_width < 4 )) && hex_width=4 +[= + +IF (exist? "mask-type") + +=] +mask_type=[= mask-type =] +(( bits > 32 )) && { + (( bits > 64 )) && die "cannot handle a $bits bit mask" + sfx=UL +} +[= + +ELSE mask type not provided + +=] +if (( bits <= 8 )) +then mask_type='uint8_t' +elif (( bits <= 16 )) +then mask_type='uint16_t' +elif (( bits <= 32 )) +then mask_type='uint32_t' +elif (( bits <= 64 )) +then mask_type='uint64_t' + sfx=UL +else + die "cannot handle a $bits bit mask" +fi +[= + +ENDIF mask type provided/not + +=] +hex_fmt=0x%0${hex_width}X${sfx} +def_fmt="#define [=(string-append PFX-STR ENUM-TYPE "_") +=]%-[=(. max-cmd-width)=]s ${hex_fmt}\\n" +[= + +(shell (out-pop #t)) =][= + +ENDDEF sizes-n-formats + +;;; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +;;; +;;; Initialize for the header +;;; +;;;=][= + +DEFINE init-header =][= + +(if (exist? "dispatch") + (error "bit masks do not have dispatching available")) + +(if (exist? "alias") + (error "bit name aliases are not allowed")) + +(define enum-type (if (exist? "prefix") "" "bit")) + +=][= + +INCLUDE "str2init.tlib" + +=][= + +(out-move ".Str2Mask-Set-Aside") +(define bit-enum-type + (string-append (if (== enum-type "bit") "" enum-type) "bnm")) +(define enum-count (string-append PFX-STR "_COUNT_" + (string-upcase bit-enum-type))) +(define assign-vals "") +(define find-func-name (string-append + "find_" base-type-name "_" bit-enum-type )) +(out-push-new (string-append tmp-dir "/" base-file-name ".def")) +=] +AutoGen Definitions str2enum; +prefix = '[=(. pfx-str)=]'; +type = '[=(string-downcase bit-enum-type)=]'; +invalid-name = '[=(. invalid-name)=]'; +invalid-val = ''; +[= + +FOR cmd =][= + (set! tmp-str (get "cmd")) + (set! idx (for-index)) + (ag-fprintf 0 "cmd[%u] = '%s';\n" idx tmp-str) + (set! tmp-str (string-downcase! (string->c-name! tmp-str))) + (set! idx (ash 1 idx)) + (set! assign-vals (string-append assign-vals + "val_" tmp-str "=" (number->string idx) "\n")) + =][= +ENDFOR =][= +(if (exist? "no-code") (emit "no-code;\n")) +(if (exist? "partial") (emit "partial;\n")) +(if (exist? "no-name") (emit "no-name;\n")) +(out-pop) +(shell assign-vals +"{ ${AGexe} -L" (dirname (tpl-file #t)) " ${tmp_dir}/" base-file-name ".def" +" || die 'Could not build enumeration\n'" + "\"`cat ${tmp_dir}/" base-file-name ".def`\"\n" +"cp " base-file-name ".[ch] ${tmp_dir}/.\n" +"rm -f " base-file-name ".[ch]\n} 1>&2") +(out-move (string-append base-file-name ".h")) + +=][= + +ENDDEF init-header + + * Local Variables: + * mode: text + * indent-tabs-mode: nil + * End: + * end of str2mask.tpl \=] diff --git a/autoopts/tpl/strings.tpl b/autoopts/tpl/strings.tpl new file mode 100644 index 0000000..fc6a039 --- /dev/null +++ b/autoopts/tpl/strings.tpl @@ -0,0 +1,171 @@ +[= AutoGen5 Template c -*- Mode: scheme -*- + +## Author: Bruce Korb +## +## Copyright (C) 2011-2018 Bruce Korb, all rights reserved. +## This is free software. It is licensed for use, modification and +## redistribution under the terms of the +## Modified (3 clause) Berkeley Software Distribution License +## +## +## Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions +## are met: +## 1. Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## 2. Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in the +## documentation and/or other materials provided with the distribution. +## 3. Neither the name ``Bruce Korb'' nor the name of any other +## contributor may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## strings IS PROVIDED BY Bruce Korb ``AS IS'' AND ANY EXPRESS +## OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +## WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +## ARE DISCLAIMED. IN NO EVENT SHALL Bruce Korb OR ANY OTHER CONTRIBUTORS +## BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +## SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +## BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +## ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +=] +[= INCLUDE "tpl-config.tlib" =][= + +(define copy-years (shell + "sed -n '/Copyright (C)/ { + s/.*(C) *// + s/ *Bruce.*// + p + q + }' " (tpl-file #t) )) \=] +[= INVOKE leader guard = false \=] +[= (out-push-new (string-append (base-name) ".h")) \=] +[= INVOKE leader guard = true =] +[= (out-suspend "header") ;; resume defines + (define string-name (string->c-name! (string-append + (base-name) "-strtable"))) + (string-table-new string-name) + (define max-name-len 0) + (define tmp-str "") + (define tmp-len 0) \=] +#include "[= (. header-file) =]" +[= + +(define str-nm "") +(define str-val "") +(define str-ct 0) +(define name-ln 0) +(define find-ln "") +(define def-fmt "#define %%-%us (%%s)\n#define %%-%us %%d\n") +(out-push-new) ;; temp file for #defines +=][= +FOR string =][= + (set! find-ln (string-length (get "nm" ""))) + (if (> find-ln name-ln) + (set! name-ln find-ln)) =][= +ENDFOR string =][= + +(if (exist? "file-name-string") (begin + (set! str-nm (string-upcase (string-append string-name "_file"))) + (set! find-ln (string-length str-nm)) + (if (> find-ln name-ln) + (set! name-ln find-ln)) + (set! def-fmt (sprintf def-fmt (+ 1 name-ln) (+ 5 name-ln))) + (set! str-ct 1) + (set! str-val (string-append (base-name) ".c")) + (set! tmp-str (string-table-add-ref string-name str-val)) + (ag-fprintf 0 def-fmt str-nm tmp-str + (string-append str-nm "_LEN") (string-length str-val)) + ) + + (set! def-fmt (sprintf def-fmt (+ 1 name-ln) (+ 5 name-ln))) +) + +(set! find-ln "") =][= + +FOR string =][= + (set! str-nm (get "nm")) + (set! str-ct (+ str-ct 1)) + (set! str-val (get "str" str-nm)) + (set! tmp-str (string-table-add-ref string-name str-val)) + (if (exist? "define-line-no") + (set! find-ln (string-append find-ln str-nm " " tmp-str "\n")) ) + (sprintf def-fmt str-nm tmp-str + (string-append str-nm "_LEN") (string-length str-val)) =][= +ENDFOR string =][= + +(out-suspend "defines") +(out-resume "header") ;; real header file +(ag-fprintf 0 + "/*\n * %d strings in %s string table\n */\n" str-ct string-name) +(out-resume "defines") +(emit (shell (string-append "sort <<\\_EOF_\n" + (out-pop #t) "_EOF_"))) ;; #defines now in real header file +(emit "\n") +(out-push-new) +(emit-string-table string-name) +(define str-table (out-pop #t)) +(emit (shell (string-append + "sed -n '/static char const/ { + s/static char/extern char/ + s/ *=.*/;/ + p + q + }' <<\\_EOF_\n" + str-table + "\n_EOF_" +))) +(out-suspend "header") ;; resuming text output +(shell (string-append + "sed 's/^static char const/char const/' <<\\_EOF_\n" + str-table + "\n_EOF_" +)) =][= + +IF (out-resume "header") ;; real header file + (> (string-length find-ln) 0)=] + +[= (out-push-new) =] +while read nm ln +do + test -z "$nm" && break + ln='/\* *'${ln#*+}' \*/' + ln=`[=(. egrep-prog)=] -n "$ln" [= (base-name) =].c` + nm=`echo $nm | tr '[a-z]' '[A-Z]'`_LINENO + printf '#define %-31s %s\n' ${nm} ${ln%%:*} +done <<\_EOF_ +[= (. find-ln) =]_EOF_[= + +(shell (out-pop #t)) =][= +ENDIF find-ln not empty =][= +(if (exist? "header-trailer") + (emit (join "\n\n" "header-trailer")) ) \=] + + +#endif /* [= (. header-guard) =] */ +[= (out-pop) =][= + +DEFINE leader \=][= + (emit (dne " * " "/* ")) + (emit "\n *\n") + (emit (license-full "mbsd" "strings" " * " "Bruce Korb" copy-years)) + (emit "\n */\n") + (if (= (get "guard") "true") + (emit (string-append + (make-header-guard "strings") + (if (exist? "header-leader") (string-append "\n\n" + (join "\n\n" "header-leader") ) "" ) )) + (if (exist? "code-leader") + (emit (string-append "\n\n" (join "\n\n" "code-leader"))) ) + ) +=][= + +ENDDEF leader =][= +(if (exist? "code-trailer") + (emit (join "\n\n" "code-trailer")) ) =] + +/* end of [= (out-name) =] */ diff --git a/autoopts/tpl/texi2man.sh b/autoopts/tpl/texi2man.sh new file mode 100755 index 0000000..7889f05 --- /dev/null +++ b/autoopts/tpl/texi2man.sh @@ -0,0 +1,75 @@ +#! /bin/sh + +## texi2man.sh -- script to convert texi-isms to man page isms +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +## This "library" converts texi-isms into man-isms. It gets included +## by the man page template at the point where texi-isms might start appearing +## and then "emit-man-text" is invoked when all the text has been assembled. +## +## Display the command line prototype, +## based only on the argument processing type. +## +## And run the entire output through "sed" to convert texi-isms + +nl=' +' +sedcmd= +bracket='{\([^}]*\)}' +replB='%BACKSLASH%fB\1%BACKSLASH%fP' +replI='%BACKSLASH%fI\1%BACKSLASH%fP' + +for f in code command var env dvn samp option strong +do + sedcmd="${sedcmd}s;@${f}${bracket};${replB};g${nl}" +done + +for f in i file emph kbd key abbr acronym email indicateurl +do + sedcmd="${sedcmd}s;@${f}${bracket};${replI};g${nl}" +done + +sed \ + -e "${sedcmd}" \ + -e 's;@pxref{\([^}]*\)};see: \1;g' \ + -e 's;@xref{\([^}]*\)};see: \1;g' \ + -e 's/@\([{}]\)/\1/g' \ + -e 's,^\$\*$,.br,' \ + -e '/@ *example/,/@ *end *example/s/^/ /' \ + -e 's/^ *@ *example/.nf/' \ + -e 's/^ *@ *end *example/.fi/' \ + -e '/^ *@ *noindent/d' \ + -e '/^ *@ *enumerate/d' \ + -e 's/^ *@ *end *enumerate/.br/' \ + -e '/^ *@ *table/d' \ + -e 's/^ *@ *end *table/.br/' \ + -e 's/^@item \(.*\)/.sp\ +.IR "\1"/' \ + -e 's/^@item/.sp 1/' \ + -e 's/\*\([a-zA-Z0-9:~=_ -]*\)\*/%BACKSLASH%fB\1%BACKSLASH%fP/g' \ + -e 's/``\([a-zA-Z0-9:~+=_ -]*\)'"''"'/\\(lq\1\\(rq/g' \ + -e "s/^'/\\'/" \ + -e 's/^@\*/.br/' \ + -e 's/^@sp/.sp/' \ + -e 's/ -/ \\-/g' \ + -e 's@^\.in \\-@.in -@' \ + -e 's#%BACKSLASH%#\\#g' diff --git a/autoopts/tpl/texi2mdoc.sh b/autoopts/tpl/texi2mdoc.sh new file mode 100755 index 0000000..b60aafa --- /dev/null +++ b/autoopts/tpl/texi2mdoc.sh @@ -0,0 +1,195 @@ +#! /bin/sh + +## texi2mdoc.sh -- script to convert texi-isms to mdoc-isms +## +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +## This "library" converts texi-isms into man-isms. It gets included +## by the man page template at the point where texi-isms might start appearing +## and then "emit-man-text" is invoked when all the text has been assembled. +## +## Display the command line prototype, +## based only on the argument processing type. +## +## And run the entire output through "sed" to convert texi-isms + +# /bin/sh on Solaris is too horrible for words +# +case "$0" in +/bin/sh ) test -x /usr/xpg4/bin/sh && exec /usr/xpg4/bin/sh ${1+"$@"} ;; +esac + +parent_pid=$$ +prog=`basename $0 .sh` + +die() { + echo "$prog error: $*" >&2 + kill -TERM $parent_pid + sleep 1 + kill -9 $parent_pid + sleep 1 + exit 1 +} + +do_example() { + echo '.Bd -literal -offset indent' + res=0 + + while : + do + IFS='' read -r line || die "incomplete example" + case "$line" in + '@end '*example ) break ;; + esac + + do_line + done + echo '.Ed' + return $res +} + +do_noindent() { + return 0 +} + +do_enumerate() { + echo '.Bl -enum -compact' + + while : + do + IFS='' read -r line || die "incomplete enumerate" + case "$line" in + '@end '*enumerate ) break ;; + esac + + do_line + done + echo '.El' + + return $res +} + +do_end() { + die "Improper ending: $line" +} + +do_table() { + echo '.Bl -tag -width 8n' + + while : + do + IFS='' read -r line || die "incomplete table" + case "$line" in + '@end '*table ) break ;; + esac + + do_line + done + echo '.El' + + return $res +} + +do_itemize() { + echo '.Bl -bullet -compact' + + while : + do + IFS='' read -r line || die "incomplete itemize" + case "$line" in + '@end '*itemize ) break ;; + esac + + do_line + done + echo '.El' + + return $res +} + +do_item() { + printf '%s\n' "$line" | sed 's/@item/.It/' +} + +do_line() { + case "${line}" in + '@subheading'* ) printf '%s\n' "$line" | sed 's/@subheading/.SS /' ;; + '@*' ) echo .br ;; + '@sp') echo echo "${line}" | sed 's/@sp/.sp/' ;; + '' ) echo .sp ;; + '@'[{}]* ) printf '%s\n' "${line}" | sed 's/@\([{}]\)/\1/g' ;; + '@'* ) + typ=`printf '%s\n' "$line" | egrep '@[a-z]*\{'` + test ${#typ} -gt 0 && printf '%s\n' "$line" && return 0 + typ=`printf '%s\n' "$line" | sed 's/@ *//;s/[^a-z].*//'` + eval do_${typ} || die "do_${typ} failed" + ;; + + * ) + printf '%s\n' "$line" + ;; + esac + return 0 +} + + +nl=' +' +sedcmd= +bracket='{\([^}]*\)}' +replB='%BACKSLASH%fB\1%BACKSLASH%fP' +replI='%BACKSLASH%fI\1%BACKSLASH%fP' + +for f in code command var env dvn samp option strong +do + sedcmd="${sedcmd}s;@${f}${bracket};${replB};g${nl}" +done + +for f in i file emph kbd key abbr acronym email indicateurl +do + sedcmd="${sedcmd}s;@${f}${bracket};${replI};g${nl}" +done + +fixfont="${sedcmd}"' + s;@pxref{\([^}]*\)};see: \1;g + s;@xref{\([^}]*\)};see: \1;g + s/@\([{@}]\)/\1/g + s,^[@$]\*$,.br, + s/\*\([a-zA-Z0-9:~=_ -]*\)\*/\\fB\1\\fP/g + s/``\([a-zA-Z0-9:~+=_ -]*\)'\'\''/\\(lq\1\\(rq/g + s/\([^\\]\)-/\1\\-/g + s/\([^\\]\)-/\1\\-/g + /^\.Bl /s/ \\-/ -/g + /^\.Bd /s/ \\-/ -/g + /^\.in /s/ \\-/ -/g + s#%BACKSLASH%#\\#g'" + s/^'/\\\\'/ + /^\$/d" +readonly fixfont + +{ + while IFS='' read -r line + do + do_line + done +} | sed "${fixfont}" + +exit 0 diff --git a/autoopts/tpl/tpl-config-tlib.in b/autoopts/tpl/tpl-config-tlib.in new file mode 100644 index 0000000..e1c6b52 --- /dev/null +++ b/autoopts/tpl/tpl-config-tlib.in @@ -0,0 +1,82 @@ +[= Autogen5 Template configuration -*- Mode: scheme -*- =] +[= + +# This file contains configure stuff used by various templates. + +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +=][= + +(define ao-version "@AO_CURRENT@:@AO_REVISION@:@AO_AGE@") +(define ao-template-ver "@AO_TEMPLATE_VERSION@") + +(define inst-prefix + (shell "prefix=\"@prefix@\" + echo \"${prefix}\"")) + +(define exec-prefix + (shell "exec_prefix=\"@exec_prefix@\" + echo \"${exec_prefix}\"")) + +(define inst-bin-dir + (shell "bindir=\"@bindir@\" + echo \"${bindir}\"")) + +(define libs + (shell "LIBS=\"@LIBS@\" + echo \"${LIBS}\"")) + +(define inc-dir + (shell "includedir=\"@includedir@\" + echo \"${includedir}\"")) + +(define lib-dir + (shell "libdir=\"@libdir@\" + echo \"${libdir}\"")) + +(define package + (shell "PACKAGE_TARNAME=\"@PACKAGE_TARNAME@\" + echo \"${PACKAGE_TARNAME}\"")) + +(define data-root-dir + (shell "datarootdir=\"@datarootdir@\" + echo \"${datarootdir}\"")) + +(define data-dir + (shell "datadir=\"@datadir@\" + echo \"${datadir}\"")) + +(define grep-prog + (shell "GREP=\"@GREP@\" + echo \"${GREP}\"")) + +(define egrep-prog + (shell "EGREP=\"@EGREP@\" + echo \"${EGREP}\"")) + +(define fgrep-prog + (shell "FGREP=\"@FGREP@\" + echo \"${FGREP}\"")) + +(define top-build-dir (shell "\\cd .. >/dev/null ; pwd")) +(define pkgdatadir (shell "echo \"${datadir}/${package}\"")) +(setenv "SHELL" "@POSIX_SHELL@") +;;; \=] diff --git a/autoopts/tpl/usage.tlib b/autoopts/tpl/usage.tlib new file mode 100644 index 0000000..eefc6e6 --- /dev/null +++ b/autoopts/tpl/usage.tlib @@ -0,0 +1,245 @@ +[= AutoGen5 Template -*- Mode: shell-script -*- + + help-text + +# This file is part of AutoGen. +# AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +# +# AutoGen is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# AutoGen is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . + +=][= INCLUDE "tpl-config.tlib" =][= + + ;; This template is designed to emit help text from the current set + ;; of option definitions. + ;; + ;;# START-BUILDTREE-ISMS + ;; + (shell "CLexe=${AGexe%/agen5/*}/columns/columns + test -x \"${CLexe}\" || { + CLexe=${AGexe%/autogen}/columns + test -x \"${CLexe}\" || die 'columns program is not findable' + }") + +=][= # END-BUILDTREE-ISMS + +(shell "CLexe=`echo ${AGexe} | sed 's@/autogen@/columns@'` + test -x \"${CLexe}\" || CLexe=`which columns`") + +# END-INSTALL-ONLY-CODE =][= + + (make-tmp-dir) + (out-push-new (shellf "echo ${tmp_dir}/%s.def" (get "prog-name"))) + (define emit-def (lambda (vname) + (if (exist? vname) + (sprintf "\n%s = %s;" vname (kr-string (get vname))) ) )) +=] +AutoGen Definitions options.tpl; +no-libopts; +no-xlate = anything; +autoopts-usage-tlib; +[= + +FOR var IN prog-name prog-title argument + environrc export homerc include + long-opts rcfile version detail + explain package preserve-case prog-desc + opts-ptr gnu-usage reorder-args usage-opt + + version-value help-value more-help-value + save-opts-value usage-value load-opts-value + =][= + (emit-def (get "var")) =][= +ENDFOR var IN .... =][= + +IF (exist? "config-header") =] +config-header = '[= prog-name =]-config.h';[= +ENDIF =][= + +FOR copyright =] +copyright = {[= + + FOR var IN date owner type text author eaddr + =][= + (emit-def (get "var")) =][= + ENDFOR var IN .... =] +};[= +ENDFOR copyright =] + +main = { main-type = main; }; +[= + +FOR flag + +=] +flag = {[= + + FOR var IN name descrip value max min must-set enable disable enabled + ifdef ifndef no-preset settable equivalence documentation + immediate immed-disable also + arg-type arg-optional arg-default default arg-range + stack-arg unstack-arg + =][= + (emit-def (get "var")) =][= + ENDFOR var IN .... =][= + + IF (exist? "keyword") =] + keyword = '[= (join "', '" (stack "keyword")) =]';[= + ENDIF keyword exists =][= + + IF (exist? "flags-must") =] + flags-must = '[= (join "', '" (stack "flags-must")) =]';[= + ENDIF flags-must exists =][= + + IF (exist? "flags-cant") =] + flags-cant = '[= (join "', '" (stack "flags-cant")) =]';[= + ENDIF flags-cant exists =] +};[= + +ENDFOR flag =][= + +(out-pop) +(out-push-new) +(out-push-new) =][= + +# We are creating a shell script that needs to obtain values from the current +# execution envronment for an execution environment that happens later. +# \=] +export tmp_dir="${tmp_dir}" \ + top_builddir="${top_builddir}" \ + CFLAGS="${CFLAGS}" \ + CLexe="${CLexe}"[= + +(shell (out-pop #t)) =] +save_dir=`pwd` +# redirect stdout. We see this IFF there is a problem +# +redirect_log=${tmp_dir}/redirected.log +exec 7>&1 9>&2 1> ${redirect_log} 2>&1 || \ + die "Redirection failure: 7>&1 9>&2 1> ${redirect_log} 2>&1" +redirect_die() { + exec 2>&9 1>&9 9>&- 7>&- + sed 's/^/## /' ${redirect_log} + die "$*" +} + +inc_list="-I${PWD} -I[=(. inc-dir)=]" +cfg_ldflags="[=(. libs)=]" +cfg_cflags="${CFLAGS}" +exe=${tmp_dir}/[= prog-name =] +[= # START-BUILDTREE-ISMS: + +# The following code is sedded away in install-hook.sh. +# The goal is to remove build tree-isms when installing this file. + +\=] +test -z "${top_builddir}" && ldflags='' || \ + ldflags=`exec 2>/dev/null + find ${top_builddir}/autoopts -name "libopts*.${OBJEXT}" | head -1` + +test -f "${ldflags}" || { + ldflags='[=(. lib-dir)=]/libopts.a' + test -f "${ldflags}" || redirect_die "Cannot locate libopts.a" +} +ldflags="$ldflags ${cfg_ldflags}" +test -d "${top_builddir}" && \ + inc_list="-I${top_builddir} -I${top_builddir}/autoopts ${inc_list}" +test -d "${top_srcdir}" && \ + inc_list="-I${top_srcdir}/autoopts ${inc_list}" + +[= # END-BUILDTREE-ISMS the following code is for installed version: + +aocfg=`dirname ${AGexe}`/autoopts-config +test -x "$aocfg" || redirect_die "missing $ag" +ldflags="${cfg_ldflags} `${aocfg} ldflags`" +cfg_cflags="${cfg_cflags} `${aocfg} cflags`" + +# END-INSTALL-ONLY-CODE \=] +[= IF (exist? "config-header") \=] +inc_list="-I${tmp_dir} ${inc_list}" +while : +do + h='[= config-header =]' + test -f "$h" && break + hdr=$h + h=`basename "${hdr}"` + test -f "$h" && break + g=$h + d=`pwd` + + while : + do + d=`dirname $d` + test "X$d" = X/ && \ + redirect_die "cannot locate $h" + h="$d/$g" + test -f "$h" && break + h="$d/$hdr" + test -f "$h" && break + done + break +done +cp "${h}" ${exe}-config.h +[= ENDIF \=] +flags="-DTEST_[= (string-upcase! (string->c-name! (get "prog-name"))) + =]_OPTS=1 ${inc_list} ${cfg_cflags}" +tpldir=`dirname [= (tpl-file)=]` +tpldir=`cd $tpldir >/dev/null && pwd` +cd ${tmp_dir} +mkdir ag-tmp +TMPDIR=${tmp_dir}/ag-tmp \ + ${AGexe} -L $tpldir [= prog-name =].def || \ + redirect_die "Cannot gen [= prog-name =]" +cd - +${CC:-cc} ${flags} -g -o TMPexe$$ ${exe}.c ${ldflags} || \ + redirect_die cannot compile ${exe}.c +mv -f TMPexe$$ ${exe} +xtr_set=`set -o | awk '/^xtrace/{ print $2 }'` +set +x +exec 2>/dev/null 1>&7 +${exe} [= + + (if (== (get "usage-type") "short") + (if (exist? "usage-opt") + (if (exist? "long-opts") + "--usage" + (string-append "-" (get "usage-value" "u")) + ) + "--give-me-short-usage 2>&1 | sed -e '/: illegal option /d'" + ) + (if (exist? "long-opts") + "--help" + (string-append "-" (get "help-value" "?")) + ) ) =] || \ + redirect_die "cannot obtain ${exe} help in ${tmp_dir}" +test "X${VERBOSE:-false}" = Xtrue && \ + cp -frp ${tmp_dir}/. ${save_dir}/TEMP-DIR +exec 1>&7 2>&9 7>&- 9>&- +test X$xtr_set = Xon && set -x +[= + +(shell (out-pop #t)) + +=][= +## +## Local Variables: +## Mode: shell-script +## indent-tabs-mode: nil +## sh-basic-offset: 4 +## sh-indent-after-do: 4 +## sh-indentation: 4 +## sh-indent-for-case-label: 0 +## sh-indent-for-case-alt: 4 +## End: +## +# end of usage.tlib =] diff --git a/autoopts/usage.c b/autoopts/usage.c new file mode 100644 index 0000000..8df3591 --- /dev/null +++ b/autoopts/usage.c @@ -0,0 +1,1285 @@ + +/* + * \file usage.c + * + * This module implements the default usage procedure for + * Automated Options. It may be overridden, of course. + * + * @addtogroup autoopts + * @{ + */ +/* + * Sort options: + --start=END-[S]TATIC-FORWARD --patt='^/\*($|[^:])' \ + --out=xx.c key='^[a-zA-Z0-9_]+\(' --trail='^/\*:' \ + --spac=2 --input=usage.c + */ + +/* + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +#define GRAPH_CH(_ch) \ + ((((unsigned)_ch) <= 0x7E) && (((unsigned)_ch) > ' ')) + +/** + * Parse the option usage flags string. Any parsing problems yield + * a zero (no flags set) result. This function is internal to + * set_usage_flags(). + * + * @param[in] fnt Flag Name Table - maps a name to a mask + * @param[in] txt the text to process. If NULL, then + * getenv("AUTOOPTS_USAGE") is used. + * @returns a bit mask indicating which \a fnt entries were found. + */ +static unsigned int +parse_usage_flags(ao_flag_names_t const * fnt, char const * txt) +{ + unsigned int res = 0; + + /* + * The text may be passed in. If not, use the environment variable. + */ + if (txt == NULL) { + txt = getenv("AUTOOPTS_USAGE"); + if (txt == NULL) + return 0; + } + + txt = SPN_WHITESPACE_CHARS(txt); + if (*txt == NUL) + return 0; + + /* + * search the string for table entries. We must understand everything + * we see in the string, or we give up on it. + */ + for (;;) { + int ix = 0; + + for (;;) { + if (strneqvcmp(txt, fnt[ix].fnm_name, (int)fnt[ix].fnm_len) == 0) + break; + if (++ix >= AOUF_COUNT) + return 0; + } + + /* + * Make sure we have a full match. Look for whitespace, + * a comma, or a NUL byte. + */ + if (! IS_END_LIST_ENTRY_CHAR(txt[fnt[ix].fnm_len])) + return 0; + + res |= 1U << ix; + txt = SPN_WHITESPACE_CHARS(txt + fnt[ix].fnm_len); + + switch (*txt) { + case NUL: + return res; + + case ',': + txt = SPN_WHITESPACE_CHARS(txt + 1); + /* Something must follow the comma */ + /* FALLTHROUGH */ + + default: + continue; + } + } +} + +/** + * Set option usage flags. Any parsing problems yield no changes to options. + * Three different bits may be fiddled: \a OPTPROC_GNUUSAGE, \a OPTPROC_MISUSE + * and \a OPTPROC_COMPUTE. + * + * @param[in] flg_txt text to parse. If NULL, then the AUTOOPTS_USAGE + * environment variable is parsed. + * @param[in,out] opts the program option descriptor + */ +static void +set_usage_flags(tOptions * opts, char const * flg_txt) +{ +# define _aof_(_n, _f) { sizeof(#_n)-1, _f, #_n }, + static ao_flag_names_t const fn_table[AOUF_COUNT] = { + AOFLAG_TABLE + }; +# undef _aof_ + + /* + * the flag word holds a bit for each selected table entry. + */ + unsigned int flg = parse_usage_flags(fn_table, flg_txt); + if (flg == 0) return; + + /* + * Ensure we do not have conflicting selections + */ + { + static unsigned int const form_mask = + AOUF_gnu | AOUF_autoopts; + static unsigned int const misuse_mask = + AOUF_no_misuse_usage | AOUF_misuse_usage; + if ( ((flg & form_mask) == form_mask) + || ((flg & misuse_mask) == misuse_mask) ) + return; + } + + /* + * Now fiddle the fOptSet bits, based on settings. + * The OPTPROC_LONGOPT bit is immutable, thus if it is set, + * then fnm points to a mask off mask. + */ + { + ao_flag_names_t const * fnm = fn_table; + for (;;) { + if ((flg & 1) != 0) { + if ((fnm->fnm_mask & OPTPROC_LONGOPT) != 0) + opts->fOptSet &= fnm->fnm_mask; + else opts->fOptSet |= fnm->fnm_mask; + } + flg >>= 1; + if (flg == 0) + break; + fnm++; + } + } +} + +/* + * Figure out if we should try to format usage text sort-of like + * the way many GNU programs do. + */ +static inline bool +do_gnu_usage(tOptions * pOpts) +{ + return (pOpts->fOptSet & OPTPROC_GNUUSAGE) ? true : false; +} + +/* + * Figure out if we should try to format usage text sort-of like + * the way many GNU programs do. + */ +static inline bool +skip_misuse_usage(tOptions * pOpts) +{ + return (pOpts->fOptSet & OPTPROC_MISUSE) ? true : false; +} + + +/*=export_func optionOnlyUsage + * + * what: Print usage text for just the options + * arg: + tOptions * + pOpts + program options descriptor + + * arg: + int + ex_code + exit code for calling exit(3) + + * + * doc: + * This routine will print only the usage for each option. + * This function may be used when the emitted usage must incorporate + * information not available to AutoOpts. +=*/ +void +optionOnlyUsage(tOptions * pOpts, int ex_code) +{ + char const * pOptTitle = NULL; + + set_usage_flags(pOpts, NULL); + if ((ex_code != EXIT_SUCCESS) && + skip_misuse_usage(pOpts)) + return; + + /* + * Determine which header and which option formatting strings to use + */ + if (do_gnu_usage(pOpts)) + (void)setGnuOptFmts(pOpts, &pOptTitle); + else + (void)setStdOptFmts(pOpts, &pOptTitle); + + prt_opt_usage(pOpts, ex_code, pOptTitle); + + fflush(option_usage_fp); + if (ferror(option_usage_fp) != 0) + fserr_exit(pOpts->pzProgName, zwriting, (option_usage_fp == stderr) + ? zstderr_name : zstdout_name); +} + +/** + * Print a message suggesting how to get help. + * + * @param[in] opts the program options + */ +static void +print_offer_usage(tOptions * opts) +{ + char help[24]; + + if (HAS_opt_usage_t(opts)) { + int ix = opts->presetOptCt; + tOptDesc * od = opts->pOptDesc + ix; + while (od->optUsage != AOUSE_HELP) { + if (++ix >= opts->optCt) + ao_bug(zmissing_help_msg); + od++; + } + switch (opts->fOptSet & (OPTPROC_LONGOPT | OPTPROC_SHORTOPT)) { + case OPTPROC_SHORTOPT: + help[0] = '-'; + help[1] = od->optValue; + help[2] = NUL; + break; + + case OPTPROC_LONGOPT: + case (OPTPROC_LONGOPT | OPTPROC_SHORTOPT): + help[0] = help[1] = '-'; + strncpy(help + 2, od->pz_Name, 20); + break; + + case 0: + strncpy(help, od->pz_Name, 20); + break; + } + + } else { + switch (opts->fOptSet & (OPTPROC_LONGOPT | OPTPROC_SHORTOPT)) { + case OPTPROC_SHORTOPT: + strcpy(help, "-h"); + break; + + case OPTPROC_LONGOPT: + case (OPTPROC_LONGOPT | OPTPROC_SHORTOPT): + strcpy(help, "--help"); + break; + + case 0: + strcpy(help, "help"); + break; + } + } + + fprintf(option_usage_fp, zoffer_usage_fmt, opts->pzProgName, help); +} + +/** + * Print information about each option. + * + * @param[in] opts the program options + * @param[in] exit_code whether or not there was a usage error reported. + * used to select full usage versus abbreviated. + */ +static void +print_usage_details(tOptions * opts, int exit_code) +{ + { + char const * pOptTitle = NULL; + int flen; + + /* + * Determine which header and which option formatting strings to use + */ + if (do_gnu_usage(opts)) { + flen = setGnuOptFmts(opts, &pOptTitle); + sprintf(line_fmt_buf, zFmtFmt, flen); + fputc(NL, option_usage_fp); + + } else { + flen = setStdOptFmts(opts, &pOptTitle); + sprintf(line_fmt_buf, zFmtFmt, flen); + + /* + * When we exit with EXIT_SUCCESS and the first option is a doc + * option, we do *NOT* want to emit the column headers. + * Otherwise, we do. + */ + if ( (exit_code != EXIT_SUCCESS) + || ((opts->pOptDesc->fOptState & OPTST_DOCUMENT) == 0) ) + + fputs(pOptTitle, option_usage_fp); + } + + flen = 4 - ((flen + 15) / 8); + if (flen > 0) + tab_skip_ct = flen; + prt_opt_usage(opts, exit_code, pOptTitle); + } + + /* + * Describe the mechanics of denoting the options + */ + switch (opts->fOptSet & OPTPROC_L_N_S) { + case OPTPROC_L_N_S: fputs(zFlagOkay, option_usage_fp); break; + case OPTPROC_SHORTOPT: break; + case OPTPROC_LONGOPT: fputs(zNoFlags, option_usage_fp); break; + case 0: fputs(zOptsOnly, option_usage_fp); break; + } + + if ((opts->fOptSet & OPTPROC_NUM_OPT) != 0) + fputs(zNumberOpt, option_usage_fp); + + if ((opts->fOptSet & OPTPROC_REORDER) != 0) + fputs(zReorder, option_usage_fp); + + if (opts->pzExplain != NULL) + fputs(opts->pzExplain, option_usage_fp); + + /* + * IF the user is asking for help (thus exiting with SUCCESS), + * THEN see what additional information we can provide. + */ + if (exit_code == EXIT_SUCCESS) + prt_prog_detail(opts); + + /* + * Give bug notification preference to the packager information + */ + if (HAS_pzPkgDataDir(opts) && (opts->pzPackager != NULL)) + fputs(opts->pzPackager, option_usage_fp); + + else if (opts->pzBugAddr != NULL) + fprintf(option_usage_fp, zPlsSendBugs, opts->pzBugAddr); + + fflush(option_usage_fp); + + if (ferror(option_usage_fp) != 0) + fserr_exit(opts->pzProgName, zwriting, (option_usage_fp == stderr) + ? zstderr_name : zstdout_name); +} + +static void +print_one_paragraph(char const * text, bool plain, FILE * fp) +{ + if (plain) { +#ifdef ENABLE_NLS +#ifdef HAVE_LIBINTL_H +#ifdef DEBUG_ENABLED +#undef gettext +#endif + char * buf = dgettext("libopts", text); + if (buf == text) + text = gettext(text); +#endif /* HAVE_LIBINTL_H */ +#endif /* ENABLE_NLS */ + fputs(text, fp); + } + + else { + char const * t = optionQuoteString(text, LINE_SPLICE); + fprintf(fp, PUTS_FMT, t); + AGFREE(t); + } +} + +/*=export_func optionPrintParagraphs + * private: + * + * what: Print a paragraph of usage text + * arg: + char const * + text + a block of text that has bee i18n-ed + + * arg: + bool + plain + false -> wrap text in fputs() + + * arg: + FILE * + fp + the stream file pointer for output + + * + * doc: + * This procedure is called in two contexts: when a full or short usage text + * has been provided for display, and when autogen is assembling a list of + * translatable texts in the optmain.tlib template. In the former case, \a + * plain is set to \a true, otherwise \a false. + * + * Anything less than 256 characters in size is printed as a single unit. + * Otherwise, paragraphs are detected. A paragraph break is defined as just + * before a non-empty line preceded by two newlines or a line that starts + * with at least one space character but fewer than 8 space characters. + * Lines indented with tabs or more than 7 spaces are considered continuation + * lines. + * + * If 'plain' is true, we are emitting text for a user to see. So, if it is + * true and NLS is not enabled, then just write the whole thing at once. +=*/ +void +optionPrintParagraphs(char const * text, bool plain, FILE * fp) +{ + size_t len = strlen(text); + char * buf; +#ifndef ENABLE_NLS + if (plain || (len < 256)) +#else + if (len < 256) +#endif + { + print_one_paragraph(text, plain, fp); + return; + } + + AGDUPSTR(buf, text, "ppara"); + text = buf; + + for (;;) { + char * scan; + + if (len < 256) { + done: + print_one_paragraph(buf, plain, fp); + break; + } + scan = buf; + + try_longer: + scan = strchr(scan, NL); + if (scan == NULL) + goto done; + + if ((scan - buf) < 40) { + scan++; + goto try_longer; + } + + scan++; + if ((! isspace((int)*scan)) || (*scan == HT)) + /* + * line starts with tab or non-whitespace --> continuation + */ + goto try_longer; + + if (*scan == NL) { + /* + * Double newline -> paragraph break + * Include all newlines in current paragraph. + */ + while (*++scan == NL) /*continue*/; + + } else { + char * p = scan; + int sp_ct = 0; + + while (*p == ' ') { + if (++sp_ct >= 8) { + /* + * Too many spaces --> continuation line + */ + scan = p; + goto try_longer; + } + p++; + } + } + + /* + * "scan" points to the first character of a paragraph or the + * terminating NUL byte. + */ + { + char svch = *scan; + *scan = NUL; + print_one_paragraph(buf, plain, fp); + len -= scan - buf; + if (len <= 0) + break; + *scan = svch; + buf = scan; + } + } + AGFREE(text); +} + +/*=export_func optionUsage + * private: + * + * what: Print usage text + * arg: + tOptions * + opts + program options descriptor + + * arg: + int + exitCode + exit code for calling exit(3) + + * + * doc: + * This routine will print usage in both GNU-standard and AutoOpts-expanded + * formats. The descriptor specifies the default, but AUTOOPTS_USAGE will + * over-ride this, providing the value of it is set to either "gnu" or + * "autoopts". This routine will @strong{not} return. + * + * If "exitCode" is "AO_EXIT_REQ_USAGE" (normally 64), then output will to + * to stdout and the actual exit code will be "EXIT_SUCCESS". +=*/ +noreturn void +optionUsage(tOptions * opts, int usage_exit_code) +{ + int exit_code = (usage_exit_code == AO_EXIT_REQ_USAGE) + ? EXIT_SUCCESS : usage_exit_code; + + displayEnum = false; + set_usage_flags(opts, NULL); + + /* + * Paged usage will preset option_usage_fp to an output file. + * If it hasn't already been set, then set it to standard output + * on successful exit (help was requested), otherwise error out. + * + * Test the version before obtaining pzFullUsage or pzShortUsage. + * These fields do not exist before revision 30. + */ + { + char const * pz; + + if (exit_code == EXIT_SUCCESS) { + pz = (opts->structVersion >= 30 * 4096) + ? opts->pzFullUsage : NULL; + + if (option_usage_fp == NULL) + option_usage_fp = print_exit ? stderr : stdout; + + } else { + pz = (opts->structVersion >= 30 * 4096) + ? opts->pzShortUsage : NULL; + + if (option_usage_fp == NULL) + option_usage_fp = stderr; + } + + if (((opts->fOptSet & OPTPROC_COMPUTE) == 0) && (pz != NULL)) { + if ((opts->fOptSet & OPTPROC_TRANSLATE) != 0) + optionPrintParagraphs(pz, true, option_usage_fp); + else + fputs(pz, option_usage_fp); + goto flush_and_exit; + } + } + + fprintf(option_usage_fp, opts->pzUsageTitle, opts->pzProgName); + + if ((exit_code == EXIT_SUCCESS) || + (! skip_misuse_usage(opts))) + + print_usage_details(opts, usage_exit_code); + else + print_offer_usage(opts); + + flush_and_exit: + fflush(option_usage_fp); + if (ferror(option_usage_fp) != 0) + fserr_exit(opts->pzProgName, zwriting, (option_usage_fp == stdout) + ? zstdout_name : zstderr_name); + + option_exits(exit_code); +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * PER OPTION TYPE USAGE INFORMATION + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * print option conflicts. + * + * @param opts the program option descriptor + * @param od the option descriptor + */ +static void +prt_conflicts(tOptions * opts, tOptDesc * od) +{ + const int * opt_no; + fputs(zTabHyp + tab_skip_ct, option_usage_fp); + + /* + * REQUIRED: + */ + if (od->pOptMust != NULL) { + opt_no = od->pOptMust; + + if (opt_no[1] == NO_EQUIVALENT) { + fprintf(option_usage_fp, zReqOne, + opts->pOptDesc[*opt_no].pz_Name); + } else { + fputs(zReqThese, option_usage_fp); + for (;;) { + fprintf(option_usage_fp, zTabout + tab_skip_ct, + opts->pOptDesc[*opt_no].pz_Name); + if (*++opt_no == NO_EQUIVALENT) + break; + } + } + + if (od->pOptCant != NULL) + fputs(zTabHypAnd + tab_skip_ct, option_usage_fp); + } + + /* + * CONFLICTS: + */ + if (od->pOptCant == NULL) + return; + + opt_no = od->pOptCant; + + if (opt_no[1] == NO_EQUIVALENT) { + fprintf(option_usage_fp, zProhibOne, + opts->pOptDesc[*opt_no].pz_Name); + return; + } + + fputs(zProhib, option_usage_fp); + for (;;) { + fprintf(option_usage_fp, zTabout + tab_skip_ct, + opts->pOptDesc[*opt_no].pz_Name); + if (*++opt_no == NO_EQUIVALENT) + break; + } +} + +/** + * Print the usage information for a single vendor option. + * + * @param[in] opts the program option descriptor + * @param[in] od the option descriptor + * @param[in] argtp names of the option argument types + * @param[in] usefmt format for primary usage line + */ +static void +prt_one_vendor(tOptions * opts, tOptDesc * od, + arg_types_t * argtp, char const * usefmt) +{ + prt_preamble(opts, od, argtp); + + { + char z[ 80 ]; + char const * pzArgType; + + /* + * Determine the argument type string first on its usage, then, + * when the option argument is required, base the type string on the + * argument type. + */ + if (od->fOptState & OPTST_ARG_OPTIONAL) { + pzArgType = argtp->pzOpt; + + } else switch (OPTST_GET_ARGTYPE(od->fOptState)) { + case OPARG_TYPE_NONE: pzArgType = argtp->pzNo; break; + case OPARG_TYPE_ENUMERATION: pzArgType = argtp->pzKey; break; + case OPARG_TYPE_FILE: pzArgType = argtp->pzFile; break; + case OPARG_TYPE_MEMBERSHIP: pzArgType = argtp->pzKeyL; break; + case OPARG_TYPE_BOOLEAN: pzArgType = argtp->pzBool; break; + case OPARG_TYPE_NUMERIC: pzArgType = argtp->pzNum; break; + case OPARG_TYPE_HIERARCHY: pzArgType = argtp->pzNest; break; + case OPARG_TYPE_STRING: pzArgType = argtp->pzStr; break; + case OPARG_TYPE_TIME: pzArgType = argtp->pzTime; break; + default: goto bogus_desc; + } + + pzArgType = SPN_WHITESPACE_CHARS(pzArgType); + if (*pzArgType == NUL) + snprintf(z, sizeof(z), "%s", od->pz_Name); + else + snprintf(z, sizeof(z), "%s=%s", od->pz_Name, pzArgType); + fprintf(option_usage_fp, usefmt, z, od->pzText); + + switch (OPTST_GET_ARGTYPE(od->fOptState)) { + case OPARG_TYPE_ENUMERATION: + case OPARG_TYPE_MEMBERSHIP: + displayEnum = (od->pOptProc != NULL) ? true : displayEnum; + } + } + + return; + + bogus_desc: + fprintf(stderr, zbad_od, opts->pzProgName, od->pz_Name); + ao_bug(zbad_arg_type_msg); +} + +/** + * Print the long options processed with "-W". These options will be the + * ones that do *not* have flag characters. + * + * @param opts the program option descriptor + * @param title the title for the options + */ +static void +prt_vendor_opts(tOptions * opts, char const * title) +{ + static unsigned int const not_vended_mask = + OPTST_NO_USAGE_MASK | OPTST_DOCUMENT; + + static char const vfmtfmt[] = "%%-%us %%s\n"; + char vfmt[sizeof(vfmtfmt)]; + + /* + * Only handle client specified options. The "vendor option" follows + * "presetOptCt", so we won't loop/recurse indefinitely. + */ + int ct = opts->presetOptCt; + tOptDesc * od = opts->pOptDesc; + fprintf(option_usage_fp, zTabout + tab_skip_ct, zVendOptsAre); + + { + size_t nmlen = 0; + do { + size_t l; + if ( ((od->fOptState & not_vended_mask) != 0) + || GRAPH_CH(od->optValue)) + continue; + + l = strlen(od->pz_Name); + if (l > nmlen) nmlen = l; + } while (od++, (--ct > 0)); + + snprintf(vfmt, sizeof(vfmt), vfmtfmt, (unsigned int)nmlen + 4); + } + + if (tab_skip_ct > 0) + tab_skip_ct--; + + ct = opts->presetOptCt; + od = opts->pOptDesc; + + do { + if ( ((od->fOptState & not_vended_mask) != 0) + || GRAPH_CH(od->optValue)) + continue; + + prt_one_vendor(opts, od, &argTypes, vfmt); + prt_extd_usage(opts, od, title); + + } while (od++, (--ct > 0)); + + /* no need to restore "tab_skip_ct" - options are done now */ +} + +/** + * Print extended usage. Usage/help was requested. + * + * @param opts the program option descriptor + * @param od the option descriptor + * @param title the title for the options + */ +static void +prt_extd_usage(tOptions * opts, tOptDesc * od, char const * title) +{ + if ( ((opts->fOptSet & OPTPROC_VENDOR_OPT) != 0) + && (od->optActualValue == VENDOR_OPTION_VALUE)) { + prt_vendor_opts(opts, title); + return; + } + + /* + * IF there are option conflicts or dependencies, + * THEN print them here. + */ + if ((od->pOptMust != NULL) || (od->pOptCant != NULL)) + prt_conflicts(opts, od); + + /* + * IF there is a disablement string + * THEN print the disablement info + */ + if (od->pz_DisableName != NULL ) + fprintf(option_usage_fp, zDis + tab_skip_ct, od->pz_DisableName); + + /* + * Check for argument types that have callbacks with magical properties + */ + switch (OPTST_GET_ARGTYPE(od->fOptState)) { + case OPARG_TYPE_NUMERIC: + /* + * IF the numeric option has a special callback, + * THEN call it, requesting the range or other special info + */ + if ( (od->pOptProc != NULL) + && (od->pOptProc != optionNumericVal) ) { + (*(od->pOptProc))(OPTPROC_EMIT_USAGE, od); + } + break; + + case OPARG_TYPE_FILE: + (*(od->pOptProc))(OPTPROC_EMIT_USAGE, od); + break; + } + + /* + * IF the option defaults to being enabled, + * THEN print that out + */ + if (od->fOptState & OPTST_INITENABLED) + fputs(zEnab + tab_skip_ct, option_usage_fp); + + /* + * IF the option is in an equivalence class + * AND not the designated lead + * THEN print equivalence and leave it at that. + */ + if ( (od->optEquivIndex != NO_EQUIVALENT) + && (od->optEquivIndex != od->optActualIndex ) ) { + fprintf(option_usage_fp, zalt_opt + tab_skip_ct, + opts->pOptDesc[ od->optEquivIndex ].pz_Name); + return; + } + + /* + * IF this particular option can NOT be preset + * AND some form of presetting IS allowed, + * AND it is not an auto-managed option (e.g. --help, et al.) + * THEN advise that this option may not be preset. + */ + if ( ((od->fOptState & OPTST_NO_INIT) != 0) + && ( (opts->papzHomeList != NULL) + || (opts->pzPROGNAME != NULL) + ) + && (od->optIndex < opts->presetOptCt) + ) + + fputs(zNoPreset + tab_skip_ct, option_usage_fp); + + /* + * Print the appearance requirements. + */ + if (OPTST_GET_ARGTYPE(od->fOptState) == OPARG_TYPE_MEMBERSHIP) + fputs(zMembers + tab_skip_ct, option_usage_fp); + + else switch (od->optMinCt) { + case 1: + case 0: + switch (od->optMaxCt) { + case 0: fputs(zPreset + tab_skip_ct, option_usage_fp); break; + case NOLIMIT: fputs(zNoLim + tab_skip_ct, option_usage_fp); break; + case 1: break; + /* + * IF the max is more than one but limited, print "UP TO" message + */ + default: + fprintf(option_usage_fp, zUpTo + tab_skip_ct, od->optMaxCt); break; + } + break; + + default: + /* + * More than one is required. Print the range. + */ + fprintf(option_usage_fp, zMust + tab_skip_ct, + od->optMinCt, od->optMaxCt); + } + + if ( NAMED_OPTS(opts) + && (opts->specOptIdx.default_opt == od->optIndex)) + fputs(zDefaultOpt + tab_skip_ct, option_usage_fp); +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Figure out where all the initialization files might live. This requires + * translating some environment variables and testing to see if a name is a + * directory or a file. It's squishy, but important to tell users how to + * find these files. + * + * @param[in] papz search path + * @param[out] ini_file an output buffer of AG_PATH_MAX+1 bytes + * @param[in] path_nm the name of the file we're hunting for + */ +static void +prt_ini_list(char const * const * papz, char const * ini_file, + char const * path_nm) +{ + char pth_buf[AG_PATH_MAX+1]; + + fputs(zPresetIntro, option_usage_fp); + + for (;;) { + char const * path = *(papz++); + char const * nm_buf = pth_buf; + + if (path == NULL) + break; + + /* + * Ignore any invalid paths + */ + if (! optionMakePath(pth_buf, (int)sizeof(pth_buf), path, path_nm)) + nm_buf = path; + + /* + * Expand paths that are relative to the executable or installation + * directories. Leave alone paths that use environment variables. + */ + else if ((*path == '$') + && ((path[1] == '$') || (path[1] == '@'))) + path = nm_buf; + + /* + * Print the name of the "homerc" file. If the "rcfile" name is + * not empty, we may or may not print that, too... + */ + fprintf(option_usage_fp, zPathFmt, path); + if (*ini_file != NUL) { + struct stat sb; + + /* + * IF the "homerc" file is a directory, + * then append the "rcfile" name. + */ + if ((stat(nm_buf, &sb) == 0) && S_ISDIR(sb.st_mode)) { + fputc(DIRCH, option_usage_fp); + fputs(ini_file, option_usage_fp); + } + } + + fputc(NL, option_usage_fp); + } +} + +/** + * Print the usage line preamble text + * + * @param opts the program option descriptor + * @param od the option descriptor + * @param at names of the option argument types + */ +static void +prt_preamble(tOptions * opts, tOptDesc * od, arg_types_t * at) +{ + /* + * Flag prefix: IF no flags at all, then omit it. If not printable + * (not allowed for this option), then blank, else print it. + * Follow it with a comma if we are doing GNU usage and long + * opts are to be printed too. + */ + if ((opts->fOptSet & OPTPROC_SHORTOPT) == 0) + fputs(at->pzSpc, option_usage_fp); + + else if (! GRAPH_CH(od->optValue)) { + if ( (opts->fOptSet & (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT)) + == (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT)) + fputc(' ', option_usage_fp); + fputs(at->pzNoF, option_usage_fp); + + } else { + fprintf(option_usage_fp, " -%c", od->optValue); + if ( (opts->fOptSet & (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT)) + == (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT)) + fputs(", ", option_usage_fp); + } +} + +/** + * Print the usage information for a single option. + * + * @param opts the program option descriptor + * @param od the option descriptor + * @param at names of the option argument types + */ +static void +prt_one_usage(tOptions * opts, tOptDesc * od, arg_types_t * at) +{ + prt_preamble(opts, od, at); + + { + char z[80]; + char const * atyp; + + /* + * Determine the argument type string first on its usage, then, + * when the option argument is required, base the type string on the + * argument type. + */ + if (od->fOptState & OPTST_ARG_OPTIONAL) { + atyp = at->pzOpt; + + } else switch (OPTST_GET_ARGTYPE(od->fOptState)) { + case OPARG_TYPE_NONE: atyp = at->pzNo; break; + case OPARG_TYPE_ENUMERATION: atyp = at->pzKey; break; + case OPARG_TYPE_FILE: atyp = at->pzFile; break; + case OPARG_TYPE_MEMBERSHIP: atyp = at->pzKeyL; break; + case OPARG_TYPE_BOOLEAN: atyp = at->pzBool; break; + case OPARG_TYPE_NUMERIC: atyp = at->pzNum; break; + case OPARG_TYPE_HIERARCHY: atyp = at->pzNest; break; + case OPARG_TYPE_STRING: atyp = at->pzStr; break; + case OPARG_TYPE_TIME: atyp = at->pzTime; break; + default: goto bogus_desc; + } + +#ifdef _WIN32 + if (at->pzOptFmt == zGnuOptFmt) + snprintf(z, sizeof(z), "--%s%s", od->pz_Name, atyp); + else if (at->pzOptFmt == zGnuOptFmt + 2) + snprintf(z, sizeof(z), "%s%s", od->pz_Name, atyp); + else +#endif + snprintf(z, sizeof(z), at->pzOptFmt, atyp, od->pz_Name, + (od->optMinCt != 0) ? at->pzReq : at->pzOpt); + + fprintf(option_usage_fp, line_fmt_buf, z, od->pzText); + + switch (OPTST_GET_ARGTYPE(od->fOptState)) { + case OPARG_TYPE_ENUMERATION: + case OPARG_TYPE_MEMBERSHIP: + displayEnum = (od->pOptProc != NULL) ? true : displayEnum; + } + } + + return; + + bogus_desc: + fprintf(stderr, zbad_od, opts->pzProgName, od->pz_Name); + option_exits(EX_SOFTWARE); +} + +/** + * Print out the usage information for just the options. + */ +static void +prt_opt_usage(tOptions * opts, int ex_code, char const * title) +{ + int ct = opts->optCt; + int optNo = 0; + tOptDesc * od = opts->pOptDesc; + int docCt = 0; + + do { + /* + * no usage --> disallowed on command line (OPTST_NO_COMMAND), or + * deprecated -- strongly discouraged (OPTST_DEPRECATED), or + * compiled out of current object code (OPTST_OMITTED) + */ + if ((od->fOptState & OPTST_NO_USAGE_MASK) != 0) { + + /* + * IF this is a compiled-out option + * *AND* usage was requested with "omitted-usage" + * *AND* this is NOT abbreviated usage + * THEN display this option. + */ + if ( (od->fOptState == (OPTST_OMITTED | OPTST_NO_INIT)) + && (od->pz_Name != NULL) + && (ex_code == EXIT_SUCCESS)) { + + char const * why_pz = + (od->pzText == NULL) ? zDisabledWhy : od->pzText; + prt_preamble(opts, od, &argTypes); + fprintf(option_usage_fp, zDisabledOpt, od->pz_Name, why_pz); + } + + continue; + } + + if ((od->fOptState & OPTST_DOCUMENT) != 0) { + if (ex_code == EXIT_SUCCESS) { + fprintf(option_usage_fp, argTypes.pzBrk, od->pzText, + title); + docCt++; + } + + continue; + } + + /* Skip name only options when we have a vendor option */ + if ( ((opts->fOptSet & OPTPROC_VENDOR_OPT) != 0) + && (! GRAPH_CH(od->optValue))) + continue; + + /* + * IF this is the first auto-opt maintained option + * *AND* we are doing a full help + * *AND* there are documentation options + * *AND* the last one was not a doc option, + * THEN document that the remaining options are not user opts + */ + if ((docCt > 0) && (ex_code == EXIT_SUCCESS)) { + if (opts->presetOptCt == optNo) { + if ((od[-1].fOptState & OPTST_DOCUMENT) == 0) + fprintf(option_usage_fp, argTypes.pzBrk, zAuto, title); + + } else if ((ct == 1) && + (opts->fOptSet & OPTPROC_VENDOR_OPT)) + fprintf(option_usage_fp, argTypes.pzBrk, zVendIntro, title); + } + + prt_one_usage(opts, od, &argTypes); + + /* + * IF we were invoked because of the --help option, + * THEN print all the extra info + */ + if (ex_code == EXIT_SUCCESS) + prt_extd_usage(opts, od, title); + + } while (od++, optNo++, (--ct > 0)); + + fputc(NL, option_usage_fp); +} + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Print program details. + * @param[in] opts the program option descriptor + */ +static void +prt_prog_detail(tOptions * opts) +{ + bool need_intro = (opts->papzHomeList == NULL); + + /* + * Display all the places we look for config files, if we have + * a list of directories to search. + */ + if (! need_intro) + prt_ini_list(opts->papzHomeList, opts->pzRcName, opts->pzProgPath); + + /* + * Let the user know about environment variable settings + */ + if ((opts->fOptSet & OPTPROC_ENVIRON) != 0) { + if (need_intro) + fputs(zPresetIntro, option_usage_fp); + + fprintf(option_usage_fp, zExamineFmt, opts->pzPROGNAME); + } + + /* + * IF we found an enumeration, + * THEN hunt for it again. Call the handler proc with a NULL + * option struct pointer. That tells it to display the keywords. + */ + if (displayEnum) { + int ct = opts->optCt; + int optNo = 0; + tOptDesc * od = opts->pOptDesc; + + fputc(NL, option_usage_fp); + fflush(option_usage_fp); + do { + switch (OPTST_GET_ARGTYPE(od->fOptState)) { + case OPARG_TYPE_ENUMERATION: + case OPARG_TYPE_MEMBERSHIP: + (*(od->pOptProc))(OPTPROC_EMIT_USAGE, od); + } + } while (od++, optNo++, (--ct > 0)); + } + + /* + * If there is a detail string, now is the time for that. + */ + if (opts->pzDetail != NULL) + fputs(opts->pzDetail, option_usage_fp); +} + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * OPTION LINE FORMATTING SETUP + * + * The "OptFmt" formats receive three arguments: + * 1. the type of the option's argument + * 2. the long name of the option + * 3. "YES" or "no ", depending on whether or not the option must appear + * on the command line. + * These formats are used immediately after the option flag (if used) has + * been printed. + * + * Set up the formatting for GNU-style output + */ +static int +setGnuOptFmts(tOptions * opts, char const ** ptxt) +{ + static char const zOneSpace[] = " "; + int flen = 22; + *ptxt = zNoRq_ShrtTtl; + + argTypes.pzStr = zGnuStrArg; + argTypes.pzReq = zOneSpace; + argTypes.pzNum = zGnuNumArg; + argTypes.pzKey = zGnuKeyArg; + argTypes.pzKeyL = zGnuKeyLArg; + argTypes.pzTime = zGnuTimeArg; + argTypes.pzFile = zGnuFileArg; + argTypes.pzBool = zGnuBoolArg; + argTypes.pzNest = zGnuNestArg; + argTypes.pzOpt = zGnuOptArg; + argTypes.pzNo = zOneSpace; + argTypes.pzBrk = zGnuBreak; + argTypes.pzNoF = zSixSpaces; + argTypes.pzSpc = zThreeSpaces; + + switch (opts->fOptSet & OPTPROC_L_N_S) { + case OPTPROC_L_N_S: argTypes.pzOptFmt = zGnuOptFmt; break; + case OPTPROC_LONGOPT: argTypes.pzOptFmt = zGnuOptFmt; break; + case 0: argTypes.pzOptFmt = zGnuOptFmt + 2; break; + case OPTPROC_SHORTOPT: + argTypes.pzOptFmt = zShrtGnuOptFmt; + zGnuStrArg[0] = zGnuNumArg[0] = zGnuKeyArg[0] = zGnuBoolArg[0] = ' '; + argTypes.pzOpt = " [arg]"; + flen = 8; + break; + } + + return flen; +} + + +/* + * Standard (AutoOpts normal) option line formatting + */ +static int +setStdOptFmts(tOptions * opts, char const ** ptxt) +{ + int flen = 0; + + argTypes.pzStr = zStdStrArg; + argTypes.pzReq = zStdReqArg; + argTypes.pzNum = zStdNumArg; + argTypes.pzKey = zStdKeyArg; + argTypes.pzKeyL = zStdKeyLArg; + argTypes.pzTime = zStdTimeArg; + argTypes.pzFile = zStdFileArg; + argTypes.pzBool = zStdBoolArg; + argTypes.pzNest = zStdNestArg; + argTypes.pzOpt = zStdOptArg; + argTypes.pzNo = zStdNoArg; + argTypes.pzBrk = zStdBreak; + argTypes.pzNoF = zFiveSpaces; + argTypes.pzSpc = zTwoSpaces; + + switch (opts->fOptSet & (OPTPROC_NO_REQ_OPT | OPTPROC_SHORTOPT)) { + case (OPTPROC_NO_REQ_OPT | OPTPROC_SHORTOPT): + *ptxt = zNoRq_ShrtTtl; + argTypes.pzOptFmt = zNrmOptFmt; + flen = 19; + break; + + case OPTPROC_NO_REQ_OPT: + *ptxt = zNoRq_NoShrtTtl; + argTypes.pzOptFmt = zNrmOptFmt; + flen = 19; + break; + + case OPTPROC_SHORTOPT: + *ptxt = zReq_ShrtTtl; + argTypes.pzOptFmt = zReqOptFmt; + flen = 24; + break; + + case 0: + *ptxt = zReq_NoShrtTtl; + argTypes.pzOptFmt = zReqOptFmt; + flen = 24; + } + + return flen; +} + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/usage.c */ diff --git a/autoopts/version.c b/autoopts/version.c new file mode 100644 index 0000000..cd46be3 --- /dev/null +++ b/autoopts/version.c @@ -0,0 +1,240 @@ + +/** \file version.c + * + * This module implements the default usage procedure for + * Automated Options. It may be overridden, of course. + * + * @addtogroup autoopts + * @{ + */ +/* + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +/*=export_func optionVersion + * + * what: return the compiled AutoOpts version number + * ret_type: char const * + * ret_desc: the version string in constant memory + * doc: + * Returns the full version string compiled into the library. + * The returned string cannot be modified. +=*/ +char const * +optionVersion(void) +{ + static char const ver[] = OPTIONS_DOTTED_VERSION; + return ver; +} + +static void +emit_first_line( + FILE * fp, char const * alt1, char const * alt2, char const * alt3) +{ + char const * p = (alt1 != NULL) ? alt1 : ((alt2 != NULL) ? alt2 : alt3); + char const * e; + if (p == NULL) + return; + e = strchr(p, NL); + if (e == NULL) + fputs(p, fp); + else + fwrite(p, 1, (e - p), fp); + fputc(NL, fp); +} + +/** + * Select among various ways to emit version information. + * + * @param[in] o the option descriptor + * @param[in] fp the output stream + */ +static void +emit_simple_ver(tOptions * o, FILE * fp) +{ + emit_first_line(fp, o->pzFullVersion, o->pzCopyright, o->pzUsageTitle); +} + +/** + * print the version with a copyright notice. + * + * @param[in] o the option descriptor + * @param[in] fp the output stream + */ +static void +emit_copy_full(tOptions * o, FILE * fp) +{ + if (o->pzCopyright != NULL) + fputs(o->pzCopyright, fp); + + else if (o->pzFullVersion != NULL) + fputs(o->pzFullVersion, fp); + + else + emit_first_line(fp, o->pzUsageTitle, NULL, NULL); + + if (HAS_pzPkgDataDir(o) && (o->pzPackager != NULL)) { + fputc(NL, fp); + fputs(o->pzPackager, fp); + + } else if (o->pzBugAddr != NULL) { + fputc(NL, fp); + fprintf(fp, zPlsSendBugs, o->pzBugAddr); + } +} + +/** + * print the version and any copyright notice. + * The version with a full copyright and additional notes. + * + * @param[in] opts the option descriptor + * @param[in] fp the output stream + */ +static void +emit_copy_note(tOptions * opts, FILE * fp) +{ + if (opts->pzCopyright != NULL) + fputs(opts->pzCopyright, fp); + + if (opts->pzCopyNotice != NULL) + fputs(opts->pzCopyNotice, fp); + + fputc(NL, fp); + fprintf(fp, zao_ver_fmt, optionVersion()); + + if (HAS_pzPkgDataDir(opts) && (opts->pzPackager != NULL)) { + fputc(NL, fp); + fputs(opts->pzPackager, fp); + + } else if (opts->pzBugAddr != NULL) { + fputc(NL, fp); + fprintf(fp, zPlsSendBugs, opts->pzBugAddr); + } +} + +/** + * Handle the version printing. We must see how much information + * is being requested and select the correct printing routine. + */ +static void +print_ver(tOptions * opts, tOptDesc * od, FILE * fp, bool call_exit) +{ + char ch; + + if (opts <= OPTPROC_EMIT_LIMIT) + return; + + /* + * IF we have an argument for this option, use it + * Otherwise, default to version only or copyright note, + * depending on whether the layout is GNU standard form or not. + */ + if ( (od->fOptState & OPTST_ARG_OPTIONAL) + && (od->optArg.argString != NULL) + && (od->optArg.argString[0] != NUL)) + + ch = od->optArg.argString[0]; + + else if (OPTST_GET_ARGTYPE(od->fOptState) == OPARG_TYPE_STATIC) { + ch = od->optArg.argString[0]; + + } else { + set_usage_flags(opts, NULL); + ch = (opts->fOptSet & OPTPROC_GNUUSAGE) ? 'c' : 'v'; + } + + switch (ch) { + case NUL: /* arg provided, but empty */ + case 'v': case 'V': emit_simple_ver(opts, fp); break; + case 'c': case 'C': emit_copy_full( opts, fp); break; + case 'n': case 'N': emit_copy_note( opts, fp); break; + + default: + fprintf(stderr, zBadVerArg, ch); + option_exits(EXIT_FAILURE); + } + + fflush(fp); + if (ferror(fp)) + fserr_exit(opts->pzProgName, zwriting, + (fp == stdout) ? zstdout_name : zstderr_name); + + if (call_exit) + option_exits(EXIT_SUCCESS); +} + +/*=export_func optionPrintVersion + * + * what: Print the program version + * arg: + tOptions * + opts + program options descriptor + + * arg: + tOptDesc * + od + the descriptor for this arg + + * + * doc: + * This routine will print the version to stdout. +=*/ +void +optionPrintVersion(tOptions * opts, tOptDesc * od) +{ + print_ver(opts, od, print_exit ? stderr : stdout, true); +} + +/*=export_func optionPrintVersionAndReturn + * + * what: Print the program version + * arg: + tOptions * + opts + program options descriptor + + * arg: + tOptDesc * + od + the descriptor for this arg + + * + * doc: + * This routine will print the version to stdout and return + * instead of exiting. Please see the source for the + * @code{print_ver} funtion for details on selecting how + * verbose to be after this function returns. +=*/ +void +optionPrintVersionAndReturn(tOptions * opts, tOptDesc * od) +{ + print_ver(opts, od, print_exit ? stderr : stdout, false); +} + +/*=export_func optionVersionStderr + * private: + * + * what: Print the program version to stderr + * arg: + tOptions * + opts + program options descriptor + + * arg: + tOptDesc * + od + the descriptor for this arg + + * + * doc: + * This routine will print the version to stderr. +=*/ +void +optionVersionStderr(tOptions * opts, tOptDesc * od) +{ + print_ver(opts, od, stderr, true); +} + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of autoopts/version.c */ diff --git a/build-aux/run-ag.sh b/build-aux/run-ag.sh new file mode 100644 index 0000000..6ee7b85 --- /dev/null +++ b/build-aux/run-ag.sh @@ -0,0 +1,89 @@ +#! /bin/bash +## run-ag.sh -- shell script for running autogen within autogen build +## +## Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . +## --------------------------------------------------------------------- +# +# If the first argument ends with *-dep.mk, then it is expected that this +# script has been called in the Makefile building phase and the target and +# any containing directory must be created. The target is created with a +# very old time stamp. +# +AGexe=/u/bkorb/tools/ag/autogen-bld/agen5/.libs/autogen +find_exe() { + eval local exe=\${$1} + test -x "$exe" && return 0 + case "$2" in + autogen ) exe=`cd ../agen5 > /dev/null ; pwd`/$2 ;; + columns ) exe=`cd ../columns > /dev/null ; pwd`/$2 ;; + + * ) echo "wrong executable: '$2'" >&2 + exit 1 ;; + esac + test -x "$exe" || exe=`command -v $2` + test -x "$exe" || { + echo "cannot locate $2" + return 1 + } 1>&2 + eval $1=$exe + return 0 +} + +STAMP_TEMP_DIR=$(mktemp --suffix=.tdir -d /tmp/run-ag-XXXXXXXX) +exec 9>&2 2>> ${STAMP_TEMP_DIR}/mk-stamps.log +VERBOSE=1 + +test "X$VERBOSE" = X1 && { + PS4='+run-ag-$LINENO> ' + set -x + : in $PWD +} + +stamp_file='' +case "$1" in + -MF*-dep.mk ) : ;; + + *-dep.mk ) + dir=`dirname "$1"` + test -d "$dir" || mkdir -p "$dir" || exit 1 + touch -t 197001020000 "$1" + exit $? + ;; + + '' ) exit 1 ;; +esac + +test -x "$AGexe" || find_exe AGexe autogen +test -x "CLexe" || find_exe CLexe columns +PATH=`dirname "$CLexe"`:"$PATH" +L_opt="-L'${top_srcdir}/autoopts/tpl'" +test "X${top_srcdir}" = "X${top_builddir}" || \ + L_opt="$L_opt -L'${top_builddir}/autoopts/tpl'" + +eval "${AGexe}" $L_opt '"$@"' +exit $? + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# END OF add-on/build-aux/mk-ag-dep.sh diff --git a/columns/Makefile.am b/columns/Makefile.am new file mode 100644 index 0000000..f6e77cc --- /dev/null +++ b/columns/Makefile.am @@ -0,0 +1,74 @@ +## -*- Mode: Makefile -*- +## +## Makefile.am -- process this file with automake to produce Makefile.in +## +## Copyright (C) 1992-2018 by Bruce Korb +## +## This file is part of AutoGen. +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . + +bin_PROGRAMS = columns +columns_LDFLAGS = -no-install +csrc = opts.h columns.c opts.c +nodist_columns_SOURCES = cols.c + +LO_LIB = $(top_builddir)/autoopts/libopts.la +columns_LDADD = $(LO_LIB) $(GUILE_LIBS) + +BUILT_SOURCES = columns.menu columns.texi columns.1 +EXTRA_DIST = opts.def $(csrc) + +RUNAG = $(AGexe) -L$(top_srcdir)/autoopts/tpl \ + -L$(top_builddir)/autoopts/tpl -MF$@ +man_MANS = columns.1 + +AM_CPPFLAGS = @INCLIST@ + +CONFIG_CLEAN_FILES = $(BUILT_SOURCES) stamp-* +MAINTAINERCLEANFILES = $(CONFIG_CLEAN_FILES) +DISTCLEANFILES = cols.c +DOC_TIMEOUT = -DLEVEL=section --timeout=`expr $(AG_TIMEOUT) '*' 3` + +gen : $(BUILT_SOURCES) + +all : gen + +## opts.h cannot be built until columns is built, so no rules for it. + +columns.menu columns.texi : stamp-agtexi +columns.1 : stamp-agman + +cols.c : Makefile + exec > $@ ; \ + echo '#undef PKGDATADIR' ; \ + echo '#define PKGDATADIR "$(pkgdatadir)"' ; \ + echo ; echo '#define DEFINING 1' ; \ + echo '#include "autoopts/project.h"' ; \ + for f in $(csrc) ; do echo "#include \"$$f\"" ; done + +$(LO_LIB) : + ( cd $(top_builddir)/autoopts ; $(MAKE) libopts.la ) + +stamp-agtexi : opts.def columns$(EXEEXT) + top_builddir=$(top_builddir) \ + $(RUNAG) -Tagtexi-cmd.tpl $(DOC_TIMEOUT) $(srcdir)/opts.def + +stamp-agman : opts.def columns$(EXEEXT) + top_builddir=$(top_builddir) \ + $(RUNAG) -Tagman-cmd.tpl $(srcdir)/opts.def + +.NOTPARALLEL: + +# end of Makefile.am diff --git a/columns/Makefile.in b/columns/Makefile.in new file mode 100644 index 0000000..8da74c6 --- /dev/null +++ b/columns/Makefile.in @@ -0,0 +1,831 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 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. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +bin_PROGRAMS = columns$(EXEEXT) +subdir = columns +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/ag_macros.m4 \ + $(top_srcdir)/config/asm-underscore.m4 \ + $(top_srcdir)/config/extensions.m4 \ + $(top_srcdir)/config/guile.m4 \ + $(top_srcdir)/config/host-cpu-c-abi.m4 \ + $(top_srcdir)/config/lib-ld.m4 \ + $(top_srcdir)/config/lib-link.m4 \ + $(top_srcdir)/config/lib-prefix.m4 \ + $(top_srcdir)/config/libopts.m4 \ + $(top_srcdir)/config/libtool.m4 \ + $(top_srcdir)/config/ltoptions.m4 \ + $(top_srcdir)/config/ltsugar.m4 \ + $(top_srcdir)/config/ltversion.m4 \ + $(top_srcdir)/config/lt~obsolete.m4 \ + $(top_srcdir)/config/onceonly.m4 $(top_srcdir)/config/pkg.m4 \ + $(top_srcdir)/config/snprintfv.m4 \ + $(top_srcdir)/config/stdnoreturn.m4 \ + $(top_srcdir)/config/unlocked-io.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" +PROGRAMS = $(bin_PROGRAMS) +nodist_columns_OBJECTS = cols.$(OBJEXT) +columns_OBJECTS = $(nodist_columns_OBJECTS) +am__DEPENDENCIES_1 = +columns_DEPENDENCIES = $(LO_LIB) $(am__DEPENDENCIES_1) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +columns_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(columns_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/config/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/cols.Po +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(nodist_columns_SOURCES) +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +man1dir = $(mandir)/man1 +NROFF = nroff +MANS = $(man_MANS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/config/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AGEN5_TESTS = @AGEN5_TESTS@ +AG_LDFLAGS = @AG_LDFLAGS@ +AG_MAJOR_VERSION = @AG_MAJOR_VERSION@ +AG_MINOR_VERSION = @AG_MINOR_VERSION@ +AG_STATIC_AUTOGEN = @AG_STATIC_AUTOGEN@ +AG_TIMEOUT = @AG_TIMEOUT@ +AG_VERSION = @AG_VERSION@ +AG_XML2 = @AG_XML2@ +AGexe = @AGexe@ +AGnam = @AGnam@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AO_AGE = @AO_AGE@ +AO_CURRENT = @AO_CURRENT@ +AO_REVISION = @AO_REVISION@ +AO_TEMPLATE_VERSION = @AO_TEMPLATE_VERSION@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLexe = @CLexe@ +CLnam = @CLnam@ +CONFIG_SHELL = @CONFIG_SHELL@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBUG_ENABLED = @DEBUG_ENABLED@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +DYNAMIC_AG = @DYNAMIC_AG@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_STATIC = @ENABLE_STATIC@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GDexe = @GDexe@ +GDnam = @GDnam@ +GO_AGE = @GO_AGE@ +GO_CURRENT = @GO_CURRENT@ +GO_REVISION = @GO_REVISION@ +GREP = @GREP@ +GUILE_CFLAGS = @GUILE_CFLAGS@ +GUILE_EFFECTIVE_VERSION = @GUILE_EFFECTIVE_VERSION@ +GUILE_LDFLAGS = @GUILE_LDFLAGS@ +GUILE_LIBS = @GUILE_LIBS@ +GUILE_LTLIBS = @GUILE_LTLIBS@ +HOST_CPU = @HOST_CPU@ +HOST_CPU_C_ABI = @HOST_CPU_C_ABI@ +INCLIST = @INCLIST@ +INCSNPRINTFV = @INCSNPRINTFV@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSNPRINTFV = @LIBSNPRINTFV@ +LIBTOOL = @LIBTOOL@ +LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ +LIBXML2_LIBS = @LIBXML2_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +M4_SRC = @M4_SRC@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPTS_TESTDIR = @OPTS_TESTDIR@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSIX_SHELL = @POSIX_SHELL@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STDNORETURN_H = @STDNORETURN_H@ +STRIP = @STRIP@ +TEXI2HTML = @TEXI2HTML@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_aux_dir = @ac_aux_dir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +columns_LDFLAGS = -no-install +csrc = opts.h columns.c opts.c +nodist_columns_SOURCES = cols.c +LO_LIB = $(top_builddir)/autoopts/libopts.la +columns_LDADD = $(LO_LIB) $(GUILE_LIBS) +BUILT_SOURCES = columns.menu columns.texi columns.1 +EXTRA_DIST = opts.def $(csrc) +RUNAG = $(AGexe) -L$(top_srcdir)/autoopts/tpl \ + -L$(top_builddir)/autoopts/tpl -MF$@ + +man_MANS = columns.1 +AM_CPPFLAGS = @INCLIST@ +CONFIG_CLEAN_FILES = $(BUILT_SOURCES) stamp-* +MAINTAINERCLEANFILES = $(CONFIG_CLEAN_FILES) +DISTCLEANFILES = cols.c +DOC_TIMEOUT = -DLEVEL=section --timeout=`expr $(AG_TIMEOUT) '*' 3` +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu columns/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu columns/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p \ + || test -f $$p1 \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' \ + `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +columns$(EXEEXT): $(columns_OBJECTS) $(columns_DEPENDENCIES) $(EXTRA_columns_DEPENDENCIES) + @rm -f columns$(EXEEXT) + $(AM_V_CCLD)$(columns_LINK) $(columns_OBJECTS) $(columns_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cols.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-man1: $(man_MANS) + @$(NORMAL_INSTALL) + @list1=''; \ + list2='$(man_MANS)'; \ + test -n "$(man1dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.1[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ + done; } + +uninstall-man1: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man1dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.1[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-am +all-am: Makefile $(PROGRAMS) $(MANS) +installdirs: + for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/cols.Po + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-man + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-binPROGRAMS + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: install-man1 + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/cols.Po + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-man + +uninstall-man: uninstall-man1 + +.MAKE: all check install install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-binPROGRAMS clean-generic clean-libtool cscopelist-am \ + ctags ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-binPROGRAMS \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-man1 \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags tags-am uninstall uninstall-am \ + uninstall-binPROGRAMS uninstall-man uninstall-man1 + +.PRECIOUS: Makefile + + +gen : $(BUILT_SOURCES) + +all : gen + +columns.menu columns.texi : stamp-agtexi +columns.1 : stamp-agman + +cols.c : Makefile + exec > $@ ; \ + echo '#undef PKGDATADIR' ; \ + echo '#define PKGDATADIR "$(pkgdatadir)"' ; \ + echo ; echo '#define DEFINING 1' ; \ + echo '#include "autoopts/project.h"' ; \ + for f in $(csrc) ; do echo "#include \"$$f\"" ; done + +$(LO_LIB) : + ( cd $(top_builddir)/autoopts ; $(MAKE) libopts.la ) + +stamp-agtexi : opts.def columns$(EXEEXT) + top_builddir=$(top_builddir) \ + $(RUNAG) -Tagtexi-cmd.tpl $(DOC_TIMEOUT) $(srcdir)/opts.def + +stamp-agman : opts.def columns$(EXEEXT) + top_builddir=$(top_builddir) \ + $(RUNAG) -Tagman-cmd.tpl $(srcdir)/opts.def + +.NOTPARALLEL: + +# end of Makefile.am + +# 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/columns/columns.c b/columns/columns.c new file mode 100644 index 0000000..e1a4725 --- /dev/null +++ b/columns/columns.c @@ -0,0 +1,741 @@ + +/** + * @file columns.c + * @group columns + * @{ + */ +/* + * Columns Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * Columns is free software. + * This file is part of AutoGen. + * + * AutoGen Copyright (C) 1992-2017 by Bruce Korb - all rights reserved + * + * AutoGen is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AutoGen is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ +#ifndef NUL +# define NUL '\0' +#endif + +struct print_list { + char ** papz; + int index; +}; + +typedef struct print_list tPrintList, *tpPrintList; + +int maxEntryWidth = 0; +int fillColumnCt = 0; + +#define LINE_LIMIT 4096 +char zLine[ LINE_LIMIT ]; +char zFmtLine[ LINE_LIMIT ]; + +char ** papzLines = (char **)NULL; +char const * pzLinePfx = ""; +char const * pzFirstPfx = NULL; +size_t allocCt = 0; +size_t usedCt = 0; +size_t columnCt = 0; +size_t columnSz = 0; +size_t indentSize = 0; + +MOD_LOCAL inline void * +malloc_or_die(size_t sz); +MOD_LOCAL char const * +construct_first_pfx(char const * f_indent); +MOD_LOCAL uint32_t +pad_indentation(char const * pzIndentArg, char const ** pfx); +MOD_LOCAL void +readLines(void); +MOD_LOCAL void +writeColumns(void); +MOD_LOCAL void +trim_last_separation(void); +MOD_LOCAL void +writeRows(void); +MOD_LOCAL int +emitWord(char const * word, size_t len, int col); +MOD_LOCAL void +writeFill(void); +MOD_LOCAL int +compProc(const void * p1, const void * p2); + +int +main(int argc, char ** argv) +{ + (void)optionProcess( &columnsOptions, argc, argv ); + + if (HAVE_OPT( INDENT )) { + indentSize = pad_indentation( OPT_ARG(INDENT), &pzLinePfx); + OPT_VALUE_WIDTH -= (long)indentSize; + + pzFirstPfx = HAVE_OPT(FIRST_INDENT) + ? construct_first_pfx( OPT_ARG(FIRST_INDENT)) + : pzLinePfx; + } + + if (HAVE_OPT( LINE_SEPARATION )) + OPT_VALUE_WIDTH -= (long int)strlen( OPT_ARG( LINE_SEPARATION)); + + if (HAVE_OPT( COL_WIDTH )) + columnSz = (size_t)OPT_VALUE_COL_WIDTH; + + if (HAVE_OPT( COLUMNS )) + columnCt = (size_t)OPT_VALUE_COLUMNS; + + if (OPT_VALUE_WIDTH <= 16) + OPT_VALUE_WIDTH = 16; + + readLines(); + + if (HAVE_OPT( SORT )) + qsort(VOIDP(papzLines), usedCt, sizeof(char *), &compProc); + + if (HAVE_OPT( BY_COLUMNS )) + writeColumns(); + else if (HAVE_OPT(FILL)) + writeFill(); + else + writeRows(); + + return EXIT_SUCCESS; +} + +MOD_LOCAL inline void * +malloc_or_die(size_t sz) +{ + void * res = malloc(sz); + if (res == NULL) + die(COLUMNS_EXIT_FAILURE, "could not allocate %d bytes", sz); + + return res; +} + +MOD_LOCAL char const * +construct_first_pfx(char const * f_indent) +{ + static char const pad_fmt[] = "%%-%ds"; + // 24 > log10(0xFFFFFFFFFFFFFFFFULL) + char pfx_buf[24 + sizeof(pad_fmt)]; + size_t firstSize = pad_indentation(f_indent, &pzFirstPfx); + size_t len; + char * res; + + /* + * If this first line exceeds the indentation size, then we + * need to append a newline and any indentation. + */ + if (firstSize > indentSize) { + size_t sep_len = HAVE_OPT(LINE_SEPARATION) + ? strlen( OPT_ARG(LINE_SEPARATION)) : 0; + len = firstSize + sep_len + indentSize + 3; + sprintf(pfx_buf, pad_fmt, (int)firstSize); + } else { + len = indentSize + 3; + sprintf(pfx_buf, pad_fmt, (int)indentSize); + } + + res = malloc_or_die(len); + snprintf(res, len, pfx_buf, pzFirstPfx); + pzFirstPfx = res; + + if (firstSize > indentSize) { + char * p = res + firstSize; + + if (HAVE_OPT( LINE_SEPARATION )) { + len = strlen(OPT_ARG(LINE_SEPARATION)); + memcpy(p, OPT_ARG(LINE_SEPARATION), len); + p += len; + } + + sprintf(p, "\n%s", pzLinePfx); + } + + return res; +} + +MOD_LOCAL uint32_t +pad_indentation(char const * pzIndentArg, char const ** pfx) +{ + char * pz; + unsigned int cct; + + errno = 0; + cct = (unsigned int)strtoul(pzIndentArg, &pz, 0); + + /* + * IF the indent argument is a number + */ + if ((*pz == NUL) && (errno == 0) && (cct < OPT_VALUE_WIDTH)) { + char * p; + + /* + * Allocate a string to hold the line prefix + */ + *pfx = p = malloc_or_die( (size_t)cct + 1 ); + + /* + * Set it to a NUL terminated string of spaces + */ + if (cct > 0) + memset(p, ' ', (size_t)cct); + p[cct] = NUL; + + } else { + /* + * Otherwise, set the line prefix to whatever the string is. + * It will not be the empty string because that is handled + * as an indent count of zero and is ignored. + */ + char const * p = pzIndentArg; + *pfx = pzIndentArg; + cct = 0; + + for (;;) { + /* + * Compute the length of the last line of the prefix. + */ + switch (*p++) { + case NUL: + goto colsCounted; + + case '\t': + cct += (unsigned)OPT_VALUE_TAB_WIDTH; + cct -= (unsigned)(cct % OPT_VALUE_TAB_WIDTH); + break; + + case '\n': + case '\f': + case '\r': + cct = 0; + break; + + default: + cct++; + break; + + case '\a': + break; + } + } colsCounted:; + } + + return cct; +} + +MOD_LOCAL void +readLines(void) +{ + int sepLen = HAVE_OPT(SEPARATION) + ? (int)strlen(OPT_ARG(SEPARATION)) : 0; + + /* + * Read the input text, stripping trailing white space + */ + for (;;) { + char * pzL; + char * pzText = fgets(zLine, (int)sizeof(zLine), stdin); + size_t len; + + if (pzText == NULL) + break; + + /* + * Trim off trailing white space. + */ + len = strlen( pzText ); + pzText += len; + while (isspace(pzText[-1])) { + if (--pzText == zLine) { + if (HAVE_OPT(FILL)) + break; + goto next_line; + } + len--; + } + + *pzText = NUL; + + /* + * IF the input lines are to be reformatted, + * THEN the length is the result of the sprintf + * Else, compute the length. + */ + if (HAVE_OPT(FORMAT)) { + pzText = zFmtLine; + len = (size_t)snprintf( + zFmtLine, sizeof(zFmtLine), OPT_ARG(FORMAT), zLine); + } else { + pzText = zLine; + } + + /* + * Allocate a string and space in the pointer array. + */ + len += (size_t)sepLen + 1; + pzL = (char *)malloc_or_die( len ); + if (++usedCt > allocCt) { + allocCt += 128; + papzLines = (char **)realloc(VOIDP(papzLines), + sizeof(char *) * allocCt ); + } + papzLines[ usedCt-1 ] = pzL; + + /* + * Copy the text and append the separation character + */ + strcpy( pzL, pzText ); + + /* + * Initially, all strings have the separator, + * the entries may get reordered. + */ + if (sepLen > 0) + strcat(pzL, OPT_ARG(SEPARATION)); + + if ((int)len > maxEntryWidth) + maxEntryWidth = (int)len; + next_line:; + } + + if (maxEntryWidth == 0) { + fputs( "columns warning: no input text was read\n", stderr ); + exit( EXIT_SUCCESS ); + } + + /* + * Set the line width to the amount of space we have to play with. + */ + if ((OPT_VALUE_WIDTH < maxEntryWidth) && (! HAVE_OPT(FILL))) + OPT_VALUE_WIDTH = maxEntryWidth; + + /* + * If we do not have a column size set, + * then figure out what it must be. + */ + if (columnSz == 0) { + /* + * IF the column count has not been set, + * THEN compute it. + */ + if (columnCt == 0) + columnCt = (size_t)(OPT_VALUE_WIDTH / maxEntryWidth); + + /* + * IF there are to be multiple columns, ... + */ + if (columnCt > 1) { + size_t spreadwidth = (size_t)(OPT_VALUE_WIDTH - maxEntryWidth); + int sz = (int)(spreadwidth / (size_t)(columnCt-1)); + + /* + * Either there is room for added space, + * or we must (possibly) reduce the number of columns + */ + if (sz >= maxEntryWidth) + columnSz = (size_t)sz; + else { + columnCt = ((size_t)spreadwidth / (size_t)maxEntryWidth) + 1; + if (columnCt > 1) + columnSz = (size_t)spreadwidth / (size_t)(columnCt - 1); + else columnSz = (size_t)OPT_VALUE_WIDTH; + } + } + } + + /* + * Otherwise, the column size has been set. Ensure it is sane. + */ + else { + bool compute_val = (columnCt == 0); + + /* + * Increase the column size to the width of the widest entry + */ + if (maxEntryWidth > (int)columnSz) + columnSz = (size_t)maxEntryWidth; + + /* + * IF we have not been provided a column count + * *OR* we are set to overfill the output line, + * THEN compute the number of columns. + */ + if (! compute_val) { + long width = (long)maxEntryWidth + (long)(columnSz * (columnCt-1)); + compute_val = width > (unsigned)OPT_VALUE_WIDTH; + } + if (compute_val) + columnCt = (size_t)( + (((long)OPT_VALUE_WIDTH - (long)maxEntryWidth) / + (long)columnSz) + 1); + } + + /* + * Ensure that any "spread" we added to the column size + * does not exceed the parameterized limit. + */ + if ( HAVE_OPT( SPREAD ) + && ((maxEntryWidth + OPT_VALUE_SPREAD - 1) < (int)columnSz)) + columnSz = (size_t)(maxEntryWidth + OPT_VALUE_SPREAD - 1); +} + +MOD_LOCAL void +writeColumns(void) +{ + char zFmt[ 12 ]; + int colCt, rowCt, col, row; + tpPrintList pPL; + + colCt = (int)columnCt; + snprintf(zFmt, sizeof(zFmt), "%%-%ds", (int)columnSz); + + if (colCt == 1) { + writeRows(); + return; + } + + pPL = (tpPrintList)malloc_or_die((unsigned long)colCt * sizeof(tPrintList)); + + /* + * This "loop" is normally executed half way through and exited. + * IF, however, we would produce an empty final column, + * we will reduce our column count and line width and then + * try the top-of-column pointer computation again. + * + * The problem solved here is that sometimes, when the + * number of entries in a row is greater than the number of rows, + * it is possible that all the entries that would have been + * in the last column are, instead, essentially put on the + * last row. That will leave the final column empty. + * We could regroup at that point and spread the columns some more, + * but, if done, is an exercise for later. + */ + for (;;) { + int rem; + int fsz; + + rowCt = ((int)usedCt/colCt) + (((int)usedCt % colCt) ? 1 : 0); + + /* + * FOR each column, compute the address of the pointer to + * the string at the top of the column, and the index of + * that entry. + */ + for (col = 0; col < colCt ; col++) { + pPL[col].papz = papzLines + (col * rowCt); + pPL[col].index = col * rowCt; + } + + /* + * IF the final column is not empty, + * THEN break out and start printing. + */ + if (pPL[colCt-1].index < (int)usedCt) + break; + + /* + * The last column is blank, so we reduce our column count, + * even if the user specified a count!! + */ + colCt--; + rem = (int)OPT_VALUE_WIDTH - (int)(colCt * maxEntryWidth); + + if ((rem == 0) || (colCt < 2) || (columnSz > 0)) + fsz = maxEntryWidth; + else + fsz = maxEntryWidth + (rem / (colCt-1)); + snprintf( zFmt, sizeof(zFmt), "%%-%ds", fsz ); + } + + /* + * Now, actually print each row... + */ + for ( row = 0 ;; ) { + char * pzL; + char * pzE; + + if (pzLinePfx != NULL) + fputs( pzLinePfx, stdout ); + + /* + * Increment the index of the current entry in the last column. + * IF it goes beyond the end of the entries in use, + * THEN reduce our column count. + */ + if ((pPL[colCt-1].index)++ >= (int)usedCt) + colCt--; + + /* + * Get the address of the string in the last column. + */ + pzE = *(pPL[colCt-1].papz++); + + col = 0; + + /* + * FOR every column except the last, + * print the entry with the width format + * + * No need to worry about referring to a non-existent entry. Only + * the last column might have that problem, and we addressed it above + * where the column count got decremented. + */ + while (++col < colCt) { + pzL = *(pPL[col-1].papz++); + fprintf( stdout, zFmt, pzL ); + free( VOIDP(pzL) ); + } + + /* + * See if we are on the last row. If so, then this is the last entry. + * Strip any separation characters, emit the entry and break out. + */ + if (++row == rowCt) { + /* + * IF we have a separator, + * THEN remove it from the last entry. + */ + if (HAVE_OPT( SEPARATION )) { + char * pz = pzE + strlen( pzE ) + - strlen( OPT_ARG(SEPARATION)); + *pz = NUL; + } + + fputs(pzE, stdout); + if (HAVE_OPT(ENDING)) + fputs(OPT_ARG(ENDING), stdout); + + putc( '\n', stdout ); + break; + } + + /* + * Print the last entry on the line, without the width format. + * If we have line separation (which does not apply to the last + * line), then emit those characters, too. + */ + fputs( pzE, stdout ); + if (HAVE_OPT( LINE_SEPARATION )) + fputs( OPT_ARG( LINE_SEPARATION ), stdout ); + + putc( '\n', stdout ); + free( VOIDP(pzE) ); + } + + free(pPL); +} + +MOD_LOCAL void +trim_last_separation(void) +{ + char * pz = papzLines[ usedCt-1 ]; + pz += strlen(pz) - strlen( OPT_ARG(SEPARATION)); + *pz = NUL; +} + +MOD_LOCAL void +writeRows(void) +{ + char zFmt[32]; + int colCt; + + colCt = (int)columnCt; + snprintf(zFmt, sizeof(zFmt), "%%-%ds", (int)columnSz); + + if (HAVE_OPT( SEPARATION )) + trim_last_separation(); + + if (pzFirstPfx != NULL) { + fputs( pzFirstPfx, stdout ); + pzFirstPfx = pzLinePfx; + } + + { + char ** ppzLL = papzLines; + size_t left = usedCt; + int lnNo = 0; + + /* + * FOR every entry we are to emit, ... + */ + for (;;) { + char * pzL = *ppzLL++; + + /* + * IF this is the last entry, + * THEN emit it and a new line and break out + */ + if (--left <= 0) { + fputs(pzL, stdout); + if (HAVE_OPT(ENDING)) + fputs(OPT_ARG(ENDING), stdout); + + putc('\n', stdout); + free(VOIDP(pzL)); + break; + } + + /* + * IF the count of entries on this line is still less + * than the number of columns, + * THEN emit the padded entry + * ELSE ... + */ + if (++lnNo < colCt) + fprintf( stdout, zFmt, pzL ); + + else { + lnNo = 0; + /* + * Last entry on the line. Emit the string without padding. + * IF we have a line separation string, emit that too. + */ + fputs( pzL, stdout ); + if (HAVE_OPT( LINE_SEPARATION )) + fputs( OPT_ARG( LINE_SEPARATION ), stdout ); + + putc( '\n', stdout ); + + /* + * Start the next line with any required indentation + */ + if (pzFirstPfx != NULL) { + fputs( pzFirstPfx, stdout ); + pzFirstPfx = pzLinePfx; + } + } + + free( VOIDP(pzL) ); + } + } +} + +MOD_LOCAL int +emitWord(char const * word, size_t len, int col) +{ + static int ended_with_period = 0; + + if (col > 0) { + if ((int)len >= (OPT_VALUE_WIDTH - col)) { + putc('\n', stdout); + if (pzLinePfx != NULL) + fputs(pzLinePfx, stdout); + col = 0; + + } else { + if (ended_with_period) { + putc(' ', stdout); + col++; + } + putc(' ', stdout); + col++; + } + } + + fwrite(word, len, 1, stdout); + col += (int)len; + ended_with_period = (word[len - 1] == '.'); + + return col; +} + +/* + * writeFill -- fill the output. Pack together as much as will fit + * on each line. + */ +MOD_LOCAL void +writeFill(void) +{ + char ** ppzLL = papzLines; + size_t left = usedCt; + int colNo = 0; + + if (HAVE_OPT( SEPARATION )) + trim_last_separation(); + + if (pzFirstPfx != NULL) + fputs(pzFirstPfx, stdout); + + /* + * FOR every entry we are to emit, ... + */ + while (left-- > 0) { + char * pzL = *ppzLL; + + while (isspace(*pzL)) pzL++; + + /* + * Blank lines are magical and trigger a blank line in output. + */ + if (*pzL == NUL) { + if (! HAVE_OPT(SORT)) { + if (colNo > 0) /* guard against multiple blank lines */ + putc('\n', stdout); + putc('\n', stdout); + colNo = -2; + } + + free(*(ppzLL++)); + continue; + } + + /* + * We are going to emit some output. Make sure we're indented. + */ + if (colNo < 0) { + if (pzLinePfx != NULL) + fputs(pzLinePfx, stdout); + colNo = 0; + } + + do { + size_t tknlen; + + for (tknlen = 0; pzL[tknlen] != NUL; tknlen++) + if (isspace(pzL[tknlen])) + break; + colNo = emitWord(pzL, tknlen, colNo); + pzL += tknlen; + while (isspace(*pzL)) pzL++; + } while (*pzL != NUL); + + free(*(ppzLL++)); + } + + if (HAVE_OPT(ENDING) && (left == 0)) + fputs(OPT_ARG(ENDING), stdout); + + putc('\n', stdout); +} + + +/* + * Line comparison procedure + */ +MOD_LOCAL int +compProc(const void * p1, const void * p2) +{ + char const * pz1 = *(char * const *)p1; + char const * pz2 = *(char * const *)p2; + return strcmp(pz1, pz2); +} +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of columns/columns.c */ diff --git a/columns/opts.c b/columns/opts.c new file mode 100644 index 0000000..1f81d8f --- /dev/null +++ b/columns/opts.c @@ -0,0 +1,1106 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * DO NOT EDIT THIS FILE (opts.c) + * + * It has been AutoGen-ed + * From the definitions opts.def + * and the template file options + * + * Generated from AutoOpts 42:1:17 templates. + * + * AutoOpts is a copyrighted work. This source file is not encumbered + * by AutoOpts licensing, but is provided under the licensing terms chosen + * by the columns author or copyright holder. AutoOpts is + * licensed under the terms of the LGPL. The redistributable library + * (``libopts'') is licensed under the terms of either the LGPL or, at the + * users discretion, the BSD license. See the AutoOpts and/or libopts sources + * for details. + * + * The columns program is copyrighted and licensed + * under the following terms: + * + * Copyright (C) 1999-2017 Bruce Korb, all rights reserved. + * This is free software. It is licensed for use, modification and + * redistribution under the terms of the GNU General Public License, + * version 3 or later + * + * columns is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * columns is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ +/** \file opts.c + * \addtogroup columns + * @{ + */ + +#ifndef __doxygen__ +#define OPTION_CODE_COMPILE 1 +#include "opts.h" +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif +extern FILE * option_usage_fp; +#define zCopyright (columns_opt_strs+0) +#define zLicenseDescrip (columns_opt_strs+268) + +/* + * global included definitions + */ + +#include + +#define OPEN_ERROR_FMT (columns_opt_strs+871) + +#ifndef NULL +# define NULL 0 +#endif + +/** + * static const strings for columns options + */ +static char const columns_opt_strs[2139] = +/* 0 */ "columns (GNU AutoGen) 1.2\n" + "Copyright (C) 1999-2017 Bruce Korb, all rights reserved.\n" + "This is free software. It is licensed for use, modification and\n" + "redistribution under the terms of the GNU General Public License,\n" + "version 3 or later \n\0" +/* 268 */ "columns is free software: you can redistribute it and/or modify it under\n" + "the terms of the GNU General Public License as published by the Free\n" + "Software Foundation, either version 3 of the License, or (at your option)\n" + "any later version.\n\n" + "columns is distributed in the hope that it will be useful, but WITHOUT ANY\n" + "WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\n" + "FOR A PARTICULAR PURPOSE. See the GNU General Public License for more\n" + "details.\n\n" + "You should have received a copy of the GNU General Public License along\n" + "with this program. If not, see .\n\0" +/* 871 */ "Error %d (%s) opening %s\n\0" +/* 897 */ "Specify the output dimensions:\0" +/* 928 */ "Maximum Line Width\0" +/* 947 */ "WIDTH\0" +/* 953 */ "width\0" +/* 959 */ "Desired number of columns\0" +/* 985 */ "COLUMNS\0" +/* 993 */ "columns\0" +/* 1001 */ "Set width of each column\0" +/* 1026 */ "COL_WIDTH\0" +/* 1036 */ "col-width\0" +/* 1046 */ "tab width\0" +/* 1056 */ "TAB_WIDTH\0" +/* 1066 */ "tab-width\0" +/* 1076 */ "Specify how to lay out the text:\0" +/* 1109 */ "maximum spread added to column width\0" +/* 1146 */ "SPREAD\0" +/* 1153 */ "spread\0" +/* 1160 */ "Fill lines with input\0" +/* 1182 */ "FILL\0" +/* 1187 */ "fill\0" +/* 1192 */ "Line prefix or indentation\0" +/* 1219 */ "INDENT\0" +/* 1226 */ "indent\0" +/* 1233 */ "First line prefix\0" +/* 1251 */ "FIRST_INDENT\0" +/* 1264 */ "first-indent\0" +/* 1277 */ "Formatting string for each input\0" +/* 1310 */ "FORMAT\0" +/* 1317 */ "format\0" +/* 1324 */ "Separation string - follows all but last\0" +/* 1365 */ "SEPARATION\0" +/* 1376 */ "separation\0" +/* 1387 */ "string at end of all lines but last\0" +/* 1423 */ "LINE_SEPARATION\0" +/* 1439 */ "line-separation\0" +/* 1455 */ "string at end of last line\0" +/* 1482 */ "ENDING\0" +/* 1489 */ "ending\0" +/* 1496 */ "Specify the ordering of the entries:\0" +/* 1533 */ "Print entries in column order\0" +/* 1563 */ "BY_COLUMNS\0" +/* 1574 */ "by-columns\0" +/* 1585 */ "Sort input text\0" +/* 1601 */ "SORT\0" +/* 1606 */ "sort\0" +/* 1611 */ "Redirecting stdin to an alternate file:\0" +/* 1651 */ "Input file (if not stdin)\0" +/* 1677 */ "INPUT\0" +/* 1683 */ "input\0" +/* 1689 */ "display extended usage information and exit\0" +/* 1733 */ "help\0" +/* 1738 */ "extended usage information passed thru pager\0" +/* 1783 */ "more-help\0" +/* 1793 */ "output version information and exit\0" +/* 1829 */ "version\0" +/* 1837 */ "save the option state to a config file\0" +/* 1876 */ "save-opts\0" +/* 1886 */ "load options from a config file\0" +/* 1918 */ "LOAD_OPTS\0" +/* 1928 */ "no-load-opts\0" +/* 1941 */ "no\0" +/* 1944 */ "columns (GNU AutoGen) - Columnize Input Text - Ver. 1.2\n" + "Usage: %s [ - [] | --[{=| }] ]...\n\0" +/* 2058 */ ".\0" +/* 2060 */ "$HOME\0" +/* 2066 */ ".columnsrc\0" +/* 2077 */ "autogen-users@lists.sourceforge.net\0" +/* 2113 */ "columns (GNU AutoGen) 1.2"; + +/** + * dimensions option description: + */ +/** dimensions option separation text */ +#define DIMENSIONS_DESC (columns_opt_strs+897) +#define DIMENSIONS_FLAGS (OPTST_DOCUMENT | OPTST_NO_INIT) + +/** + * width option description: + */ +/** Descriptive text for the width option */ +#define WIDTH_DESC (columns_opt_strs+928) +/** Upper-cased name for the width option */ +#define WIDTH_NAME (columns_opt_strs+947) +/** Name string for the width option */ +#define WIDTH_name (columns_opt_strs+953) +/** The compiled in default value for the width option argument */ +#define WIDTH_DFT_ARG ((char const*)79) +/** Compiled in flag settings for the width option */ +#define WIDTH_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_NUMERIC)) + +/** + * columns option description: + */ +/** Descriptive text for the columns option */ +#define COLUMNS_DESC (columns_opt_strs+959) +/** Upper-cased name for the columns option */ +#define COLUMNS_NAME (columns_opt_strs+985) +/** Name string for the columns option */ +#define COLUMNS_name (columns_opt_strs+993) +/** The compiled in default value for the columns option argument */ +#define COLUMNS_DFT_ARG ((char const*)0) +/** Compiled in flag settings for the columns option */ +#define COLUMNS_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_NUMERIC)) + +/** + * col_width option description: + */ +/** Descriptive text for the col_width option */ +#define COL_WIDTH_DESC (columns_opt_strs+1001) +/** Upper-cased name for the col_width option */ +#define COL_WIDTH_NAME (columns_opt_strs+1026) +/** Name string for the col_width option */ +#define COL_WIDTH_name (columns_opt_strs+1036) +/** The compiled in default value for the col_width option argument */ +#define COL_WIDTH_DFT_ARG ((char const*)0) +/** Compiled in flag settings for the col_width option */ +#define COL_WIDTH_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_NUMERIC)) + +/** + * tab_width option description: + */ +/** Descriptive text for the tab_width option */ +#define TAB_WIDTH_DESC (columns_opt_strs+1046) +/** Upper-cased name for the tab_width option */ +#define TAB_WIDTH_NAME (columns_opt_strs+1056) +/** Name string for the tab_width option */ +#define TAB_WIDTH_name (columns_opt_strs+1066) +/** The compiled in default value for the tab_width option argument */ +#define TAB_WIDTH_DFT_ARG ((char const*)8) +/** Compiled in flag settings for the tab_width option */ +#define TAB_WIDTH_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_NUMERIC)) + +/** + * treatment option description: + */ +/** treatment option separation text */ +#define TREATMENT_DESC (columns_opt_strs+1076) +#define TREATMENT_FLAGS (OPTST_DOCUMENT | OPTST_NO_INIT) + +/** + * spread option description: + */ +/** Descriptive text for the spread option */ +#define SPREAD_DESC (columns_opt_strs+1109) +/** Upper-cased name for the spread option */ +#define SPREAD_NAME (columns_opt_strs+1146) +/** Name string for the spread option */ +#define SPREAD_name (columns_opt_strs+1153) +/** The compiled in default value for the spread option argument */ +#define SPREAD_DFT_ARG ((char const*)0) +/** Compiled in flag settings for the spread option */ +#define SPREAD_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_NUMERIC)) + +/** + * fill option description with + * "Must also have options" and "Incompatible options": + */ +/** Descriptive text for the fill option */ +#define FILL_DESC (columns_opt_strs+1160) +/** Upper-cased name for the fill option */ +#define FILL_NAME (columns_opt_strs+1182) +/** Name string for the fill option */ +#define FILL_name (columns_opt_strs+1187) +/** Other options that appear in conjunction with the fill option */ +static int const aFillCantList[] = { + INDEX_OPT_SPREAD, + INDEX_OPT_COL_WIDTH, + INDEX_OPT_BY_COLUMNS, NO_EQUIVALENT }; +/** Compiled in flag settings for the fill option */ +#define FILL_FLAGS (OPTST_DISABLED) + +/** + * indent option description: + */ +/** Descriptive text for the indent option */ +#define INDENT_DESC (columns_opt_strs+1192) +/** Upper-cased name for the indent option */ +#define INDENT_NAME (columns_opt_strs+1219) +/** Name string for the indent option */ +#define INDENT_name (columns_opt_strs+1226) +/** Compiled in flag settings for the indent option */ +#define INDENT_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/** + * first_indent option description with + * "Must also have options" and "Incompatible options": + */ +/** Descriptive text for the first_indent option */ +#define FIRST_INDENT_DESC (columns_opt_strs+1233) +/** Upper-cased name for the first_indent option */ +#define FIRST_INDENT_NAME (columns_opt_strs+1251) +/** Name string for the first_indent option */ +#define FIRST_INDENT_name (columns_opt_strs+1264) +/** Other options that are required by the first_indent option */ +static int const aFirst_IndentMustList[] = { + INDEX_OPT_INDENT, NO_EQUIVALENT }; +/** Compiled in flag settings for the first_indent option */ +#define FIRST_INDENT_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/** + * format option description: + */ +/** Descriptive text for the format option */ +#define FORMAT_DESC (columns_opt_strs+1277) +/** Upper-cased name for the format option */ +#define FORMAT_NAME (columns_opt_strs+1310) +/** Name string for the format option */ +#define FORMAT_name (columns_opt_strs+1317) +/** Compiled in flag settings for the format option */ +#define FORMAT_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/** + * separation option description: + */ +/** Descriptive text for the separation option */ +#define SEPARATION_DESC (columns_opt_strs+1324) +/** Upper-cased name for the separation option */ +#define SEPARATION_NAME (columns_opt_strs+1365) +/** Name string for the separation option */ +#define SEPARATION_name (columns_opt_strs+1376) +/** Compiled in flag settings for the separation option */ +#define SEPARATION_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/** + * line_separation option description: + */ +/** Descriptive text for the line_separation option */ +#define LINE_SEPARATION_DESC (columns_opt_strs+1387) +/** Upper-cased name for the line_separation option */ +#define LINE_SEPARATION_NAME (columns_opt_strs+1423) +/** Name string for the line_separation option */ +#define LINE_SEPARATION_name (columns_opt_strs+1439) +/** Compiled in flag settings for the line_separation option */ +#define LINE_SEPARATION_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/** + * ending option description: + */ +/** Descriptive text for the ending option */ +#define ENDING_DESC (columns_opt_strs+1455) +/** Upper-cased name for the ending option */ +#define ENDING_NAME (columns_opt_strs+1482) +/** Name string for the ending option */ +#define ENDING_name (columns_opt_strs+1489) +/** Compiled in flag settings for the ending option */ +#define ENDING_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/** + * ordering option description: + */ +/** ordering option separation text */ +#define ORDERING_DESC (columns_opt_strs+1496) +#define ORDERING_FLAGS (OPTST_DOCUMENT | OPTST_NO_INIT) + +/** + * by_columns option description: + */ +/** Descriptive text for the by_columns option */ +#define BY_COLUMNS_DESC (columns_opt_strs+1533) +/** Upper-cased name for the by_columns option */ +#define BY_COLUMNS_NAME (columns_opt_strs+1563) +/** Name string for the by_columns option */ +#define BY_COLUMNS_name (columns_opt_strs+1574) +/** Compiled in flag settings for the by_columns option */ +#define BY_COLUMNS_FLAGS (OPTST_DISABLED) + +/** + * sort option description: + */ +/** Descriptive text for the sort option */ +#define SORT_DESC (columns_opt_strs+1585) +/** Upper-cased name for the sort option */ +#define SORT_NAME (columns_opt_strs+1601) +/** Name string for the sort option */ +#define SORT_name (columns_opt_strs+1606) +/** Compiled in flag settings for the sort option */ +#define SORT_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING) | OPTST_ARG_OPTIONAL) + +/** + * input-text option description: + */ +/** input-text option separation text */ +#define INPUT_TEXT_DESC (columns_opt_strs+1611) +#define INPUT_TEXT_FLAGS (OPTST_DOCUMENT | OPTST_NO_INIT) + +/** + * input option description: + */ +/** Descriptive text for the input option */ +#define INPUT_DESC (columns_opt_strs+1651) +/** Upper-cased name for the input option */ +#define INPUT_NAME (columns_opt_strs+1677) +/** Name string for the input option */ +#define INPUT_name (columns_opt_strs+1683) +/** Compiled in flag settings for the input option */ +#define INPUT_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/* + * Help/More_Help/Version option descriptions: + */ +#define HELP_DESC (columns_opt_strs+1689) +#define HELP_name (columns_opt_strs+1733) +#ifdef HAVE_WORKING_FORK +#define MORE_HELP_DESC (columns_opt_strs+1738) +#define MORE_HELP_name (columns_opt_strs+1783) +#define MORE_HELP_FLAGS (OPTST_IMM | OPTST_NO_INIT) +#else +#define MORE_HELP_DESC HELP_DESC +#define MORE_HELP_name HELP_name +#define MORE_HELP_FLAGS (OPTST_OMITTED | OPTST_NO_INIT) +#endif +#ifdef NO_OPTIONAL_OPT_ARGS +# define VER_FLAGS (OPTST_IMM | OPTST_NO_INIT) +#else +# define VER_FLAGS (OPTST_SET_ARGTYPE(OPARG_TYPE_STRING) | \ + OPTST_ARG_OPTIONAL | OPTST_IMM | OPTST_NO_INIT) +#endif +#define VER_DESC (columns_opt_strs+1793) +#define VER_name (columns_opt_strs+1829) +#define SAVE_OPTS_DESC (columns_opt_strs+1837) +#define SAVE_OPTS_name (columns_opt_strs+1876) +#define LOAD_OPTS_DESC (columns_opt_strs+1886) +#define LOAD_OPTS_NAME (columns_opt_strs+1918) +#define NO_LOAD_OPTS_name (columns_opt_strs+1928) +#define LOAD_OPTS_pfx (columns_opt_strs+1941) +#define LOAD_OPTS_name (NO_LOAD_OPTS_name + 3) +/** + * Declare option callback procedures + */ +extern tOptProc + optionBooleanVal, optionNestedVal, optionNumericVal, + optionPagedUsage, optionPrintVersion, optionResetOpt, + optionStackArg, optionTimeDate, optionTimeVal, + optionUnstackArg, optionVendorOption; +static tOptProc + doOptCol_Width, doOptColumns, doOptInput, doOptSpread, + doOptWidth, doUsageOpt; +#define VER_PROC optionPrintVersion + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Define the columns Option Descriptions. + * This is an array of OPTION_CT entries, one for each + * option that the columns program responds to. + */ +static tOptDesc optDesc[OPTION_CT] = { + { /* entry idx, value */ 0, 0, + /* equiv idx, value */ 0, 0, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 0, 0, + /* opt state flags */ DIMENSIONS_FLAGS, 0, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ DIMENSIONS_DESC, NULL, NULL, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 1, VALUE_OPT_WIDTH, + /* equiv idx, value */ 1, VALUE_OPT_WIDTH, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ WIDTH_FLAGS, 0, + /* last opt argumnt */ { WIDTH_DFT_ARG }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ doOptWidth, + /* desc, NAME, name */ WIDTH_DESC, WIDTH_NAME, WIDTH_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 2, VALUE_OPT_COLUMNS, + /* equiv idx, value */ 2, VALUE_OPT_COLUMNS, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ COLUMNS_FLAGS, 0, + /* last opt argumnt */ { COLUMNS_DFT_ARG }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ doOptColumns, + /* desc, NAME, name */ COLUMNS_DESC, COLUMNS_NAME, COLUMNS_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 3, VALUE_OPT_COL_WIDTH, + /* equiv idx, value */ 3, VALUE_OPT_COL_WIDTH, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ COL_WIDTH_FLAGS, 0, + /* last opt argumnt */ { COL_WIDTH_DFT_ARG }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ doOptCol_Width, + /* desc, NAME, name */ COL_WIDTH_DESC, COL_WIDTH_NAME, COL_WIDTH_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 4, VALUE_OPT_TAB_WIDTH, + /* equiv idx, value */ 4, VALUE_OPT_TAB_WIDTH, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ TAB_WIDTH_FLAGS, 0, + /* last opt argumnt */ { TAB_WIDTH_DFT_ARG }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ optionNumericVal, + /* desc, NAME, name */ TAB_WIDTH_DESC, TAB_WIDTH_NAME, TAB_WIDTH_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 0, 0, + /* equiv idx, value */ 0, 0, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 0, 0, + /* opt state flags */ TREATMENT_FLAGS, 0, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ TREATMENT_DESC, NULL, NULL, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 6, VALUE_OPT_SPREAD, + /* equiv idx, value */ 6, VALUE_OPT_SPREAD, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ SPREAD_FLAGS, 0, + /* last opt argumnt */ { SPREAD_DFT_ARG }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ doOptSpread, + /* desc, NAME, name */ SPREAD_DESC, SPREAD_NAME, SPREAD_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 7, VALUE_OPT_FILL, + /* equiv idx, value */ 7, VALUE_OPT_FILL, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ FILL_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --fill */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, aFillCantList, + /* option proc */ NULL, + /* desc, NAME, name */ FILL_DESC, FILL_NAME, FILL_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 8, VALUE_OPT_INDENT, + /* equiv idx, value */ 8, VALUE_OPT_INDENT, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ INDENT_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --indent */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ INDENT_DESC, INDENT_NAME, INDENT_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 9, VALUE_OPT_FIRST_INDENT, + /* equiv idx, value */ 9, VALUE_OPT_FIRST_INDENT, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ FIRST_INDENT_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --first_indent */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ aFirst_IndentMustList, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ FIRST_INDENT_DESC, FIRST_INDENT_NAME, FIRST_INDENT_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 10, VALUE_OPT_FORMAT, + /* equiv idx, value */ 10, VALUE_OPT_FORMAT, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ FORMAT_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --format */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ FORMAT_DESC, FORMAT_NAME, FORMAT_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 11, VALUE_OPT_SEPARATION, + /* equiv idx, value */ 11, VALUE_OPT_SEPARATION, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ SEPARATION_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --separation */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ SEPARATION_DESC, SEPARATION_NAME, SEPARATION_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 12, VALUE_OPT_LINE_SEPARATION, + /* equiv idx, value */ 12, VALUE_OPT_LINE_SEPARATION, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ LINE_SEPARATION_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --line_separation */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ LINE_SEPARATION_DESC, LINE_SEPARATION_NAME, LINE_SEPARATION_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 13, VALUE_OPT_ENDING, + /* equiv idx, value */ 13, VALUE_OPT_ENDING, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ ENDING_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --ending */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ ENDING_DESC, ENDING_NAME, ENDING_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 0, 0, + /* equiv idx, value */ 0, 0, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 0, 0, + /* opt state flags */ ORDERING_FLAGS, 0, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ ORDERING_DESC, NULL, NULL, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 15, VALUE_OPT_BY_COLUMNS, + /* equiv idx, value */ 15, VALUE_OPT_BY_COLUMNS, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ BY_COLUMNS_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --by_columns */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ BY_COLUMNS_DESC, BY_COLUMNS_NAME, BY_COLUMNS_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 16, VALUE_OPT_SORT, + /* equiv idx, value */ 16, VALUE_OPT_SORT, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ SORT_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --sort */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ SORT_DESC, SORT_NAME, SORT_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 0, 0, + /* equiv idx, value */ 0, 0, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 0, 0, + /* opt state flags */ INPUT_TEXT_FLAGS, 0, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ INPUT_TEXT_DESC, NULL, NULL, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 18, VALUE_OPT_INPUT, + /* equiv idx, value */ 18, VALUE_OPT_INPUT, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ INPUT_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --input */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ doOptInput, + /* desc, NAME, name */ INPUT_DESC, INPUT_NAME, INPUT_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ INDEX_OPT_VERSION, VALUE_OPT_VERSION, + /* equiv idx value */ NO_EQUIVALENT, VALUE_OPT_VERSION, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ VER_FLAGS, AOUSE_VERSION, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ VER_PROC, + /* desc, NAME, name */ VER_DESC, NULL, VER_name, + /* disablement strs */ NULL, NULL }, + + + + { /* entry idx, value */ INDEX_OPT_HELP, VALUE_OPT_HELP, + /* equiv idx value */ NO_EQUIVALENT, VALUE_OPT_HELP, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ OPTST_IMM | OPTST_NO_INIT, AOUSE_HELP, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ doUsageOpt, + /* desc, NAME, name */ HELP_DESC, NULL, HELP_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ INDEX_OPT_MORE_HELP, VALUE_OPT_MORE_HELP, + /* equiv idx value */ NO_EQUIVALENT, VALUE_OPT_MORE_HELP, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ MORE_HELP_FLAGS, AOUSE_MORE_HELP, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ optionPagedUsage, + /* desc, NAME, name */ MORE_HELP_DESC, NULL, MORE_HELP_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ INDEX_OPT_SAVE_OPTS, VALUE_OPT_SAVE_OPTS, + /* equiv idx value */ NO_EQUIVALENT, VALUE_OPT_SAVE_OPTS, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ OPTST_SET_ARGTYPE(OPARG_TYPE_STRING) + | OPTST_ARG_OPTIONAL | OPTST_NO_INIT, AOUSE_SAVE_OPTS, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ SAVE_OPTS_DESC, NULL, SAVE_OPTS_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ INDEX_OPT_LOAD_OPTS, VALUE_OPT_LOAD_OPTS, + /* equiv idx value */ NO_EQUIVALENT, VALUE_OPT_LOAD_OPTS, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, NOLIMIT, 0, + /* opt state flags */ OPTST_SET_ARGTYPE(OPARG_TYPE_STRING) + | OPTST_DISABLE_IMM, AOUSE_LOAD_OPTS, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ optionLoadOpt, + /* desc, NAME, name */ LOAD_OPTS_DESC, LOAD_OPTS_NAME, LOAD_OPTS_name, + /* disablement strs */ NO_LOAD_OPTS_name, LOAD_OPTS_pfx } +}; + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** Reference to the upper cased version of columns. */ +#define zPROGNAME (columns_opt_strs+985) +/** Reference to the title line for columns usage. */ +#define zUsageTitle (columns_opt_strs+1944) +/** columns configuration file name. */ +#define zRcName (columns_opt_strs+2066) +/** Directories to search for columns config files. */ +static char const * const apzHomeList[3] = { + columns_opt_strs+2058, + columns_opt_strs+2060, + NULL }; +/** The columns program bug email address. */ +#define zBugsAddr (columns_opt_strs+2077) +/** Clarification/explanation of what columns does. */ +#define zExplain (NULL) +/** Extra detail explaining what columns does. */ +#define zDetail (NULL) +/** The full version string for columns. */ +#define zFullVersion (columns_opt_strs+2113) +/* extracted from optcode.tlib near line 342 */ + +#define OPTPROC_BASE OPTPROC_NONE +#define translate_option_strings NULL + +#define columns_full_usage (NULL) +#define columns_short_usage (NULL) + +#endif /* not defined __doxygen__ */ + +/* + * Create the static procedure(s) declared above. + */ +/** + * The callout function that invokes the optionUsage function. + * + * @param[in] opts the AutoOpts option description structure + * @param[in] od the descriptor for the "help" (usage) option. + * @noreturn + */ +static void +doUsageOpt(tOptions * opts, tOptDesc * od) +{ + int ex_code; + ex_code = COLUMNS_EXIT_SUCCESS; + optionUsage(&columnsOptions, ex_code); + /* NOTREACHED */ + exit(COLUMNS_EXIT_FAILURE); + (void)opts; + (void)od; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Code to handle the width option. + * This option specifies the full width of the output line, + * including any start-of-line indentation. The output will fill + * each line as completely as possible, unless the column width has + * been explicitly specified. If the maximum width is less than + * the length of the widest input, you will get a single column + * of output. + * @param[in] pOptions the columns options data structure + * @param[in,out] pOptDesc the option descriptor for this option. + */ +static void +doOptWidth(tOptions* pOptions, tOptDesc* pOptDesc) +{ + static struct {long rmin, rmax;} const rng[1] = { + { 16, 4095 } }; + int ix; + + if (pOptions <= OPTPROC_EMIT_LIMIT) + goto emit_ranges; + optionNumericVal(pOptions, pOptDesc); + + for (ix = 0; ix < 1; ix++) { + if (pOptDesc->optArg.argInt < rng[ix].rmin) + continue; /* ranges need not be ordered. */ + if (pOptDesc->optArg.argInt == rng[ix].rmin) + return; + if (rng[ix].rmax == LONG_MIN) + continue; + if (pOptDesc->optArg.argInt <= rng[ix].rmax) + return; + } + + option_usage_fp = stderr; + + emit_ranges: +optionShowRange(pOptions, pOptDesc, VOIDP(rng), 1); +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Code to handle the columns option. + * Use this option to specify exactly how many columns to produce. + * If that many columns will not fit within @var{line_width}, then + * the count will be reduced to the number that fit. + * @param[in] pOptions the columns options data structure + * @param[in,out] pOptDesc the option descriptor for this option. + */ +static void +doOptColumns(tOptions* pOptions, tOptDesc* pOptDesc) +{ + static struct {long rmin, rmax;} const rng[1] = { + { 1, 2048 } }; + int ix; + + if (pOptions <= OPTPROC_EMIT_LIMIT) + goto emit_ranges; + optionNumericVal(pOptions, pOptDesc); + + for (ix = 0; ix < 1; ix++) { + if (pOptDesc->optArg.argInt < rng[ix].rmin) + continue; /* ranges need not be ordered. */ + if (pOptDesc->optArg.argInt == rng[ix].rmin) + return; + if (rng[ix].rmax == LONG_MIN) + continue; + if (pOptDesc->optArg.argInt <= rng[ix].rmax) + return; + } + + option_usage_fp = stderr; + + emit_ranges: +optionShowRange(pOptions, pOptDesc, VOIDP(rng), 1); +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Code to handle the col_width option. + * Use this option to specify exactly how many characters are to be + * allocated for each column. If it is narrower than the widest entry, + * it will be over-ridden with the required width. + * @param[in] pOptions the columns options data structure + * @param[in,out] pOptDesc the option descriptor for this option. + */ +static void +doOptCol_Width(tOptions* pOptions, tOptDesc* pOptDesc) +{ + static struct {long rmin, rmax;} const rng[1] = { + { 1, 2048 } }; + int ix; + + if (pOptions <= OPTPROC_EMIT_LIMIT) + goto emit_ranges; + optionNumericVal(pOptions, pOptDesc); + + for (ix = 0; ix < 1; ix++) { + if (pOptDesc->optArg.argInt < rng[ix].rmin) + continue; /* ranges need not be ordered. */ + if (pOptDesc->optArg.argInt == rng[ix].rmin) + return; + if (rng[ix].rmax == LONG_MIN) + continue; + if (pOptDesc->optArg.argInt <= rng[ix].rmax) + return; + } + + option_usage_fp = stderr; + + emit_ranges: +optionShowRange(pOptions, pOptDesc, VOIDP(rng), 1); +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Code to handle the spread option. + * Use this option to specify exactly how many characters may be + * added to each column. It allows you to prevent columns from + * becoming too far apart. Without this option, @file{columns} + * will attempt to widen columns to fill the full width. + * @param[in] pOptions the columns options data structure + * @param[in,out] pOptDesc the option descriptor for this option. + */ +static void +doOptSpread(tOptions* pOptions, tOptDesc* pOptDesc) +{ + static struct {long rmin, rmax;} const rng[1] = { + { 1, 1024 } }; + int ix; + + if (pOptions <= OPTPROC_EMIT_LIMIT) + goto emit_ranges; + optionNumericVal(pOptions, pOptDesc); + + for (ix = 0; ix < 1; ix++) { + if (pOptDesc->optArg.argInt < rng[ix].rmin) + continue; /* ranges need not be ordered. */ + if (pOptDesc->optArg.argInt == rng[ix].rmin) + return; + if (rng[ix].rmax == LONG_MIN) + continue; + if (pOptDesc->optArg.argInt <= rng[ix].rmax) + return; + } + + option_usage_fp = stderr; + + emit_ranges: +optionShowRange(pOptions, pOptDesc, VOIDP(rng), 1); +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Code to handle the input option. + * This program normally runs as a @code{filter}, reading from standard + * input, columnizing and writing to standard out. This option redirects + * input to a file. + * @param[in] pOptions the columns options data structure + * @param[in,out] pOptDesc the option descriptor for this option. + */ +static void +doOptInput(tOptions* pOptions, tOptDesc* pOptDesc) +{ + /* + * Be sure the flag-code[0] handles special values for the options pointer + * viz. (poptions <= OPTPROC_EMIT_LIMIT) *and also* the special flag bit + * ((poptdesc->fOptState & OPTST_RESET) != 0) telling the option to + * reset its state. + */ + /* extracted from opts.def, line 305 */ + FILE * fp = freopen( + pOptDesc->optArg.argString, "r" FOPEN_BINARY_FLAG, stdin); + + if (fp == (FILE *)NULL) { + fprintf(stderr, OPEN_ERROR_FMT, errno, strerror(errno), + pOptDesc->optArg.argString); + USAGE(EXIT_FAILURE); + } + (void)pOptions; +} +/* extracted from optmain.tlib near line 1250 */ + +/** + * Print a fatal error message and die, \a va_list style. + * + * @param[in] exit_code the value to call exit(3) with + * @param[in] fmt the death rattle message + * @param[in] ap the argument list for the message + * @noreturn + */ +noreturn extern void +vdie(int exit_code, char const * fmt, va_list ap) +{ + char const * die_leader = _("columns fatal error:\n"); + fputs(die_leader, stderr); + vfprintf(stderr, fmt, ap); + fflush(stderr); + exit(exit_code); +} + +/** + * Print a fatal error message and die, var-arg style. + * + * @param[in] exit_code the value to call exit(3) with + * @param[in] fmt the death rattle message + * @param[in] ... the list of arguments for the message + * @noreturn + */ +noreturn extern void +die(int exit_code, char const * fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vdie(exit_code, fmt, ap); +} + +/** + * Print a file system error fatal error message and die. + * + * @param[in] exit_code the value to call exit(3) with. + * @param[in] op the operation that failed. + * @param[in] fname the file name the operation was on. + * @noreturn + */ +noreturn extern void +fserr(int exit_code, char const * op, char const * fname) +{ + char const * fserr_fmt = _("fserr %d (%s) performing '%s' on %s\n"); + die(exit_code, fserr_fmt, errno, strerror(errno), op, fname); +} + +/** + * The directory containing the data associated with columns. + */ +#ifndef PKGDATADIR +# define PKGDATADIR "" +#endif + +/** + * Information about the person or institution that packaged columns + * for the current distribution. + */ +#ifndef WITH_PACKAGER +# define columns_packager_info NULL +#else +/** Packager information for columns. */ +static char const columns_packager_info[] = + "Packaged by " WITH_PACKAGER + +# ifdef WITH_PACKAGER_VERSION + " ("WITH_PACKAGER_VERSION")" +# endif + +# ifdef WITH_PACKAGER_BUG_REPORTS + "\nReport columns bugs to " WITH_PACKAGER_BUG_REPORTS +# endif + "\n"; +#endif +#ifndef __doxygen__ + +#endif /* __doxygen__ */ +/** + * The option definitions for columns. The one structure that + * binds them all. + */ +tOptions columnsOptions = { + OPTIONS_STRUCT_VERSION, + 0, NULL, /* original argc + argv */ + ( OPTPROC_BASE + + OPTPROC_ERRSTOP + + OPTPROC_SHORTOPT + + OPTPROC_LONGOPT + + OPTPROC_NO_REQ_OPT + + OPTPROC_ENVIRON + + OPTPROC_NO_ARGS ), + 0, NULL, /* current option index, current option */ + NULL, NULL, zPROGNAME, + zRcName, zCopyright, zLicenseDescrip, + zFullVersion, apzHomeList, zUsageTitle, + zExplain, zDetail, optDesc, + zBugsAddr, /* address to send bugs to */ + NULL, NULL, /* extensions/saved state */ + optionUsage, /* usage procedure */ + translate_option_strings, /* translation procedure */ + /* + * Indexes to special options + */ + { INDEX_OPT_MORE_HELP, /* more-help option index */ + INDEX_OPT_SAVE_OPTS, /* save option index */ + NO_EQUIVALENT, /* '-#' option index */ + NO_EQUIVALENT /* index of default opt */ + }, + 24 /* full option count */, 19 /* user option count */, + columns_full_usage, columns_short_usage, + NULL, NULL, + PKGDATADIR, columns_packager_info +}; + +#ifdef __cplusplus +} +#endif +/** @} */ +/* opts.c ends here */ diff --git a/columns/opts.def b/columns/opts.def new file mode 100644 index 0000000..dbe975f --- /dev/null +++ b/columns/opts.def @@ -0,0 +1,362 @@ +/* -*- Mode: conf -*- */ + +autogen definitions options; +addtogroup = columns; + +/* opts.def: option definitons for columns + * + * AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoGen is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AutoGen is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +copyright = { + date = "1999-2017"; + type = gpl; + owner = "Bruce Korb"; + eaddr = 'autogen-users@lists.sourceforge.net'; +}; + +prog-name = "columns"; +prog-title = "Columnize Input Text"; +package = 'GNU AutoGen'; +homerc = '.', '$HOME'; +environrc; +long-opts; +no-xlate = anything; +omit-nls-code; +die-code; + +version = "1.2"; + +export = <<- EOExport + #include "config.h" + #include + #include + #include + #include + #include + #include + EOExport; + +include = "[= AutoGen5 Template =]"; +include = "#include "; + +flag = { + name = dimensions; + documentation; + + descrip = 'Specify the output dimensions'; +}; + +flag = { + name = width; + value = W; + arg-type = number; + arg-default = 79; + arg-name = num; + arg-range = '16->4095'; + descrip = "Maximum Line Width"; + doc = <<- _EODoc_ + This option specifies the full width of the output line, + including any start-of-line indentation. The output will fill + each line as completely as possible, unless the column width has + been explicitly specified. If the maximum width is less than + the length of the widest input, you will get a single column + of output. + _EODoc_; +}; + +flag = { + name = columns; + value = c; + arg-type = number; + arg-default = 0; + arg-name = count; + arg-range = '1->2048'; + descrip = "Desired number of columns"; + doc = <<- _EODoc_ + Use this option to specify exactly how many columns to produce. + If that many columns will not fit within @var{line_width}, then + the count will be reduced to the number that fit. + _EODoc_; +}; + +flag = { + name = col_width; + value = w; + arg-type = number; + arg-default = 0; + arg-name = num; + arg-range = '1->2048'; + descrip = "Set width of each column"; + doc = <<- _EODoc_ + Use this option to specify exactly how many characters are to be + allocated for each column. If it is narrower than the widest entry, + it will be over-ridden with the required width. + _EODoc_; +}; + +flag = { + name = tab_width; + arg-type = number; + arg-default = 8; + arg-name = num; + descrip = "tab width"; + doc = <<- _EODoc_ + If an indentation string contains tabs, then this value is used to + compute the ending column of the prefix string. + _EODoc_; +}; + +#ifdef LATER +flag = { + name = page_len; + arg-type = number; + arg-name = num; + descrip = "Page Length"; + doc = <<- _EODoc_ + This many lines will be printed before a form feed is emitted. + The 'by_columns' ordering will wrap columns within a page. + _EODoc_; +}; +#endif + +flag = { + name = treatment; + documentation; + descrip = 'Specify how to lay out the text'; +}; + +flag = { + name = spread; + arg-type = number; + arg-default = 0; + arg-name = num; + arg-range = '1->1024'; + descrip = "maximum spread added to column width"; + doc = <<- _EODoc_ + Use this option to specify exactly how many characters may be + added to each column. It allows you to prevent columns from + becoming too far apart. Without this option, @file{columns} + will attempt to widen columns to fill the full width. + _EODoc_; +}; + +flag = { + name = fill; + descrip = "Fill lines with input"; + flags-cant = spread, col_width, by_columns; + doc = <<- _EODoc_ + Instead of columnizing the input text, fill the output lines + with the input lines. Blank lines on input will cause a + blank line in the output, unless the output is sorted. + With sorted output, blank lines are ignored. + _EODoc_; +}; + +flag = { + name = indent; + value = I; + arg-type = string; + arg-name = l-pfx; + descrip = "Line prefix or indentation"; + doc = <<- _EODoc_ + If a number, then this many spaces will be inserted at the start of + every line. Otherwise, it is a line prefix that will be inserted + at the start of every line. + _EODoc_; +}; + +flag = { + name = first_indent; + arg-type = string; + flags_must = indent; + arg-name = l-pfx; + descrip = "First line prefix"; + doc = <<- _EODoc_ + If a number, then this many spaces will be inserted at the start of + the first line. Otherwise, it is a line prefix that will be inserted + at the start of that line. If its length exceeds "indent", then it + will be emitted on a line by itself, suffixed by any line separation + string. For example: + + @example + $ columns --first='#define TABLE' -c 2 -I4 --line=' \' <<_EOF_ + one + two + three + four + _EOF_ + #define TABLE \ + one two \ + three four + @end example + _EODoc_; // ' +}; + +flag = { + name = format; + value = f; + arg-type = string; + arg-name = fmt-str; + descrip = "Formatting string for each input"; + doc = <<- _EODoc_ + If you need to reformat each input text, the argument to this + option is interpreted as an @code{sprintf(3)} format that is used + to produce each output entry. + _EODoc_; +}; + +flag = { + name = separation; + value = S; + arg-type = string; + arg-name = sep-str; + descrip = "Separation string - follows all but last"; + doc = <<- _EODoc_ + Use this option if, for example, you wish a comma to appear after + each entry except the last. + _EODoc_; +}; + +flag = { + name = line_separation; + arg-type = string; + arg-name = sep-str; + descrip = "string at end of all lines but last"; + doc = <<- _EODoc_ + Use this option if, for example, you wish a backslash to appear at + the end of every line, except the last. + _EODoc_; +}; + +flag = { + name = ending; + arg-type = string; + arg-name = end-str; + descrip = "string at end of last line"; + doc = <<- _EODoc_ + This option puts the specified string at the end of the output. + _EODoc_; +}; + +flag = { + name = ordering; + documentation; + descrip = 'Specify the ordering of the entries'; +}; + +flag = { + name = by_columns; + descrip = "Print entries in column order"; + doc = <<- _EODoc_ + Normally, the entries are printed out in order by rows and then columns. + This option will cause the entries to be ordered within columns. + The final column, instead of the final row, may be shorter than the + others. + _EODoc_; +}; + +flag = { + name = sort; + value = s; + arg-type = string; + arg-optional; + arg-name = key-pat; + descrip = "Sort input text"; + doc = <<- _EODoc_ + Causes the input text to be sorted. If an argument is supplied, + it is presumed to be a pattern and the sort is based upon the + matched text. If the pattern starts with or consists of + an asterisk (@code{*}), then the sort is case insensitive. + _EODoc_; +}; + +flag = { + name = input-text; + documentation; + descrip = 'Redirecting stdin to an alternate file'; +}; + +include = + '#define OPEN_ERROR_FMT ([= + (string-table-add-ref opt-strs + "Error %d (%s) opening %s\n")=])'; + +flag = { + name = input; + value = i; + arg-type = string; + arg-name = file; + descrip = "Input file (if not stdin)"; + flag-code = <<- _EODoc_ + FILE * fp = freopen( + pOptDesc->optArg.argString, "r" FOPEN_BINARY_FLAG, stdin); + + if (fp == (FILE *)NULL) { + fprintf(stderr, OPEN_ERROR_FMT, errno, strerror(errno), + pOptDesc->optArg.argString); + USAGE(EXIT_FAILURE); + } + _EODoc_; + doc = <<- _EODoc_ + This program normally runs as a @code{filter}, reading from standard + input, columnizing and writing to standard out. This option redirects + input to a file. + _EODoc_; +}; + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * Program Documentation + */ +option-doc-format = texi; + +/* prog_man_descrip = -- unchanged; */ + +doc-section = { + ds-type = "SEE ALSO"; + ds-format = texi; + ds-text = <<- _EndOfMan_ + This program is documented more fully in the Columns section + of the Add-On chapter in the @code{AutoGen} Info system documentation. + _EndOfMan_; +}; + +prog_descrip = <<- _EndOfMan_ + This program was designed for the purpose of generating compact, + columnized tables. It will read a list of text items from standard + in or a specified input file and produce a columnized listing of + all the non-blank lines. Leading white space on each line is + preserved, but trailing white space is stripped. Methods of + applying per-entry and per-line embellishments are provided. + See the formatting and separation arguments below. + + This program is used by AutoGen to help clean up and organize + its output. + + See @file{autogen/agen5/fsm.tpl} and the generated output + @file{pseudo-fsm.h}. + + This function was not implemented as an expression function because + either it would have to be many expression functions, or a provision + would have to be added to provide options to expression functions. + Maybe not a bad idea, but it is not being implemented at the moment. + + A side benefit is that you can use it outside of @code{autogen} to + columnize input, a la the @code{ls} command. + _EndOfMan_; + +/* end of opts.def */ diff --git a/columns/opts.h b/columns/opts.h new file mode 100644 index 0000000..a41aed0 --- /dev/null +++ b/columns/opts.h @@ -0,0 +1,251 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * DO NOT EDIT THIS FILE (opts.h) + * + * It has been AutoGen-ed + * From the definitions opts.def + * and the template file options + * + * Generated from AutoOpts 42:1:17 templates. + * + * AutoOpts is a copyrighted work. This header file is not encumbered + * by AutoOpts licensing, but is provided under the licensing terms chosen + * by the columns author or copyright holder. AutoOpts is + * licensed under the terms of the LGPL. The redistributable library + * (``libopts'') is licensed under the terms of either the LGPL or, at the + * users discretion, the BSD license. See the AutoOpts and/or libopts sources + * for details. + * + * The columns program is copyrighted and licensed + * under the following terms: + * + * Copyright (C) 1999-2017 Bruce Korb, all rights reserved. + * This is free software. It is licensed for use, modification and + * redistribution under the terms of the GNU General Public License, + * version 3 or later + * + * columns is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * columns is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ +/** \file opts.h + * \addtogroup columns + * @{ + */ +/** + * This file contains the programmatic interface to the Automated + * Options generated for the columns program. + * These macros are documented in the AutoGen info file in the + * "AutoOpts" chapter. Please refer to that doc for usage help. + */ +#ifndef AUTOOPTS_OPTS_H_GUARD +#define AUTOOPTS_OPTS_H_GUARD 1 +#include +#include +#include + +/** + * Ensure that the library used for compiling this generated header is at + * least as new as the version current when the header template was released + * (not counting patch version increments). Also ensure that the oldest + * tolerable version is at least as old as what was current when the header + * template was released. + */ +#define AO_TEMPLATE_VERSION 172033 +#if (AO_TEMPLATE_VERSION < OPTIONS_MINIMUM_VERSION) \ + || (AO_TEMPLATE_VERSION > OPTIONS_STRUCT_VERSION) +# error option template version mismatches autoopts/options.h header + Choke Me. +#endif + +#if GCC_VERSION > 40400 +#define NOT_REACHED __builtin_unreachable(); +#else +#define NOT_REACHED +#endif + +/** + * Enumeration of each option type for columns + */ +typedef enum { + INDEX_OPT_WIDTH = 1, + INDEX_OPT_COLUMNS = 2, + INDEX_OPT_COL_WIDTH = 3, + INDEX_OPT_TAB_WIDTH = 4, + INDEX_OPT_SPREAD = 6, + INDEX_OPT_FILL = 7, + INDEX_OPT_INDENT = 8, + INDEX_OPT_FIRST_INDENT = 9, + INDEX_OPT_FORMAT = 10, + INDEX_OPT_SEPARATION = 11, + INDEX_OPT_LINE_SEPARATION = 12, + INDEX_OPT_ENDING = 13, + INDEX_OPT_BY_COLUMNS = 15, + INDEX_OPT_SORT = 16, + INDEX_OPT_INPUT = 18, + INDEX_OPT_VERSION = 19, + INDEX_OPT_HELP = 20, + INDEX_OPT_MORE_HELP = 21, + INDEX_OPT_SAVE_OPTS = 22, + INDEX_OPT_LOAD_OPTS = 23 +} teOptIndex; +/** count of all options for columns */ +#define OPTION_CT 24 +/** columns version */ +#define COLUMNS_VERSION "1.2" +/** Full columns version text */ +#define COLUMNS_FULL_VERSION "columns (GNU AutoGen) 1.2" + +/** + * Interface defines for all options. Replace "n" with the UPPER_CASED + * option name (as in the teOptIndex enumeration above). + * e.g. HAVE_OPT(DIMENSIONS) + */ +#define DESC(n) (columnsOptions.pOptDesc[INDEX_OPT_## n]) +/** 'true' if an option has been specified in any way */ +#define HAVE_OPT(n) (! UNUSED_OPT(& DESC(n))) +/** The string argument to an option. The argument type must be \"string\". */ +#define OPT_ARG(n) (DESC(n).optArg.argString) +/** Mask the option state revealing how an option was specified. + * It will be one and only one of \a OPTST_SET, \a OPTST_PRESET, + * \a OPTST_DEFINED, \a OPTST_RESET or zero. + */ +#define STATE_OPT(n) (DESC(n).fOptState & OPTST_SET_MASK) +/** Count of option's occurrances *on the command line*. */ +#define COUNT_OPT(n) (DESC(n).optOccCt) +/** mask of \a OPTST_SET and \a OPTST_DEFINED. */ +#define ISSEL_OPT(n) (SELECTED_OPT(&DESC(n))) +/** 'true' if \a HAVE_OPT would yield 'false'. */ +#define ISUNUSED_OPT(n) (UNUSED_OPT(& DESC(n))) +/** 'true' if OPTST_DISABLED bit not set. */ +#define ENABLED_OPT(n) (! DISABLED_OPT(& DESC(n))) +/** number of stacked option arguments. + * Valid only for stacked option arguments. */ +#define STACKCT_OPT(n) (((tArgList*)(DESC(n).optCookie))->useCt) +/** stacked argument vector. + * Valid only for stacked option arguments. */ +#define STACKLST_OPT(n) (((tArgList*)(DESC(n).optCookie))->apzArgs) +/** Reset an option. */ +#define CLEAR_OPT(n) STMTS( \ + DESC(n).fOptState &= OPTST_PERSISTENT_MASK; \ + if ((DESC(n).fOptState & OPTST_INITENABLED) == 0) \ + DESC(n).fOptState |= OPTST_DISABLED; \ + DESC(n).optCookie = NULL ) +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Enumeration of columns exit codes + */ +typedef enum { + COLUMNS_EXIT_SUCCESS = 0, + COLUMNS_EXIT_FAILURE = 1, + COLUMNS_EXIT_USAGE_ERROR = 64, + COLUMNS_EXIT_NO_CONFIG_INPUT = 66, + COLUMNS_EXIT_LIBOPTS_FAILURE = 70 +} columns_exit_code_t; +/** + * Interface defines for specific options. + * @{ + */ +#define VALUE_OPT_WIDTH 'W' + +#define OPT_VALUE_WIDTH (DESC(WIDTH).optArg.argInt) +#define VALUE_OPT_COLUMNS 'c' + +#define OPT_VALUE_COLUMNS (DESC(COLUMNS).optArg.argInt) +#define VALUE_OPT_COL_WIDTH 'w' + +#define OPT_VALUE_COL_WIDTH (DESC(COL_WIDTH).optArg.argInt) +#define VALUE_OPT_TAB_WIDTH 0x1001 + +#define OPT_VALUE_TAB_WIDTH (DESC(TAB_WIDTH).optArg.argInt) +#define VALUE_OPT_SPREAD 0x1002 + +#define OPT_VALUE_SPREAD (DESC(SPREAD).optArg.argInt) +#define VALUE_OPT_FILL 0x1003 +#define VALUE_OPT_INDENT 'I' +#define VALUE_OPT_FIRST_INDENT 0x1004 +#define VALUE_OPT_FORMAT 'f' +#define VALUE_OPT_SEPARATION 'S' +#define VALUE_OPT_LINE_SEPARATION 0x1005 +#define VALUE_OPT_ENDING 0x1006 +#define VALUE_OPT_BY_COLUMNS 0x1007 +#define VALUE_OPT_SORT 's' +#define VALUE_OPT_INPUT 'i' +/** option flag (value) for help-value option */ +#define VALUE_OPT_HELP '?' +/** option flag (value) for more-help-value option */ +#define VALUE_OPT_MORE_HELP '!' +/** option flag (value) for version-value option */ +#define VALUE_OPT_VERSION 'v' +/** option flag (value) for save-opts-value option */ +#define VALUE_OPT_SAVE_OPTS '>' +/** option flag (value) for load-opts-value option */ +#define VALUE_OPT_LOAD_OPTS '<' +#define SET_OPT_SAVE_OPTS(a) STMTS( \ + DESC(SAVE_OPTS).fOptState &= OPTST_PERSISTENT_MASK; \ + DESC(SAVE_OPTS).fOptState |= OPTST_SET; \ + DESC(SAVE_OPTS).optArg.argString = (char const*)(a)) +/* + * Interface defines not associated with particular options + */ +#define ERRSKIP_OPTERR STMTS(columnsOptions.fOptSet &= ~OPTPROC_ERRSTOP) +#define ERRSTOP_OPTERR STMTS(columnsOptions.fOptSet |= OPTPROC_ERRSTOP) +#define RESTART_OPT(n) STMTS( \ + columnsOptions.curOptIdx = (n); \ + columnsOptions.pzCurOpt = NULL ) +#define START_OPT RESTART_OPT(1) +#define USAGE(c) (*columnsOptions.pUsageProc)(&columnsOptions, c) + +#ifdef __cplusplus +extern "C" { +#endif +/* + * global exported definitions + */ +#include "config.h" +#include +#include +#include +#include +#include +#include + + +/* * * * * * + * + * Declare the columns option descriptor. + */ +extern tOptions columnsOptions; +# define OPT_NO_XLAT_CFG_NAMES +# define OPT_NO_XLAT_OPT_NAMES + +# define OPT_XLAT_CFG_NAMES +# define OPT_XLAT_OPT_NAMES + +# ifndef _ +# define _(_s) _s +# endif + + +noreturn extern void +vdie( int exit_code, char const * fmt, va_list); +noreturn extern void +die( int exit_code, char const * fmt, ...); +noreturn extern void +fserr(int exit_code, char const * op, char const * fn); +#ifdef __cplusplus +} +#endif +#endif /* AUTOOPTS_OPTS_H_GUARD */ + +/** @} */ +/* opts.h ends here */ diff --git a/compat/Makefile.am b/compat/Makefile.am new file mode 100644 index 0000000..b745a1e --- /dev/null +++ b/compat/Makefile.am @@ -0,0 +1,51 @@ +## -*- Mode: Makefile -*- +## +## Makefile.am -- process this file with automake to produce Makefile.in +## +## Copyright (C) 1997-2018 by Bruce Korb +## Author: Bruce Korb +## +## This file is part of AutoGen. +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . + +COMPAT_CSRC = chmod.c pathfind.c snprintf.c strchr.c strdup.c strftime.c \ + strsignal.c +COMPAT_HDRS = compat.h strsignal.h windows-config.h unlocked-io.h +COMPAT_GEN = bootstrap.dir strsignal.def strsignal.tpl +EXTRA_DIST = $(COMPAT_CSRC) $(COMPAT_HDRS) $(COMPAT_GEN) + +MAINTAINERCLEANFILES = strsignal.h + +all: + : + +strsignal.h : strsignal.def strsignal.tpl + @if $(AGexe) --version >&- 2>&- ; then \ + echo $(AGexe) -L $(srcdir) $(srcdir)/strsignal.def ; \ + top_srcdir=$(top_srcdir) top_builddir=$(top_builddir) \ + $(AGexe) -L $(srcdir) $(srcdir)/strsignal.def ; \ + elif $(AGnam) --version >&- 2>&- ; then \ + echo $(AGnam) -L $(srcdir) $(srcdir)/strsignal.def ; \ + top_srcdir=$(top_srcdir) top_builddir=$(top_builddir) \ + $(AGnam) -L $(srcdir) $(srcdir)/strsignal.def ; \ + elif test -s $(srcdir)/$@; then \ + echo "WARNING: $(AGnam) not available, current $(srcdir)/$@ used"; \ + else \ + echo "ERROR: $(srcdir)/$@ has been corrupted"; exit 1;\ + fi + +.NOTPARALLEL: + +# compat/Makefile.am ends here diff --git a/compat/Makefile.in b/compat/Makefile.in new file mode 100644 index 0000000..d315571 --- /dev/null +++ b/compat/Makefile.in @@ -0,0 +1,534 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 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. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = compat +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/ag_macros.m4 \ + $(top_srcdir)/config/asm-underscore.m4 \ + $(top_srcdir)/config/extensions.m4 \ + $(top_srcdir)/config/guile.m4 \ + $(top_srcdir)/config/host-cpu-c-abi.m4 \ + $(top_srcdir)/config/lib-ld.m4 \ + $(top_srcdir)/config/lib-link.m4 \ + $(top_srcdir)/config/lib-prefix.m4 \ + $(top_srcdir)/config/libopts.m4 \ + $(top_srcdir)/config/libtool.m4 \ + $(top_srcdir)/config/ltoptions.m4 \ + $(top_srcdir)/config/ltsugar.m4 \ + $(top_srcdir)/config/ltversion.m4 \ + $(top_srcdir)/config/lt~obsolete.m4 \ + $(top_srcdir)/config/onceonly.m4 $(top_srcdir)/config/pkg.m4 \ + $(top_srcdir)/config/snprintfv.m4 \ + $(top_srcdir)/config/stdnoreturn.m4 \ + $(top_srcdir)/config/unlocked-io.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +am__DIST_COMMON = $(srcdir)/Makefile.in +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AGEN5_TESTS = @AGEN5_TESTS@ +AG_LDFLAGS = @AG_LDFLAGS@ +AG_MAJOR_VERSION = @AG_MAJOR_VERSION@ +AG_MINOR_VERSION = @AG_MINOR_VERSION@ +AG_STATIC_AUTOGEN = @AG_STATIC_AUTOGEN@ +AG_TIMEOUT = @AG_TIMEOUT@ +AG_VERSION = @AG_VERSION@ +AG_XML2 = @AG_XML2@ +AGexe = @AGexe@ +AGnam = @AGnam@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AO_AGE = @AO_AGE@ +AO_CURRENT = @AO_CURRENT@ +AO_REVISION = @AO_REVISION@ +AO_TEMPLATE_VERSION = @AO_TEMPLATE_VERSION@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLexe = @CLexe@ +CLnam = @CLnam@ +CONFIG_SHELL = @CONFIG_SHELL@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBUG_ENABLED = @DEBUG_ENABLED@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +DYNAMIC_AG = @DYNAMIC_AG@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_STATIC = @ENABLE_STATIC@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GDexe = @GDexe@ +GDnam = @GDnam@ +GO_AGE = @GO_AGE@ +GO_CURRENT = @GO_CURRENT@ +GO_REVISION = @GO_REVISION@ +GREP = @GREP@ +GUILE_CFLAGS = @GUILE_CFLAGS@ +GUILE_EFFECTIVE_VERSION = @GUILE_EFFECTIVE_VERSION@ +GUILE_LDFLAGS = @GUILE_LDFLAGS@ +GUILE_LIBS = @GUILE_LIBS@ +GUILE_LTLIBS = @GUILE_LTLIBS@ +HOST_CPU = @HOST_CPU@ +HOST_CPU_C_ABI = @HOST_CPU_C_ABI@ +INCLIST = @INCLIST@ +INCSNPRINTFV = @INCSNPRINTFV@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSNPRINTFV = @LIBSNPRINTFV@ +LIBTOOL = @LIBTOOL@ +LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ +LIBXML2_LIBS = @LIBXML2_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +M4_SRC = @M4_SRC@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPTS_TESTDIR = @OPTS_TESTDIR@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSIX_SHELL = @POSIX_SHELL@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STDNORETURN_H = @STDNORETURN_H@ +STRIP = @STRIP@ +TEXI2HTML = @TEXI2HTML@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_aux_dir = @ac_aux_dir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +COMPAT_CSRC = chmod.c pathfind.c snprintf.c strchr.c strdup.c strftime.c \ + strsignal.c + +COMPAT_HDRS = compat.h strsignal.h windows-config.h unlocked-io.h +COMPAT_GEN = bootstrap.dir strsignal.def strsignal.tpl +EXTRA_DIST = $(COMPAT_CSRC) $(COMPAT_HDRS) $(COMPAT_GEN) +MAINTAINERCLEANFILES = strsignal.h +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu compat/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu compat/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: + + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + cscopelist-am ctags-am distclean distclean-generic \ + distclean-libtool distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +all: + : + +strsignal.h : strsignal.def strsignal.tpl + @if $(AGexe) --version >&- 2>&- ; then \ + echo $(AGexe) -L $(srcdir) $(srcdir)/strsignal.def ; \ + top_srcdir=$(top_srcdir) top_builddir=$(top_builddir) \ + $(AGexe) -L $(srcdir) $(srcdir)/strsignal.def ; \ + elif $(AGnam) --version >&- 2>&- ; then \ + echo $(AGnam) -L $(srcdir) $(srcdir)/strsignal.def ; \ + top_srcdir=$(top_srcdir) top_builddir=$(top_builddir) \ + $(AGnam) -L $(srcdir) $(srcdir)/strsignal.def ; \ + elif test -s $(srcdir)/$@; then \ + echo "WARNING: $(AGnam) not available, current $(srcdir)/$@ used"; \ + else \ + echo "ERROR: $(srcdir)/$@ has been corrupted"; exit 1;\ + fi + +.NOTPARALLEL: + +# compat/Makefile.am ends here + +# 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/compat/bootstrap.dir b/compat/bootstrap.dir new file mode 100644 index 0000000..79611db --- /dev/null +++ b/compat/bootstrap.dir @@ -0,0 +1,32 @@ +#! /bin/echo This_file_must_be_sourced,_not_executed +## +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . + +if ${skip_gen} +then + gunzip < strsignal.h.gz > strsignal.h +else + ${AGexe} strsignal.def +fi + +# Local Variables: +# mode:shell-script +# sh-indentation:4 +# sh-basic-offset:4 +# indent-tabs-mode: nil +# End: + +# compat/bootstrap.dir ends here diff --git a/compat/chmod.c b/compat/chmod.c new file mode 100644 index 0000000..01a1be0 --- /dev/null +++ b/compat/chmod.c @@ -0,0 +1,4 @@ + +inline int chmod(char const * path, mode_t mode) { + return 0; +} diff --git a/compat/compat.h b/compat/compat.h new file mode 100644 index 0000000..70a5652 --- /dev/null +++ b/compat/compat.h @@ -0,0 +1,383 @@ +/* -*- Mode: C -*- + * + * compat.h is free software. + * This file is part of AutoGen and AutoOpts. + * + * AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +/** + * \file compat.h + * fake the preprocessor into handlng stuff portability + */ +#ifndef COMPAT_H_GUARD +#define COMPAT_H_GUARD 1 + +#if defined(HAVE_CONFIG_H) +# include + +#elif defined(_WIN32) && !defined(__CYGWIN__) +# include "windows-config.h" + +#else +# error "compat.h" requires "config.h" + choke me. +#endif + + +#ifndef HAVE_STRSIGNAL +# ifndef HAVE_RAW_DECL_STRSIGNAL + char * strsignal(int signo); +# endif +#endif + +#define _GNU_SOURCE 1 /* for strsignal in GNU's libc */ +#define __USE_GNU 1 /* exact same thing as above */ +#define __EXTENSIONS__ 1 /* and another way to call for it */ + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * SYSTEM HEADERS: + */ +#include +#ifdef HAVE_SYS_MMAN_H +# include +#endif +#include +#if HAVE_SYS_PROCSET_H +# include +#endif +#include +#ifdef HAVE_SYS_WAIT_H +# include +#endif + +#if defined( HAVE_SOLARIS_SYSINFO ) +# include +#elif defined( HAVE_UNAME_SYSCALL ) +# include +#endif + +#ifdef DAEMON_ENABLED +# if HAVE_SYS_STROPTS_H +# include +# endif + +# if HAVE_SYS_SOCKET_H +# include +# endif + +# if ! defined(HAVE_SYS_POLL_H) && ! defined(HAVE_SYS_SELECT_H) +# error This system cannot support daemon processing + Choke Me. +# endif + +# if HAVE_SYS_POLL_H +# include +# endif + +# if HAVE_SYS_SELECT_H +# include +# endif + +# if HAVE_NETINET_IN_H +# include +# endif + +# if HAVE_SYS_UN_H +# include +# endif +#endif + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * USER HEADERS: + */ +#include +#include +#include + +/* + * Directory opening stuff: + */ +# if defined (_POSIX_SOURCE) +/* Posix does not require that the d_ino field be present, and some + systems do not provide it. */ +# define REAL_DIR_ENTRY(dp) 1 +# else /* !_POSIX_SOURCE */ +# define REAL_DIR_ENTRY(dp) (dp->d_ino != 0) +# endif /* !_POSIX_SOURCE */ + +# if defined (HAVE_DIRENT_H) +# include +# define D_NAMLEN(dirent) strlen((dirent)->d_name) +# else /* !HAVE_DIRENT_H */ +# define dirent direct +# define D_NAMLEN(dirent) (dirent)->d_namlen +# if defined (HAVE_SYS_NDIR_H) +# include +# endif /* HAVE_SYS_NDIR_H */ +# if defined (HAVE_SYS_DIR_H) +# include +# endif /* HAVE_SYS_DIR_H */ +# if defined (HAVE_NDIR_H) +# include +# endif /* HAVE_NDIR_H */ +# endif /* !HAVE_DIRENT_H */ + +#include +#ifdef HAVE_FCNTL_H +# include +#endif +#ifndef O_NONBLOCK +# define O_NONBLOCK FNDELAY +#endif + +#if defined(HAVE_LIBGEN) && defined(HAVE_LIBGEN_H) +# include +#endif + +#if defined(HAVE_LIMITS_H) /* this is also in options.h */ +# include +#elif defined(HAVE_SYS_LIMITS_H) +# include +#endif /* HAVE_LIMITS/SYS_LIMITS_H */ + +#include +#include +#include + +#if defined(HAVE_STDINT_H) +# include + +#elif defined(HAVE_INTTYPES_H) +# include +#endif + +#include +#include +#include + +#ifdef HAVE_UTIME_H +# include +#endif + +#ifdef HAVE_UNISTD_H +# include +#endif + +#if defined(HAVE_STDBOOL_H) +# include +#elif ! defined(bool) + typedef enum { false = 0, true = 1 } _Bool; +# define bool _Bool + + /* The other macros must be usable in preprocessor directives. */ +# define false 0 +# define true 1 +#endif + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * FIXUPS and CONVIENCE STUFF: + */ +#ifdef __cplusplus +# define EXTERN extern "C" +#else +# define EXTERN extern +#endif + +/* some systems #def errno! and others do not declare it!! */ +#ifndef errno + extern int errno; +#endif + +/* Some machines forget this! */ + +# ifndef EXIT_FAILURE +# define EXIT_SUCCESS 0 +# define EXIT_FAILURE 1 +# endif + +#ifndef NUL +# define NUL '\0' +#endif + +#ifndef NULL +# define NULL 0 +#endif + +#if !defined (MAXPATHLEN) && defined (HAVE_SYS_PARAM_H) +# include +#endif /* !MAXPATHLEN && HAVE_SYS_PARAM_H */ + +#if !defined (MAXPATHLEN) && defined (PATH_MAX) +# define MAXPATHLEN PATH_MAX +#endif /* !MAXPATHLEN && PATH_MAX */ + +#if !defined (MAXPATHLEN) && defined(_MAX_PATH) +# define PATH_MAX _MAX_PATH +# define MAXPATHLEN _MAX_PATH +#endif + +#if !defined (MAXPATHLEN) +# define MAXPATHLEN 4096 +#endif /* MAXPATHLEN */ + +#define AG_PATH_MAX ((size_t)MAXPATHLEN) + +#ifndef LONG_MAX +# define LONG_MAX ~(1L << (8*sizeof(long) -1)) +# define INT_MAX ~(1 << (8*sizeof(int) -1)) +#endif + +#ifndef ULONG_MAX +# define ULONG_MAX ~(OUL) +# define UINT_MAX ~(OU) +#endif + +#ifndef SHORT_MAX +# define SHORT_MAX ~(1 << (8*sizeof(short) - 1)) +#else +# define USHORT_MAX ~(OUS) +#endif + +#ifndef HAVE_INT8_T + typedef signed char int8_t; +# define HAVE_INT8_T 1 +#endif +#ifndef HAVE_UINT8_T + typedef unsigned char uint8_t; +# define HAVE_UINT8_T 1 +#endif +#ifndef HAVE_INT16_T + typedef signed short int16_t; +# define HAVE_INT16_T 1 +#endif +#ifndef HAVE_UINT16_T + typedef unsigned short uint16_t; +# define HAVE_UINT16_T 1 +#endif + +#ifndef HAVE_INT32_T +# if SIZEOF_INT == 4 + typedef signed int int32_t; +# elif SIZEOF_LONG == 4 + typedef signed long int32_t; +# endif +# define HAVE_INT32_T 1 +#endif + +#ifndef HAVE_UINT32_T +# if SIZEOF_INT == 4 + typedef unsigned int uint32_t; +# elif SIZEOF_LONG == 4 + typedef unsigned long uint32_t; +# else +# error Cannot create a uint32_t type. + Choke Me. +# endif +# define HAVE_UINT32_T 1 +#endif + +#ifndef HAVE_INTPTR_T +# if SIZEOF_CHARP == SIZEOF_LONG + typedef signed long intptr_t; +# else + typedef signed int intptr_t; +# endif +# define HAVE_INTPTR_T 1 +#endif + +#ifndef HAVE_UINTPTR_T +# if SIZEOF_CHARP == SIZEOF_LONG + typedef unsigned long intptr_t; +# else + typedef unsigned int intptr_t; +# endif +# define HAVE_INTPTR_T 1 +#endif + +#ifndef HAVE_UINT_T + typedef unsigned int uint_t; +# define HAVE_UINT_T 1 +#endif + +#ifndef HAVE_SIZE_T + typedef unsigned int size_t; +# define HAVE_SIZE_T 1 +#endif +#ifndef HAVE_WINT_T + typedef unsigned int wint_t; +# define HAVE_WINT_T 1 +#endif +#ifndef HAVE_PID_T + typedef signed int pid_t; +# define HAVE_PID_T 1 +#endif + +/* redefine these for BSD style string libraries */ +#ifndef HAVE_STRCHR +# define strchr index +# define strrchr rindex +#endif + +#ifdef USE_FOPEN_BINARY +# ifndef FOPEN_BINARY_FLAG +# define FOPEN_BINARY_FLAG "b" +# endif +# ifndef FOPEN_TEXT_FLAG +# define FOPEN_TEXT_FLAG "t" +# endif +#else +# ifndef FOPEN_BINARY_FLAG +# define FOPEN_BINARY_FLAG +# endif +# ifndef FOPEN_TEXT_FLAG +# define FOPEN_TEXT_FLAG +# endif +#endif + +#ifndef STR +# define _STR(s) #s +# define STR(s) _STR(s) +#endif + +/* ##### Pointer sized word ##### */ + +/* FIXME: the MAX stuff in here is broken! */ +#if SIZEOF_CHARP > SIZEOF_INT + typedef long t_word; + #define WORD_MAX LONG_MAX + #define WORD_MIN LONG_MIN +#else /* SIZEOF_CHARP <= SIZEOF_INT */ + typedef int t_word; + #define WORD_MAX INT_MAX + #define WORD_MIN INT_MIN +#endif + +#endif /* COMPAT_H_GUARD */ + +/* + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of compat/compat.h */ diff --git a/compat/pathfind.c b/compat/pathfind.c new file mode 100644 index 0000000..5c477ca --- /dev/null +++ b/compat/pathfind.c @@ -0,0 +1,283 @@ +/* -*- Mode: C -*- */ + +/* pathfind.c --- find a FILE MODE along PATH */ + +/* Author: Gary V Vaughan */ + +/* Code: */ + +static char * +pathfind( char const * path, + char const * fname, + char const * mode ); + +#include "compat.h" +#ifndef HAVE_PATHFIND +#if defined(__windows__) && !defined(__CYGWIN__) +static char * +pathfind( char const * path, + char const * fname, + char const * mode ) +{ + return strdup(fname); +} +#else + +static char * make_absolute(char const * string, char const * dot_path); +static char * canonicalize_pathname(char * path); +static char * extract_colon_unit(char * dir, char const * string, int * p_index); + +/** + * local implementation of pathfind. + * @param[in] path colon separated list of directories + * @param[in] fname the name we are hunting for + * @param[in] mode the required file mode + * @returns an allocated string with the full path, or NULL + */ +static char * +pathfind( char const * path, + char const * fname, + char const * mode ) +{ + int p_index = 0; + int mode_bits = 0; + char * res_path = NULL; + char zPath[ AG_PATH_MAX + 1 ]; + + if (strchr( mode, 'r' )) mode_bits |= R_OK; + if (strchr( mode, 'w' )) mode_bits |= W_OK; + if (strchr( mode, 'x' )) mode_bits |= X_OK; + + /* + * FOR each non-null entry in the colon-separated path, DO ... + */ + for (;;) { + DIR * dirP; + char * colon_unit = extract_colon_unit( zPath, path, &p_index ); + + if (colon_unit == NULL) + break; + + dirP = opendir( colon_unit ); + + /* + * IF the directory is inaccessable, THEN next directory + */ + if (dirP == NULL) + continue; + + for (;;) { + struct dirent *entP = readdir( dirP ); + + if (entP == (struct dirent *)NULL) + break; + + /* + * IF the file name matches the one we are looking for, ... + */ + if (strcmp(entP->d_name, fname) == 0) { + char * abs_name = make_absolute(fname, colon_unit); + + /* + * Make sure we can access it in the way we want + */ + if (access(abs_name, mode_bits) >= 0) { + /* + * We can, so normalize the name and return it below + */ + res_path = canonicalize_pathname(abs_name); + } + + free(abs_name); + break; + } + } + + closedir( dirP ); + + if (res_path != NULL) + break; + } + + return res_path; +} + +/* + * Turn STRING (a pathname) into an absolute pathname, assuming that + * DOT_PATH contains the symbolic location of `.'. This always returns + * a new string, even if STRING was an absolute pathname to begin with. + */ +static char * +make_absolute( char const * string, char const * dot_path ) +{ + char * result; + int result_len; + + if (!dot_path || *string == '/') { + result = strdup( string ); + } else { + if (dot_path && dot_path[0]) { + result = malloc( 2 + strlen( dot_path ) + strlen( string ) ); + strcpy( result, dot_path ); + result_len = (int)strlen(result); + if (result[result_len - 1] != '/') { + result[result_len++] = '/'; + result[result_len] = '\0'; + } + } else { + result = malloc( 3 + strlen( string ) ); + result[0] = '.'; result[1] = '/'; result[2] = '\0'; + result_len = 2; + } + + strcpy( result + result_len, string ); + } + + return result; +} + +/* + * Canonicalize PATH, and return a new path. The new path differs from + * PATH in that: + * + * Multiple `/'s are collapsed to a single `/'. + * Leading `./'s are removed. + * Trailing `/.'s are removed. + * Trailing `/'s are removed. + * Non-leading `../'s and trailing `..'s are handled by removing + * portions of the path. + */ +static char * +canonicalize_pathname( char *path ) +{ + int i, start; + char stub_char, *result; + + /* The result cannot be larger than the input PATH. */ + result = strdup( path ); + + stub_char = (*path == '/') ? '/' : '.'; + + /* Walk along RESULT looking for things to compact. */ + i = 0; + while (result[i]) { + while (result[i] != '\0' && result[i] != '/') + i++; + + start = i++; + + /* If we didn't find any slashes, then there is nothing left to + * do. + */ + if (!result[start]) + break; + + /* Handle multiple `/'s in a row. */ + while (result[i] == '/') + i++; + +#if !defined (apollo) + if ((start + 1) != i) +#else + if ((start + 1) != i && (start != 0 || i != 2)) +#endif /* apollo */ + { + strcpy( result + start + 1, result + i ); + i = start + 1; + } + + /* Handle backquoted `/'. */ + if (start > 0 && result[start - 1] == '\\') + continue; + + /* Check for trailing `/', and `.' by itself. */ + if ((start && !result[i]) + || (result[i] == '.' && !result[i+1])) { + result[--i] = '\0'; + break; + } + + /* Check for `../', `./' or trailing `.' by itself. */ + if (result[i] == '.') { + /* Handle `./'. */ + if (result[i + 1] == '/') { + strcpy( result + i, result + i + 1 ); + i = (start < 0) ? 0 : start; + continue; + } + + /* Handle `../' or trailing `..' by itself. */ + if (result[i + 1] == '.' && + (result[i + 2] == '/' || !result[i + 2])) { + while (--start > -1 && result[start] != '/') + ; + strcpy( result + start + 1, result + i + 2 ); + i = (start < 0) ? 0 : start; + continue; + } + } + } + + if (!*result) { + *result = stub_char; + result[1] = '\0'; + } + + return result; +} + +/* + * Given a string containing units of information separated by colons, + * return the next one pointed to by (P_INDEX), or NULL if there are no + * more. Advance (P_INDEX) to the character after the colon. + */ +static char * +extract_colon_unit(char * pzDir, char const * string, int * p_index) +{ + char * pzDest = pzDir; + int ix = *p_index; + + if (string == NULL) + return NULL; + + if ((unsigned)ix >= strlen( string )) + return NULL; + + { + char const * pzSrc = string + ix; + + while (*pzSrc == ':') pzSrc++; + + for (;;) { + char ch = (*(pzDest++) = *(pzSrc++)); + switch (ch) { + case ':': + pzDest[-1] = NUL; + /* FALLTHROUGH */ + case NUL: + goto copy_done; + } + + if ((unsigned long)(pzDest - pzDir) >= AG_PATH_MAX) + break; + } copy_done:; + + ix = (int)(pzSrc - string); + } + + if (*pzDir == NUL) + return NULL; + + *p_index = ix; + return pzDir; +} +#endif /* __windows__ / __CYGWIN__ */ +#endif /* HAVE_PATHFIND */ + +/* + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of compat/pathfind.c */ diff --git a/compat/snprintf.c b/compat/snprintf.c new file mode 100644 index 0000000..eccea1f --- /dev/null +++ b/compat/snprintf.c @@ -0,0 +1,62 @@ + +#ifndef HAVE_VPRINTF +#include "choke-me: no vprintf and no snprintf" + choke me. +#endif + +#if defined(HAVE_STDARG_H) +# include +# ifndef VA_START +# define VA_START(a, f) va_start(a, f) +# define VA_END(a) va_end(a) +# endif /* VA_START */ +# define SNV_USING_STDARG_H + +#elif defined(HAVE_VARARGS_H) +# include +# ifndef VA_START +# define VA_START(a, f) va_start(a) +# define VA_END(a) va_end(a) +# endif /* VA_START */ +# undef SNV_USING_STDARG_H + +#else +# include "must-have-stdarg-or-varargs" + choke me. +#endif + +static int +snprintf(char *str, size_t n, char const *fmt, ...) +{ + va_list ap; + int rval; + +#ifdef VSPRINTF_CHARSTAR + char *rp; + VA_START(ap, fmt); + rp = vsprintf(str, fmt, ap); + VA_END(ap); + rval = strlen(rp); + +#else + VA_START(ap, fmt); + rval = vsprintf(str, fmt, ap); + VA_END(ap); +#endif + + if (rval > n) { + fprintf(stderr, "snprintf buffer overrun %d > %d\n", rval, (int)n); + abort(); + } + return rval; +} + +static int +vsnprintf( char *str, size_t n, char const *fmt, va_list ap ) +{ +#ifdef VSPRINTF_CHARSTAR + return (strlen(vsprintf(str, fmt, ap))); +#else + return (vsprintf(str, fmt, ap)); +#endif +} diff --git a/compat/strchr.c b/compat/strchr.c new file mode 100644 index 0000000..f409387 --- /dev/null +++ b/compat/strchr.c @@ -0,0 +1,66 @@ +/* + SYNOPSIS + #include + + char *strchr(char const *s, int c); + + char *strrchr(char const *s, int c); + + DESCRIPTION + The strchr() function returns a pointer to the first occurrence of the + character c in the string s. + + The strrchr() function returns a pointer to the last occurrence of the + character c in the string s. + + Here "character" means "byte" - these functions do not work with wide + or multi-byte characters. + + RETURN VALUE + The strchr() and strrchr() functions return a pointer to the matched + character or NULL if the character is not found. + + CONFORMING TO + SVID 3, POSIX, BSD 4.3, ISO 9899 +*/ + +static char * +strchr(char const *s, int c); + +static char * +strrchr(char const *s, int c); + +static char * +strchr(char const *s, int c) +{ + do { + if ((unsigned char)*s == (unsigned char)c) + return s; + + } while (*(++s) != NUL); + + return NULL; +} + +static char * +strrchr(char const *s, int c) +{ + char const *e = s + strlen(s); + + for (;;) { + if (--e < s) + break; + + if ((unsigned char)*e == (unsigned char)c) + return e; + } + return NULL; +} + +/* + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of compat/strsignal.c */ diff --git a/compat/strdup.c b/compat/strdup.c new file mode 100644 index 0000000..f3a4077 --- /dev/null +++ b/compat/strdup.c @@ -0,0 +1,22 @@ +/* + * Platforms without strdup ?!?!?! + */ + +static char * +strdup( char const *s ); + +static char * +strdup( char const *s ) +{ + char *cp; + + if (s == NULL) + return NULL; + + cp = (char *) AGALOC((unsigned) (strlen(s)+1), "strdup"); + + if (cp != NULL) + (void) strcpy(cp, s); + + return cp; +} diff --git a/compat/strftime.c b/compat/strftime.c new file mode 100644 index 0000000..400ad52 --- /dev/null +++ b/compat/strftime.c @@ -0,0 +1,1049 @@ +/* + NOTE: The canonical source of this file is maintained with the GNU C + Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu. + + 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, see . + + */ + +#if HAVE_CONFIG_H +# include +#endif + +#ifdef _LIBC +# define HAVE_LIMITS_H 1 +# define HAVE_MBLEN 1 +# define HAVE_MBRLEN 1 +# define HAVE_STRUCT_ERA_ENTRY 1 +# define HAVE_TM_GMTOFF 1 +# define HAVE_TM_ZONE 1 +# define HAVE_TZNAME 1 +# define HAVE_TZSET 1 +# define MULTIBYTE_IS_FORMAT_SAFE 1 +# define STDC_HEADERS 1 +# include +# include "../locale/localeinfo.h" +#endif + +#include +#include /* Some systems define `time_t' here. */ + +#ifdef TIME_WITH_SYS_TIME +# include +# include +#else +# ifdef HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif +#if HAVE_TZNAME +extern char *tzname[]; +#endif + +/* Do multibyte processing if multibytes are supported, unless + multibyte sequences are safe in formats. Multibyte sequences are + safe if they cannot contain byte sequences that look like format + conversion specifications. The GNU C Library uses UTF8 multibyte + encoding, which is safe for formats, but strftime.c can be used + with other C libraries that use unsafe encodings. */ +#define DO_MULTIBYTE (HAVE_MBLEN && ! MULTIBYTE_IS_FORMAT_SAFE) + +#if DO_MULTIBYTE +# if HAVE_MBRLEN +# include +# else + /* Simulate mbrlen with mblen as best we can. */ +# define mbstate_t int +# define mbrlen(s, n, ps) mblen (s, n) +# define mbsinit(ps) (*(ps) == 0) +# endif + static const mbstate_t mbstate_zero; +#endif + +#if HAVE_LIMITS_H +# include +#endif + +#if STDC_HEADERS +# include +# include +# include +#else +# define memcpy(d, s, n) bcopy ((s), (d), (n)) +#endif + +#ifndef __P +# if defined (__GNUC__) || (defined (__STDC__) && __STDC__) +# define __P(args) args +# else +# define __P(args) () +# endif /* GCC. */ +#endif /* Not __P. */ + +#ifndef PTR +# ifdef __STDC__ +# define PTR void * +# else +# define PTR char * +# endif +#endif + +#ifndef CHAR_BIT +# define CHAR_BIT 8 +#endif + +#ifndef NULL +# define NULL 0 +#endif + +#define TYPE_SIGNED(t) ((t) -1 < 0) + +/* Bound on length of the string representing an integer value of type t. + Subtract one for the sign bit if t is signed; + 302 / 1000 is log10 (2) rounded up; + add one for integer division truncation; + add one more for a minus sign if t is signed. */ +#define INT_STRLEN_BOUND(t) \ + ((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 100 + 1 + TYPE_SIGNED (t)) + +#define TM_YEAR_BASE 1900 + +#ifndef __isleap +/* Nonzero if YEAR is a leap year (every 4 years, + except every 100th isn't, and every 400th is). */ +# define __isleap(year) \ + ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0)) +#endif + + +#ifdef _LIBC +# define gmtime_r __gmtime_r +# define localtime_r __localtime_r +extern int __tz_compute __P ((time_t timer, const struct tm *tm)); +# define tzname __tzname +# define tzset __tzset +#else +# if ! HAVE_LOCALTIME_R +# if ! HAVE_TM_GMTOFF +/* Approximate gmtime_r as best we can in its absence. */ +# define gmtime_r my_gmtime_r +static struct tm *gmtime_r __P ((const time_t *, struct tm *)); +static struct tm * +gmtime_r (const time_t *t, struct tm *tp) +{ + struct tm *l = gmtime (t); + if (! l) + return 0; + *tp = *l; + return tp; +} +# endif /* ! HAVE_TM_GMTOFF */ + +/* Approximate localtime_r as best we can in its absence. */ +# define localtime_r my_localtime_r +static struct tm *localtime_r __P ((const time_t *, struct tm *)); +static struct tm * +localtime_r (const time_t *t, struct tm *tp) +{ + struct tm *l = localtime (t); + if (! l) + return 0; + *tp = *l; + return tp; +} +# endif /* ! HAVE_LOCALTIME_R */ +#endif /* ! defined (_LIBC) */ + + +#if !defined (memset) && !HAVE_MEMSET && !_LIBC +/* Some systems lack the `memset' function and we don't want to + introduce additional dependencies. */ +static char const spaces[16] = " "; + +# define memset_space(P, Len) \ + do { \ + int _len = (Len); \ + \ + do \ + { \ + int _this = _len > 16 ? 16 : _len; \ + memcpy ((P), spaces, (size_t) _this); \ + (P) += _this; \ + _len -= _this; \ + } \ + while (_len > 0); \ + } while (false) +#else +# define memset_space(P, Len) memset ((P), ' ', (size_t) (Len)) +#endif + +#define add(n, f) \ + do \ + { \ + int _n = (n); \ + int _delta = width - _n; \ + int _incr = _n + (_delta > 0 ? _delta : 0); \ + if (i + _incr >= maxsize) \ + return 0; \ + if (p) \ + { \ + if (_delta > 0) \ + memset_space (p, _delta); \ + f; \ + p += _n; \ + } \ + i += _incr; \ + } while (false) + +#define cpy(n, s) \ + add ((n), \ + if (to_lowcase) \ + memcpy_lowcase (p, (s), (size_t) _n); \ + else if (to_uppcase) \ + memcpy_uppcase (p, (s), (size_t) _n); \ + else \ + memcpy ((PTR) p, (PTR) (s), (size_t) _n)) + + + +#ifdef _LIBC +# define TOUPPER(Ch) toupper (Ch) +# define TOLOWER(Ch) tolower (Ch) +#else +# define TOUPPER(Ch) (islower (Ch) ? toupper (Ch) : (Ch)) +# define TOLOWER(Ch) (isupper (Ch) ? tolower (Ch) : (Ch)) +#endif +/* We don't use `isdigit' here since the locale dependent + interpretation is not what we want here. We only need to accept + the arabic digits in the ASCII range. One day there is perhaps a + more reliable way to accept other sets of digits. */ +#define ISDIGIT(Ch) ((unsigned int) (Ch) - '0' <= 9) + +static char *memcpy_lowcase __P ((char *dest, char const *src, size_t len)); + +static char * +memcpy_lowcase (char *dest, char const *src, size_t len) +{ + while (len-- > 0) + dest[len] = TOLOWER (src[len]); + return dest; +} + +static char *memcpy_uppcase __P ((char *dest, char const *src, size_t len)); + +static char * +memcpy_uppcase (char *dest, char const *src, size_t len) +{ + while (len-- > 0) + dest[len] = TOUPPER (src[len]); + return dest; +} + +#if ! HAVE_TM_GMTOFF +/* Yield the difference between *A and *B, + measured in seconds, ignoring leap seconds. */ +static int tm_diff __P ((const struct tm *, const struct tm *)); +static int +tm_diff (const struct tm *a, const struct tm *b) +{ + /* Compute intervening leap days correctly even if year is negative. + Take care to avoid int overflow in leap day calculations, + but it's OK to assume that A and B are close to each other. */ + int a4 = (a->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (a->tm_year & 3); + int b4 = (b->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (b->tm_year & 3); + int a100 = a4 / 25 - (a4 % 25 < 0); + int b100 = b4 / 25 - (b4 % 25 < 0); + int a400 = a100 >> 2; + int b400 = b100 >> 2; + int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400); + int years = a->tm_year - b->tm_year; + int days = (365 * years + intervening_leap_days + + (a->tm_yday - b->tm_yday)); + return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour)) + + (a->tm_min - b->tm_min)) + + (a->tm_sec - b->tm_sec)); +} +#endif /* ! HAVE_TM_GMTOFF */ + + + +/* The number of days from the first day of the first ISO week of this + year to the year day YDAY with week day WDAY. ISO weeks start on + Monday; the first ISO week has the year's first Thursday. YDAY may + be as small as YDAY_MINIMUM. */ +#define ISO_WEEK_START_WDAY 1 /* Monday */ +#define ISO_WEEK1_WDAY 4 /* Thursday */ +#define YDAY_MINIMUM (-366) +static int iso_week_days __P ((int, int)); +#ifdef __GNUC__ +inline +#endif +static int +iso_week_days (int yday, int wday) +{ + /* Add enough to the first operand of % to make it nonnegative. */ + int big_enough_multiple_of_7 = (-YDAY_MINIMUM / 7 + 2) * 7; + return (yday + - (yday - wday + ISO_WEEK1_WDAY + big_enough_multiple_of_7) % 7 + + ISO_WEEK1_WDAY - ISO_WEEK_START_WDAY); +} + + +#ifndef _NL_CURRENT +static char const weekday_name[][10] = + { + "Sunday", "Monday", "Tuesday", "Wednesday", + "Thursday", "Friday", "Saturday" + }; +static char const month_name[][10] = + { + "January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December" + }; +#endif + + +#if !defined _LIBC && HAVE_TZNAME && HAVE_TZSET + /* Solaris 2.5 tzset sometimes modifies the storage returned by localtime. + Work around this bug by copying *tp before it might be munged. */ + size_t _strftime_copytm __P ((char *, size_t, char const *, + const struct tm *)); + size_t + strftime (s, maxsize, format, tp) + char *s; + size_t maxsize; + char const *format; + const struct tm *tp; + { + struct tm tmcopy; + tmcopy = *tp; + return _strftime_copytm (s, maxsize, format, &tmcopy); +} +# ifdef strftime +# undef strftime +# endif +# define strftime _strftime_copytm +#endif + + + +/* Write information from TP into S according to the format + string FORMAT, writing no more that MAXSIZE characters + (including the terminating '\0') and returning number of + characters written. If S is NULL, nothing will be written + anywhere, so to determine how many characters would be + written, use NULL for S and (size_t) UINT_MAX for MAXSIZE. */ +size_t +strftime (char *s, size_t maxsize, char const *format, const struct tm *tp) +{ + int hour12 = tp->tm_hour; +#ifdef _NL_CURRENT + char const *const a_wkday = _NL_CURRENT (LC_TIME, ABDAY_1 + tp->tm_wday); + char const *const f_wkday = _NL_CURRENT (LC_TIME, DAY_1 + tp->tm_wday); + char const *const a_month = _NL_CURRENT (LC_TIME, ABMON_1 + tp->tm_mon); + char const *const f_month = _NL_CURRENT (LC_TIME, MON_1 + tp->tm_mon); + char const *const ampm = _NL_CURRENT (LC_TIME, + hour12 > 11 ? PM_STR : AM_STR); + size_t aw_len = strlen (a_wkday); + size_t am_len = strlen (a_month); + size_t ap_len = strlen (ampm); +#else + char const *const f_wkday = weekday_name[tp->tm_wday]; + char const *const f_month = month_name[tp->tm_mon]; + char const *const a_wkday = f_wkday; + char const *const a_month = f_month; + char const *const ampm = "AMPM" + 2 * (hour12 > 11); + size_t aw_len = 3; + size_t am_len = 3; + size_t ap_len = 2; +#endif + size_t wkday_len = strlen (f_wkday); + size_t month_len = strlen (f_month); + char const *zone; + size_t zonelen; + size_t i = 0; + char *p = s; + char const *f; + + zone = NULL; +#if !defined _LIBC && HAVE_TM_ZONE + /* XXX We have some problems here. First, the string pointed to by + tm_zone is dynamically allocated while loading the zone data. But + when another zone is loaded since the information in TP were + computed this would be a stale pointer. + The second problem is the POSIX test suite which assumes setting + the environment variable TZ to a new value before calling strftime() + will influence the result (the %Z format) even if the information in + TP is computed with a totally different time zone. --drepper@gnu */ + zone = (char const *) tp->tm_zone; +#endif +#if HAVE_TZNAME + /* POSIX.1 8.1.1 requires that whenever strftime() is called, the + time zone names contained in the external variable `tzname' shall + be set as if the tzset() function had been called. */ +# if HAVE_TZSET + tzset (); +# endif + + if (!(zone && *zone) && tp->tm_isdst >= 0) + zone = tzname[tp->tm_isdst]; +#endif + if (! zone) + zone = ""; /* POSIX.2 requires the empty string here. */ + + zonelen = strlen (zone); + + if (hour12 > 12) + hour12 -= 12; + else + if (hour12 == 0) hour12 = 12; + + for (f = format; *f != '\0'; ++f) + { + int pad; /* Padding for number ('-', '_', or 0). */ + int modifier; /* Field modifier ('E', 'O', or 0). */ + int digits; /* Max digits for numeric format. */ + int number_value; /* Numeric value to be printed. */ + int negative_number; /* 1 if the number is negative. */ + char const *subfmt; + char *bufp; + char buf[1 + (sizeof (int) < sizeof (time_t) + ? INT_STRLEN_BOUND (time_t) + : INT_STRLEN_BOUND (int))]; + int width = -1; + int to_lowcase = 0; + int to_uppcase = 0; + +#if DO_MULTIBYTE + + switch (*f) + { + case '%': + break; + +#if __STDC__ + case '\a': +#else + case 7: /* '\a' is ASCII decimal value 7. */ +#endif + case '\b': case '\t': case '\n': + case '\v': case '\f': case '\r': + case ' ': case '!': case '"': case '#': case '&': case'\'': + case '(': case ')': case '*': case '+': case ',': case '-': + case '.': case '/': case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': case '8': case '9': + case ':': case ';': case '<': case '=': case '>': case '?': + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': + case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': + case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': + case 'Y': case 'Z': case '[': case'\\': case ']': case '^': + case '_': case 'a': case 'b': case 'c': case 'd': case 'e': + case 'f': case 'g': case 'h': case 'i': case 'j': case 'k': + case 'l': case 'm': case 'n': case 'o': case 'p': case 'q': + case 'r': case 's': case 't': case 'u': case 'v': case 'w': + case 'x': case 'y': case 'z': case '{': case '|': case '}': + case '~': + /* The C Standard requires these 98 characters (plus '%') to + be in the basic execution character set. None of these + characters can start a multibyte sequence, so they need + not be analyzed further. */ + add (1, *p = *f); + continue; + + default: + /* Copy this multibyte sequence until we reach its end, find + an error, or come back to the initial shift state. */ + { + mbstate_t mbstate = mbstate_zero; + size_t len = 0; + + do + { + size_t bytes = mbrlen (f + len, (size_t) -1, &mbstate); + + if (bytes == 0) + break; + + if (bytes == (size_t) -2 || bytes == (size_t) -1) + { + len++; + break; + } + + len += bytes; + } + while (! mbsinit (&mbstate)); + + cpy (len, f); + continue; + } + } + +#else /* ! DO_MULTIBYTE */ + + /* Either multibyte encodings are not supported, or they are + safe for formats, so any non-'%' byte can be copied through. */ + if (*f != '%') + { + add (1, *p = *f); + continue; + } + +#endif /* ! DO_MULTIBYTE */ + + /* Check for flags that can modify a format. */ + pad = 0; + while (1) + { + switch (*++f) + { + /* This influences the number formats. */ + case '_': + case '-': + case '0': + pad = *f; + continue; + + /* This changes textual output. */ + case '^': + to_uppcase = 1; + continue; + + default: + break; + } + break; + } + + /* As a GNU extension we allow to specify the field width. */ + if (ISDIGIT (*f)) + { + width = 0; + do + { + width *= 10; + width += *f - '0'; + ++f; + } + while (ISDIGIT (*f)); + } + + /* Check for modifiers. */ + switch (*f) + { + case 'E': + case 'O': + modifier = *f++; + break; + + default: + modifier = 0; + break; + } + + /* Now do the specified format. */ + switch (*f) + { +#define DO_NUMBER(d, v) \ + digits = d; number_value = v; goto do_number +#define DO_NUMBER_SPACEPAD(d, v) \ + digits = d; number_value = v; goto do_number_spacepad + + case '%': + if (modifier != 0) + goto bad_format; + add (1, *p = *f); + break; + + case 'a': + if (modifier != 0) + goto bad_format; + cpy (aw_len, a_wkday); + break; + + case 'A': + if (modifier != 0) + goto bad_format; + cpy (wkday_len, f_wkday); + break; + + case 'b': + case 'h': /* POSIX.2 extension. */ + if (modifier != 0) + goto bad_format; + cpy (am_len, a_month); + break; + + case 'B': + if (modifier != 0) + goto bad_format; + cpy (month_len, f_month); + break; + + case 'c': + if (modifier == 'O') + goto bad_format; +#ifdef _NL_CURRENT + if (! (modifier == 'E' + && *(subfmt = _NL_CURRENT (LC_TIME, ERA_D_T_FMT)) != '\0')) + subfmt = _NL_CURRENT (LC_TIME, D_T_FMT); +#else + subfmt = "%a %b %e %H:%M:%S %Y"; +#endif + + subformat: + { + char *old_start = p; + size_t len = strftime (NULL, maxsize - i, subfmt, tp); + if (len == 0 && *subfmt) + return 0; + add (len, strftime (p, maxsize - i, subfmt, tp)); + + if (to_uppcase) + while (old_start < p) + { + *old_start = TOUPPER (*old_start); + ++old_start; + } + } + break; + + case 'C': /* POSIX.2 extension. */ + if (modifier == 'O') + goto bad_format; +#if HAVE_STRUCT_ERA_ENTRY + if (modifier == 'E') + { + struct era_entry *era = _nl_get_era_entry (tp); + if (era) + { + size_t len = strlen (era->name_fmt); + cpy (len, era->name_fmt); + break; + } + } +#endif + { + int year = tp->tm_year + TM_YEAR_BASE; + DO_NUMBER (1, year / 100 - (year % 100 < 0)); + } + + case 'x': + if (modifier == 'O') + goto bad_format; +#ifdef _NL_CURRENT + if (! (modifier == 'E' + && *(subfmt = _NL_CURRENT (LC_TIME, ERA_D_FMT)) != '\0')) + subfmt = _NL_CURRENT (LC_TIME, D_FMT); + goto subformat; +#endif + /* Fall through. */ + case 'D': /* POSIX.2 extension. */ + if (modifier != 0) + goto bad_format; + subfmt = "%m/%d/%y"; + goto subformat; + + case 'd': + if (modifier == 'E') + goto bad_format; + + DO_NUMBER (2, tp->tm_mday); + + case 'e': /* POSIX.2 extension. */ + if (modifier == 'E') + goto bad_format; + + DO_NUMBER_SPACEPAD (2, tp->tm_mday); + + /* All numeric formats set DIGITS and NUMBER_VALUE and then + jump to one of these two labels. */ + + do_number_spacepad: + /* Force `_' flag unless overwritten by `0' flag. */ + if (pad != '0') + pad = '_'; + + do_number: + /* Format the number according to the MODIFIER flag. */ + +#ifdef _NL_CURRENT + if (modifier == 'O' && 0 <= number_value) + { + /* Get the locale specific alternate representation of + the number NUMBER_VALUE. If none exist NULL is returned. */ + char const *cp = _nl_get_alt_digit (number_value); + + if (cp != NULL) + { + size_t digitlen = strlen (cp); + if (digitlen != 0) + { + cpy (digitlen, cp); + break; + } + } + } +#endif + { + unsigned int u = number_value; + + bufp = buf + sizeof (buf); + negative_number = number_value < 0; + + if (negative_number) + u = -u; + + do + *--bufp = u % 10 + '0'; + while ((u /= 10) != 0); + } + + do_number_sign_and_padding: + if (negative_number) + *--bufp = '-'; + + if (pad != '-') + { + int padding = digits - (buf + sizeof (buf) - bufp); + + if (pad == '_') + { + while (0 < padding--) + *--bufp = ' '; + } + else + { + bufp += negative_number; + while (0 < padding--) + *--bufp = '0'; + if (negative_number) + *--bufp = '-'; + } + } + + cpy (buf + sizeof (buf) - bufp, bufp); + break; + + + case 'H': + if (modifier == 'E') + goto bad_format; + + DO_NUMBER (2, tp->tm_hour); + + case 'I': + if (modifier == 'E') + goto bad_format; + + DO_NUMBER (2, hour12); + + case 'k': /* GNU extension. */ + if (modifier == 'E') + goto bad_format; + + DO_NUMBER_SPACEPAD (2, tp->tm_hour); + + case 'l': /* GNU extension. */ + if (modifier == 'E') + goto bad_format; + + DO_NUMBER_SPACEPAD (2, hour12); + + case 'j': + if (modifier == 'E') + goto bad_format; + + DO_NUMBER (3, 1 + tp->tm_yday); + + case 'M': + if (modifier == 'E') + goto bad_format; + + DO_NUMBER (2, tp->tm_min); + + case 'm': + if (modifier == 'E') + goto bad_format; + + DO_NUMBER (2, tp->tm_mon + 1); + + case 'n': /* POSIX.2 extension. */ + add (1, *p = '\n'); + break; + + case 'P': + to_lowcase = 1; + /* FALLTHROUGH */ + + case 'p': + cpy (ap_len, ampm); + break; + + case 'R': /* GNU extension. */ + subfmt = "%H:%M"; + goto subformat; + + case 'r': /* POSIX.2 extension. */ +#ifdef _NL_CURRENT + if (*(subfmt = _NL_CURRENT (LC_TIME, T_FMT_AMPM)) == '\0') +#endif + subfmt = "%I:%M:%S %p"; + goto subformat; + + case 'S': + if (modifier == 'E') + goto bad_format; + + DO_NUMBER (2, tp->tm_sec); + + case 's': /* GNU extension. */ + { + struct tm ltm; + time_t t; + + ltm = *tp; + t = mktime (<m); + + /* Generate string value for T using time_t arithmetic; + this works even if sizeof (long) < sizeof (time_t). */ + + bufp = buf + sizeof (buf); + negative_number = t < 0; + + do + { + int d = t % 10; + t /= 10; + + if (negative_number) + { + d = -d; + + /* Adjust if division truncates to minus infinity. */ + if (0 < -1 % 10 && d < 0) + { + t++; + d += 10; + } + } + + *--bufp = d + '0'; + } + while (t != 0); + + digits = 1; + goto do_number_sign_and_padding; + } + + case 'X': + if (modifier == 'O') + goto bad_format; +#ifdef _NL_CURRENT + if (! (modifier == 'E' + && *(subfmt = _NL_CURRENT (LC_TIME, ERA_T_FMT)) != '\0')) + subfmt = _NL_CURRENT (LC_TIME, T_FMT); + goto subformat; +#endif + /* Fall through. */ + case 'T': /* POSIX.2 extension. */ + subfmt = "%H:%M:%S"; + goto subformat; + + case 't': /* POSIX.2 extension. */ + add (1, *p = '\t'); + break; + + case 'u': /* POSIX.2 extension. */ + DO_NUMBER (1, (tp->tm_wday - 1 + 7) % 7 + 1); + + case 'U': + if (modifier == 'E') + goto bad_format; + + DO_NUMBER (2, (tp->tm_yday - tp->tm_wday + 7) / 7); + + case 'V': + case 'g': /* GNU extension. */ + case 'G': /* GNU extension. */ + if (modifier == 'E') + goto bad_format; + { + int year = tp->tm_year + TM_YEAR_BASE; + int days = iso_week_days (tp->tm_yday, tp->tm_wday); + + if (days < 0) + { + /* This ISO week belongs to the previous year. */ + year--; + days = iso_week_days (tp->tm_yday + (365 + __isleap (year)), + tp->tm_wday); + } + else + { + int d = iso_week_days (tp->tm_yday - (365 + __isleap (year)), + tp->tm_wday); + if (0 <= d) + { + /* This ISO week belongs to the next year. */ + year++; + days = d; + } + } + + switch (*f) + { + case 'g': + DO_NUMBER (2, (year % 100 + 100) % 100); + + case 'G': + DO_NUMBER (1, year); + + default: + DO_NUMBER (2, days / 7 + 1); + } + } + + case 'W': + if (modifier == 'E') + goto bad_format; + + DO_NUMBER (2, (tp->tm_yday - (tp->tm_wday - 1 + 7) % 7 + 7) / 7); + + case 'w': + if (modifier == 'E') + goto bad_format; + + DO_NUMBER (1, tp->tm_wday); + + case 'Y': +#if HAVE_STRUCT_ERA_ENTRY + if (modifier == 'E') + { + struct era_entry *era = _nl_get_era_entry (tp); + if (era) + { + subfmt = strchr (era->name_fmt, '\0') + 1; + goto subformat; + } + } +#endif + if (modifier == 'O') + goto bad_format; + else + DO_NUMBER (1, tp->tm_year + TM_YEAR_BASE); + + case 'y': +#if HAVE_STRUCT_ERA_ENTRY + if (modifier == 'E') + { + struct era_entry *era = _nl_get_era_entry (tp); + if (era) + { + int delta = tp->tm_year - era->start_date[0]; + DO_NUMBER (1, (era->offset + + (era->direction == '-' ? -delta : delta))); + } + } +#endif + DO_NUMBER (2, (tp->tm_year % 100 + 100) % 100); + + case 'Z': + cpy (zonelen, zone); + break; + + case 'z': /* GNU extension. */ + if (tp->tm_isdst < 0) + break; + + { + int diff; +#if HAVE_TM_GMTOFF + diff = tp->tm_gmtoff; +#else + struct tm gtm; + struct tm ltm; + time_t lt; + + ltm = *tp; + lt = mktime (<m); + + if (lt == (time_t) -1) + { + /* mktime returns -1 for errors, but -1 is also a + valid time_t value. Check whether an error really + occurred. */ + struct tm tm; + localtime_r (<, &tm); + + if ((ltm.tm_sec ^ tm.tm_sec) + | (ltm.tm_min ^ tm.tm_min) + | (ltm.tm_hour ^ tm.tm_hour) + | (ltm.tm_mday ^ tm.tm_mday) + | (ltm.tm_mon ^ tm.tm_mon) + | (ltm.tm_year ^ tm.tm_year)) + break; + } + + if (! gmtime_r (<, >m)) + break; + + diff = tm_diff (<m, >m); +#endif + + if (diff < 0) + { + add (1, *p = '-'); + diff = -diff; + } + else + add (1, *p = '+'); + + diff /= 60; + DO_NUMBER (4, (diff / 60) * 100 + diff % 60); + } + + case '\0': /* GNU extension: % at end of format. */ + --f; + /* Fall through. */ + default: + /* Unknown format; output the format, including the '%', + since this is most likely the right thing to do if a + multibyte string has been misparsed. */ + bad_format: + { + int flen; + for (flen = 1; f[1 - flen] != '%'; flen++) + continue; + cpy (flen, &f[1 - flen]); + } + break; + } + } + + if (p) + *p = '\0'; + return i; +} + +/* + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of compat/strftime.c */ diff --git a/compat/strsignal.c b/compat/strsignal.c new file mode 100644 index 0000000..7d785ee --- /dev/null +++ b/compat/strsignal.c @@ -0,0 +1,119 @@ + +/** + * \file strsignal.c + * + * This file is part of AutoGen. + * + * AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoGen is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AutoGen is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + * + * As a special exception, Bruce Korb gives permission for additional + * uses of the text contained in the release of strsignal. + * + * The exception is that, if you link the strsignal library with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the strsignal library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by Bruce Korb under + * the name strsignal. If you copy code from other sources under the + * General Public License into a copy of strsignal, as the General Public + * License permits, the exception does not apply to the code that you add + * in this way. To avoid misleading anyone as to the status of such + * modified files, you must delete this exception notice from them. + * + * If you write modifications of your own for strsignal, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + */ + +#include "compat.h" + +/* Routines imported from standard C runtime libraries. */ + +#if ! defined(HAVE_STRSIGNAL) + +#ifdef __STDC__ +# include +#else /* !__STDC__ */ +# ifndef const +# define const +# endif +#endif /* __STDC__ */ + +#ifdef HAVE_SYS_SIGLIST +# include +#endif + +/* + * Import the generated tables + */ +#include "strsignal.h" +#endif + +#ifndef HAVE_STRSIGNAL + +/* + +NAME + + strsignal -- map a signal number to a signal message string + +SYNOPSIS + + char *strsignal (int signo) + +DESCRIPTION + + Maps an signal number to an signal message string, the contents of + which are implementation defined. On systems which have the external + variable sys_siglist, these strings will be the same as the ones used + by psignal(). + + If the supplied signal number is within the valid range of indices + for the sys_siglist, but no message is available for the particular + signal number, then returns the string "Signal NUM", where NUM is the + signal number. + + If the supplied signal number is not a valid index into sys_siglist, + returns NULL. + + The returned string is only guaranteed to be valid only until the + next call to strsignal. + + Also, though not declared "const", it is. +*/ + +char * +strsignal( int signo ) +{ + if (SIGNAL_IN_RANGE( signo )) + return (char *)SIGNAL_INFO( signo ); + + return NULL; +} +#endif /* HAVE_STRSIGNAL */ + +/* + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of compat/strsignal.c */ diff --git a/compat/strsignal.def b/compat/strsignal.def new file mode 100644 index 0000000..19f2f0e --- /dev/null +++ b/compat/strsignal.def @@ -0,0 +1,151 @@ +autogen definitions strsignal; + +/* + * Dynamic definitions for creating the strsignal.h header file + * + * This file is part of AutoGen. + * + * AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoGen is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AutoGen is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#shell + +RE_sigfind=$'[A-Z12]+[ \t]+[1-9][0-9]*' +RE_sigdef=$'^#[ \t]*define[ \t][ \t]*_*SIG' +RE_inc=$'^#[ \t]*include[ \t][ \t]*<' + +threshold=5 # minimum number of signals to accept +num=0 # number of signals defined in this file +seen="" # include files already searched +files="sys/signal.h" # initial files to search + +cd /usr/include +while test -n "$files" +do + for file in $files; do + # look for $threshold or more matches in one of the search files + test -f $file || continue + sigs=`egrep "$RE_sigdef$RE_sigfind" $file|sed "s,$RE_sigdef,,"` + test -z "$sigs" || num=`echo "$sigs" | wc -l` + test $num -lt $threshold || break + seen="$file $seen" + done + test $num -lt $threshold || break + + # IF no file has $threshold or better SIG matches; + # generate a new search list from all files #included from the old list + newfiles="" + for file in $files; do + test -f $file || continue + new=`egrep "$RE_inc" $file|sed "s,$RE_inc,,"';s,>.*$,,'` + newfiles=" $new $newfiles" + done + + # remove any files that have been searched previously + for file in $seen; do + newfiles=`echo "$newfiles"|sed "s, $file , ,g"` + done + + # set the search list for the next iteration + files="$newfiles" + num=0 +done + +if test $num -lt $threshold +then + echo "WARNING: cannot find signal definitions in $seen" >&2 + echo "using POSIX + ANSI signal definitions" >&2 + cat <<- _EOF_ + signal[ 1 ] = { signame = SIGHUP; + sigtext = "Hangup (POSIX)."; }; + signal[ 2 ] = { signame = SIGINT; + sigtext = "Interrupt (ANSI)."; }; + signal[ 3 ] = { signame = SIGQUIT; + sigtext = "Quit (POSIX)."; }; + signal[ 4 ] = { signame = SIGILL; + sigtext = "Illegal instruction (ANSI)."; }; + signal[ 5 ] = { signame = SIGTRAP; + sigtext = "Trace trap (POSIX)."; }; + signal[ 6 ] = { signame = SIGABRT; + sigtext = "Abort (ANSI)."; }; + signal[ 8 ] = { signame = SIGFPE; + sigtext = "Floating-point exception (ANSI)."; }; + signal[ 9 ] = { signame = SIGKILL; + sigtext = "Kill, unblockable (POSIX)."; }; + signal[ 10 ] = { signame = SIGUSR1; + sigtext = "User-defined signal 1 (POSIX)."; }; + signal[ 11 ] = { signame = SIGSEGV; + sigtext = "Segmentation violation (ANSI)."; }; + signal[ 12 ] = { signame = SIGUSR2; + sigtext = "User-defined signal 2 (POSIX)."; }; + signal[ 13 ] = { signame = SIGPIPE; + sigtext = "Broken pipe (POSIX)."; }; + signal[ 14 ] = { signame = SIGALRM; + sigtext = "Alarm clock (POSIX)."; }; + signal[ 15 ] = { signame = SIGTERM; + sigtext = "Termination (ANSI)."; }; + signal[ 17 ] = { signame = SIGCHLD; + sigtext = "Child status has changed (POSIX)."; }; + signal[ 18 ] = { signame = SIGCONT; + sigtext = "Continue (POSIX)."; }; + signal[ 19 ] = { signame = SIGSTOP; + sigtext = "Stop, unblockable (POSIX)."; }; + signal[ 20 ] = { signame = SIGTSTP; + sigtext = "Keyboard stop (POSIX)."; }; + signal[ 21 ] = { signame = SIGTTIN; + sigtext = "Background read from tty (POSIX)."; }; + signal[ 22 ] = { signame = SIGTTOU; + sigtext = "Background write to tty (POSIX)."; }; +_EOF_ + +else + echo "$sigs" | + while read SIG NUM f + do + # IF the "signal number" is octal or hex or non-numeric, + # THEN we know it is a value we are not interested in + # + case ${NUM} in + *[A-Za-z_]* ) + continue ;; + esac + + # Sometimes, there are aliases. Accept only the first. + # + if eval test ! -z \"\$HAVE_${NUM}\" + then continue ; fi + + # We also know we are not interested in super large numbers + # (e.g. SIGSTKSZ 8192) + # + if test ${NUM} -gt 127 + then continue ; fi + + eval HAVE_${NUM}=1 + f=`echo "$f" | sed -e 's;/\*[ ]*;;' -e 's;[ ]*\*/;;'` + if test -z "$f" + then f="Undescribed: SIG${SIG} (${NUM})" ; fi + + cat <<- _EOF_ + signal[ ${NUM} ] = { + signame = ${SIG}; + sigtext = "$f"; + }; + + _EOF_ + done +fi +#endshell diff --git a/compat/strsignal.h b/compat/strsignal.h new file mode 100644 index 0000000..466bf15 --- /dev/null +++ b/compat/strsignal.h @@ -0,0 +1,96 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * DO NOT EDIT THIS FILE (strsignal.h) + * + * It has been AutoGen-ed + * From the definitions strsignal.def + * and the template file strsignal + * + * Generated for a 4.15.0-20-generic Linux platform + * + * strsignal Copyright (C) 1992-2017 by Bruce Korb - all rights reserved + * + * AutoGen is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AutoGen is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ +#ifndef MAX_SIGNAL_NUMBER +#define MAX_SIGNAL_NUMBER 22 +#define SIGNAL_IN_RANGE(s) (((unsigned)s) <= MAX_SIGNAL_NUMBER) +#define SIGNAL_NAME(s) (zSigNames + sigNameOffset[s]) +#define SIGNAL_INFO(s) (zSigInfo + sigInfoOffset[s]) + +static char const zSigNames[] = + "INVALID\0" "SIGSIGHUP\0" "SIGSIGINT\0" "SIGSIGQUIT\0" "SIGSIGILL\0" + "SIGSIGTRAP\0" "SIGSIGABRT\0" "SIGSIGFPE\0" "SIGSIGKILL\0" "SIGSIGUSR1\0" + "SIGSIGSEGV\0" "SIGSIGUSR2\0" "SIGSIGPIPE\0" "SIGSIGALRM\0" "SIGSIGTERM\0" + "SIGSIGCHLD\0" "SIGSIGCONT\0" "SIGSIGSTOP\0" "SIGSIGTSTP\0" "SIGSIGTTIN\0" + "SIGSIGTTOU\0"; + +static const unsigned int sigNameOffset[] = { + 0, 8, 18, 28, 39, 49, 60, 0, 71, 81, 92, 103, 114, 125, 136, + 147, 0, 158, 169, 180, 191, 202, 213 }; + +#ifndef HAVE_SYS_SIGLIST +static char const zSigInfo[] = + /* 0 */ "Signal 0 invalid\0" + /* 1 */ "Hangup (POSIX).\0" + /* 2 */ "Interrupt (ANSI).\0" + /* 3 */ "Quit (POSIX).\0" + /* 4 */ "Illegal instruction (ANSI).\0" + /* 5 */ "Trace trap (POSIX).\0" + /* 6 */ "Abort (ANSI).\0" + /* 7 */ "Signal 7 invalid\0" + /* 8 */ "Floating-point exception (ANSI).\0" + /* 9 */ "Kill, unblockable (POSIX).\0" + /* 10 */ "User-defined signal 1 (POSIX).\0" + /* 11 */ "Segmentation violation (ANSI).\0" + /* 12 */ "User-defined signal 2 (POSIX).\0" + /* 13 */ "Broken pipe (POSIX).\0" + /* 14 */ "Alarm clock (POSIX).\0" + /* 15 */ "Termination (ANSI).\0" + /* 16 */ "Signal 16 invalid\0" + /* 17 */ "Child status has changed (POSIX).\0" + /* 18 */ "Continue (POSIX).\0" + /* 19 */ "Stop, unblockable (POSIX).\0" + /* 20 */ "Keyboard stop (POSIX).\0" + /* 21 */ "Background read from tty (POSIX).\0" + /* 22 */ "Background write to tty (POSIX).\0"; + +static const unsigned int sigInfoOffset[] = { + 0, 17, 33, 51, 65, 93, 113, 127, 144, 177, 204, 235, 266, 297, 318, + 339, 359, 377, 411, 429, 456, 479, 513 }; + +#endif /* MAX_SIGNAL_NUMBER */ + +#ifndef HAVE_STRSIGNAL +extern char * strsignal( int signo ); +#endif + +#ifdef DEBUG_STRSIGNAL +#include + +int +main(int argc, char ** argv) +{ + int sig = 0; + fputs( "Sig Sig-Name Description\n" + "=== ======== ===========\n", stdout ); + do { + printf( "%3d %-10s %s\n", sig, SIGNAL_NAME(sig), + SIGNAL_INFO(sig) ); + ++sig; + } while (SIGNAL_IN_RANGE(sig)); + return 0; +} +#endif /* DEBUG */ +#endif /* MAX_SIGNAL_NUMBER */ diff --git a/compat/strsignal.tpl b/compat/strsignal.tpl new file mode 100644 index 0000000..87e6243 --- /dev/null +++ b/compat/strsignal.tpl @@ -0,0 +1,126 @@ +[= AutoGen5 template -*- Mode: html -*- + +h + +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . + +(setenv "SHELL" "/bin/sh") + +=] +[=(dne " * " "/* ")=] + * + * Generated for a [=`uname -r`=] [=`uname`=] platform + * + * strsignal Copyright (C) 1992-2017 by Bruce Korb - all rights reserved + * +[=(gpl "AutoGen" " * ")=] + */ +#ifndef MAX_SIGNAL_NUMBER +#define MAX_SIGNAL_NUMBER [= (high-lim "signal") =] +#define SIGNAL_IN_RANGE(s) (((unsigned)s) <= MAX_SIGNAL_NUMBER) +#define SIGNAL_NAME(s) (zSigNames + sigNameOffset[s]) +#define SIGNAL_INFO(s) (zSigInfo + sigInfoOffset[s])[= + +(define sig-names "\"INVALID\\0\"\n") +(define name-refs "") +(define name-ix (- (string-length sig-names) 4)) +(define tmp-text "") + +(define sig-info "") +(define info-refs "") +(define info-ix 0) + +(define add-string (lambda() + (if (exist? "signame") + (begin + (set! tmp-text (string-append "\"SIG" (get "signame") "\\0\"\n")) + (set! sig-names (string-append sig-names tmp-text)) + (set! name-refs (string-append name-refs + (sprintf "%d\n" name-ix) )) + (set! name-ix (+ name-ix (string-length tmp-text) -4)) + + (set! tmp-text (sprintf "/* %3d */ \"%s\\0\"\n" + (for-index) (get "sigtext"))) + ) + + (begin + (set! name-refs (string-append name-refs "0\n")) + (set! tmp-text (sprintf "/* %1$3d */ \"Signal %1$d invalid\\0\"\n" + (for-index))) + ) ) + + (set! sig-info (string-append sig-info tmp-text)) + (set! info-refs (string-append info-refs + (sprintf "%d\n" info-ix) )) + (set! info-ix (+ info-ix (string-length tmp-text) -14)) +)) =][= + +FOR signal (for-from 0) (for-by 1) =][= + + (add-string) =][= + +ENDFOR signal =] + +static char const zSigNames[] = +[=(shell (string-append + "columns -I4 --spread=1 <<'_EOF_'\n" + sig-names + "_EOF_" )) =]; + +static const unsigned int sigNameOffset[] = { +[=(shell (string-append + "columns -I4 -S, --spread=1 <<'_EOF_'\n" + name-refs + "_EOF_" )) =] }; + +#ifndef HAVE_SYS_SIGLIST +static char const zSigInfo[] = +[=(shell (string-append + "columns -I4 --spread=1 <<'_EOF_'\n" + sig-info + "_EOF_" )) =]; + +static const unsigned int sigInfoOffset[] = { +[=(shell (string-append + "columns -I4 -S, --spread=1 <<'_EOF_'\n" + info-refs + "_EOF_" )) =] }; + +#endif /* MAX_SIGNAL_NUMBER */ + +#ifndef HAVE_STRSIGNAL +extern char * strsignal( int signo ); +#endif + +#ifdef DEBUG_STRSIGNAL +#include + +int +main(int argc, char ** argv) +{ + int sig = 0; + fputs( "Sig Sig-Name Description\n" + "=== ======== ===========\n", stdout ); + do { + printf( "%3d %-10s %s\n", sig, SIGNAL_NAME(sig), + SIGNAL_INFO(sig) ); + ++sig; + } while (SIGNAL_IN_RANGE(sig)); + return 0; +} +#endif /* DEBUG */ +#endif /* MAX_SIGNAL_NUMBER */ diff --git a/compat/unlocked-io.h b/compat/unlocked-io.h new file mode 100644 index 0000000..1fc1097 --- /dev/null +++ b/compat/unlocked-io.h @@ -0,0 +1,137 @@ +/* Prefer faster, non-thread-safe stdio functions if available. + + Copyright (C) 2001-2004, 2009-2012, 2014-2015, 2018 + Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* Written by Jim Meyering. */ + +#ifndef UNLOCKED_IO_H +# define UNLOCKED_IO_H 1 + +/* These are wrappers for functions/macros from the GNU C library, and + from other C libraries supporting POSIX's optional thread-safe functions. + + The standard I/O functions are thread-safe. These *_unlocked ones are + more efficient but not thread-safe. That they're not thread-safe is + fine since all of the applications in this package are single threaded. + + Also, some code that is shared with the GNU C library may invoke + the *_unlocked functions directly. On hosts that lack those + functions, invoke the non-thread-safe versions instead. */ + +# include + +# if HAVE_DECL_CLEARERR_UNLOCKED +# undef clearerr +# define clearerr(x) clearerr_unlocked (x) +# else +# define clearerr_unlocked(x) clearerr (x) +# endif + +# if HAVE_DECL_FEOF_UNLOCKED +# undef feof +# define feof(x) feof_unlocked (x) +# else +# define feof_unlocked(x) feof (x) +# endif + +# if HAVE_DECL_FERROR_UNLOCKED +# undef ferror +# define ferror(x) ferror_unlocked (x) +# else +# define ferror_unlocked(x) ferror (x) +# endif + +# if HAVE_DECL_FFLUSH_UNLOCKED +# undef fflush +# define fflush(x) fflush_unlocked (x) +# else +# define fflush_unlocked(x) fflush (x) +# endif + +# if HAVE_DECL_FGETS_UNLOCKED +# undef fgets +# define fgets(x,y,z) fgets_unlocked (x,y,z) +# else +# define fgets_unlocked(x,y,z) fgets (x,y,z) +# endif + +# if HAVE_DECL_FPUTC_UNLOCKED +# undef fputc +# define fputc(x,y) fputc_unlocked (x,y) +# else +# define fputc_unlocked(x,y) fputc (x,y) +# endif + +# if HAVE_DECL_FPUTS_UNLOCKED +# undef fputs +# define fputs(x,y) fputs_unlocked (x,y) +# else +# define fputs_unlocked(x,y) fputs (x,y) +# endif + +# if HAVE_DECL_FREAD_UNLOCKED +# undef fread +# define fread(w,x,y,z) fread_unlocked (w,x,y,z) +# else +# define fread_unlocked(w,x,y,z) fread (w,x,y,z) +# endif + +# if HAVE_DECL_FWRITE_UNLOCKED +# undef fwrite +# define fwrite(w,x,y,z) fwrite_unlocked (w,x,y,z) +# else +# define fwrite_unlocked(w,x,y,z) fwrite (w,x,y,z) +# endif + +# if HAVE_DECL_GETC_UNLOCKED +# undef getc +# define getc(x) getc_unlocked (x) +# else +# define getc_unlocked(x) getc (x) +# endif + +# if HAVE_DECL_GETCHAR_UNLOCKED +# undef getchar +# define getchar() getchar_unlocked () +# else +# define getchar_unlocked() getchar () +# endif + +# if HAVE_DECL_PUTC_UNLOCKED +# undef putc +# define putc(x,y) putc_unlocked (x,y) +# else +# define putc_unlocked(x,y) putc (x,y) +# endif + +# if HAVE_DECL_PUTCHAR_UNLOCKED +# undef putchar +# define putchar(x) putchar_unlocked (x) +# else +# define putchar_unlocked(x) putchar (x) +# endif + +# undef flockfile +# define flockfile(x) ((void) 0) + +# undef ftrylockfile +# define ftrylockfile(x) 0 + +# undef funlockfile +# define funlockfile(x) ((void) 0) + +#endif /* UNLOCKED_IO_H */ diff --git a/compat/windows-config.h b/compat/windows-config.h new file mode 100644 index 0000000..7ce1636 --- /dev/null +++ b/compat/windows-config.h @@ -0,0 +1,144 @@ + +/** + * \file windows-config.h + * + * This file contains all of the routines that must be linked into + * an executable to use the generated option processing. The optional + * routines are in separately compiled modules so that they will not + * necessarily be linked in. + * + * This file is part of AutoOpts, a companion to AutoGen. + * AutoOpts is free software. + * AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoOpts is available under any one of two licenses. The license + * in use must be one of these two and the choice is under the control + * of the user of the license. + * + * The GNU Lesser General Public License, version 3 or later + * See the files "COPYING.lgplv3" and "COPYING.gplv3" + * + * The Modified Berkeley Software Distribution License + * See the file "COPYING.mbsd" + * + * These files have the following sha256 sums: + * + * 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 + * 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 + * 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + */ + +#ifndef WINDOWS_CONFIG_HACKERY +#define WINDOWS_CONFIG_HACKERY 1 + +/* + * The definitions below have been stolen from NTP's config.h for Windows. + * However, they may be kept here in order to keep libopts independent from + * the NTP project. + */ +#ifndef __windows__ +# define __windows__ 4 +#endif + +/* + * Miscellaneous functions that Microsoft maps to other names + */ +#define snprintf _snprintf + +#define SIZEOF_INT 4 +#define SIZEOF_CHARP 4 +#define SIZEOF_LONG 4 +#define SIZEOF_SHORT 2 + +#define HAVE_LIMITS_H 1 +#define HAVE_STRDUP 1 +#define HAVE_STRCHR 1 +#define HAVE_FCNTL_H 1 + +/* + * VS.NET's version of wspiapi.h has a bug in it where it assigns a value + * to a variable inside an if statement. It should be comparing them. + * We prevent inclusion since we are not using this code so we don't have + * to see the warning messages + */ +#ifndef _WSPIAPI_H_ +#define _WSPIAPI_H_ +#endif + +/* Prevent inclusion of winsock.h in windows.h */ +#ifndef _WINSOCKAPI_ +#define _WINSOCKAPI_ +#endif + +#ifndef __RPCASYNC_H__ +#define __RPCASYNC_H__ +#endif + +/* Include Windows headers */ +#include +#include +#include + +/* + * Compatibility declarations for Windows, assuming SYS_WINNT + * has been defined. + */ +#define strdup _strdup +#define stat _stat /* struct stat from */ +#define unlink _unlink +#define fchmod( _x, _y ) +#define ssize_t SSIZE_T + +#include +#define open _open +#define close _close +#define read _read +#define write _write +#define lseek _lseek +#define pipe _pipe +#define dup2 _dup2 + +#define O_RDWR _O_RDWR +#define O_RDONLY _O_RDONLY +#define O_EXCL _O_EXCL + +#ifndef S_ISREG +# define S_IFREG _S_IFREG +# define S_ISREG(mode) (((mode) & S_IFREG) == S_IFREG) +#endif + +#ifndef S_ISDIR +# define S_IFDIR _S_IFDIR +# define S_ISDIR(mode) (((mode) & S_IFDIR) == S_IFDIR) +#endif + +/* C99 exact size integer support. */ +#if defined(HAVE_INTTYPES_H) +# include + +#elif defined(HAVE_STDINT_H) +# include +# define MISSING_INTTYPES_H 1 + +#elif ! defined(ADDED_EXACT_SIZE_INTEGERS) +# define ADDED_EXACT_SIZE_INTEGERS 1 +# define MISSING_INTTYPES_H 1 + + typedef __int8 int8_t; + typedef unsigned __int8 uint8_t; + + typedef __int16 int16_t; + typedef unsigned __int16 uint16_t; + + typedef __int32 int32_t; + typedef unsigned __int32 uint32_t; + + typedef __int64 int64_t; + typedef unsigned __int64 uint64_t; + + typedef unsigned long uintptr_t; + typedef long intptr_t; +#endif + +#endif /* WINDOWS_CONFIG_HACKERY */ +/* windows-config.h ends here */ diff --git a/config-h.in b/config-h.in new file mode 100644 index 0000000..afd32d0 --- /dev/null +++ b/config-h.in @@ -0,0 +1,759 @@ +/* config-h.in. Generated from configure.ac by autoheader. */ + +/* CPU and C ABI indicator */ +#ifndef __i386__ +#undef __i386__ +#endif +#ifndef __x86_64_x32__ +#undef __x86_64_x32__ +#endif +#ifndef __x86_64__ +#undef __x86_64__ +#endif +#ifndef __alpha__ +#undef __alpha__ +#endif +#ifndef __arm__ +#undef __arm__ +#endif +#ifndef __armhf__ +#undef __armhf__ +#endif +#ifndef __arm64_ilp32__ +#undef __arm64_ilp32__ +#endif +#ifndef __arm64__ +#undef __arm64__ +#endif +#ifndef __hppa__ +#undef __hppa__ +#endif +#ifndef __hppa64__ +#undef __hppa64__ +#endif +#ifndef __ia64_ilp32__ +#undef __ia64_ilp32__ +#endif +#ifndef __ia64__ +#undef __ia64__ +#endif +#ifndef __m68k__ +#undef __m68k__ +#endif +#ifndef __mips__ +#undef __mips__ +#endif +#ifndef __mipsn32__ +#undef __mipsn32__ +#endif +#ifndef __mips64__ +#undef __mips64__ +#endif +#ifndef __powerpc__ +#undef __powerpc__ +#endif +#ifndef __powerpc64__ +#undef __powerpc64__ +#endif +#ifndef __powerpc64_elfv2__ +#undef __powerpc64_elfv2__ +#endif +#ifndef __riscv32__ +#undef __riscv32__ +#endif +#ifndef __riscv64__ +#undef __riscv64__ +#endif +#ifndef __riscv32_ilp32__ +#undef __riscv32_ilp32__ +#endif +#ifndef __riscv32_ilp32f__ +#undef __riscv32_ilp32f__ +#endif +#ifndef __riscv32_ilp32d__ +#undef __riscv32_ilp32d__ +#endif +#ifndef __riscv64_ilp32__ +#undef __riscv64_ilp32__ +#endif +#ifndef __riscv64_ilp32f__ +#undef __riscv64_ilp32f__ +#endif +#ifndef __riscv64_ilp32d__ +#undef __riscv64_ilp32d__ +#endif +#ifndef __riscv64_lp64__ +#undef __riscv64_lp64__ +#endif +#ifndef __riscv64_lp64f__ +#undef __riscv64_lp64f__ +#endif +#ifndef __riscv64_lp64d__ +#undef __riscv64_lp64d__ +#endif +#ifndef __s390__ +#undef __s390__ +#endif +#ifndef __s390x__ +#undef __s390x__ +#endif +#ifndef __sh__ +#undef __sh__ +#endif +#ifndef __sparc__ +#undef __sparc__ +#endif +#ifndef __sparc64__ +#undef __sparc64__ +#endif + + +#ifndef AUTOGEN_CONFIG_H + +#define AUTOGEN_CONFIG_H 1 + +/* define to suitable timeout limit for shell command */ +#undef AG_DEFAULT_TIMEOUT + +/* Define this to the autoopts interface age number */ +#undef AO_AGE + +/* Define this to the autoopts current interface number */ +#undef AO_CURRENT + +/* Define this to the autoopts interface revision number */ +#undef AO_REVISION + +/* format_arg attribute wrapper */ +#undef ATTRIBUTE_FORMAT_ARG + +/* Define this to a working Bourne shell */ +#undef CONFIG_SHELL + +/* Define this if debugging is enabled */ +#undef DEBUG_ENABLED + +/* "Define if we can use it" */ +#undef ENABLE_FMEMOPEN + +/* nls support in libopts */ +#undef ENABLE_NLS + +/* fopen(3) accepts a 'b' in the mode flag */ +#undef FOPEN_BINARY_FLAG + +/* fopen(3) accepts a 't' in the mode flag */ +#undef FOPEN_TEXT_FLAG + +/* define to a single number for Guile version */ +#undef GUILE_VERSION + +/* Define to 1 if you have the header file. */ +#undef HAVE_ASSERT_H + +/* Define to 1 if you have the `canonicalize_file_name' function. */ +#undef HAVE_CANONICALIZE_FILE_NAME + +/* Define to 1 if you have the `chmod' function. */ +#undef HAVE_CHMOD + +/* Define to 1 if you have the `clock_gettime' function. */ +#undef HAVE_CLOCK_GETTIME + +/* Define to 1 if you have the `copysign' function. */ +#undef HAVE_COPYSIGN + +/* Define to 1 if you have the `copysignl' function. */ +#undef HAVE_COPYSIGNL + +/* Define to 1 if you have the header file. */ +#undef HAVE_CTYPE_H + +/* Define to 1 if you have the declaration of `clearerr_unlocked', and to 0 if + you don't. */ +#undef HAVE_DECL_CLEARERR_UNLOCKED + +/* Define to 1 if you have the declaration of `feof_unlocked', and to 0 if you + don't. */ +#undef HAVE_DECL_FEOF_UNLOCKED + +/* Define to 1 if you have the declaration of `ferror_unlocked', and to 0 if + you don't. */ +#undef HAVE_DECL_FERROR_UNLOCKED + +/* Define to 1 if you have the declaration of `fflush_unlocked', and to 0 if + you don't. */ +#undef HAVE_DECL_FFLUSH_UNLOCKED + +/* Define to 1 if you have the declaration of `fgets_unlocked', and to 0 if + you don't. */ +#undef HAVE_DECL_FGETS_UNLOCKED + +/* Define to 1 if you have the declaration of `fputc_unlocked', and to 0 if + you don't. */ +#undef HAVE_DECL_FPUTC_UNLOCKED + +/* Define to 1 if you have the declaration of `fputs_unlocked', and to 0 if + you don't. */ +#undef HAVE_DECL_FPUTS_UNLOCKED + +/* Define to 1 if you have the declaration of `fread_unlocked', and to 0 if + you don't. */ +#undef HAVE_DECL_FREAD_UNLOCKED + +/* Define to 1 if you have the declaration of `fwrite_unlocked', and to 0 if + you don't. */ +#undef HAVE_DECL_FWRITE_UNLOCKED + +/* Define to 1 if you have the declaration of `getchar_unlocked', and to 0 if + you don't. */ +#undef HAVE_DECL_GETCHAR_UNLOCKED + +/* Define to 1 if you have the declaration of `getc_unlocked', and to 0 if you + don't. */ +#undef HAVE_DECL_GETC_UNLOCKED + +/* Define to 1 if you have the declaration of `putchar_unlocked', and to 0 if + you don't. */ +#undef HAVE_DECL_PUTCHAR_UNLOCKED + +/* Define to 1 if you have the declaration of `putc_unlocked', and to 0 if you + don't. */ +#undef HAVE_DECL_PUTC_UNLOCKED + +/* Define to 1 if you have the declaration of `sigsetjmp', and to 0 if you + don't. */ +#undef HAVE_DECL_SIGSETJMP + +/* Define to 1 if you have the declaration of `sys_siglist', and to 0 if you + don't. */ +#undef HAVE_DECL_SYS_SIGLIST + +/* Define this if /dev/zero is readable device */ +#undef HAVE_DEV_ZERO + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#undef HAVE_DIRENT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define to 1 if you have the `dlopen' function. */ +#undef HAVE_DLOPEN + +/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ +#undef HAVE_DOPRNT + +/* Define to 1 if you have the header file. */ +#undef HAVE_ERRNO_H + +/* Define to 1 if you have the `fchmod' function. */ +#undef HAVE_FCHMOD + +/* Define to 1 if you have the header file. */ +#undef HAVE_FCNTL_H + +/* Define to 1 if you have the `fopencookie' function. */ +#undef HAVE_FOPENCOOKIE + +/* Define to 1 if you have the `fork' function. */ +#undef HAVE_FORK + +/* Define to 1 if you have the `frexpl' function. */ +#undef HAVE_FREXPL + +/* Define to 1 if you have the `fstat' function. */ +#undef HAVE_FSTAT + +/* Define to 1 if you have the `funopen' function. */ +#undef HAVE_FUNOPEN + +/* Define to 1 if you have the `futimes' function. */ +#undef HAVE_FUTIMES + +/* Define to 1 if you have the `getdate_r' function. */ +#undef HAVE_GETDATE_R + +/* Define to 1 if the system has the type `int16_t'. */ +#undef HAVE_INT16_T + +/* Define to 1 if the system has the type `int32_t'. */ +#undef HAVE_INT32_T + +/* Define to 1 if the system has the type `int8_t'. */ +#undef HAVE_INT8_T + +/* Define to 1 if the system has the type `intptr_t'. */ +#undef HAVE_INTPTR_T + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `ldexpl' function. */ +#undef HAVE_LDEXPL + +/* Define to 1 if you have the `dl' library (-ldl). */ +#undef HAVE_LIBDL + +/* Define to 1 if you have the `gen' library (-lgen). */ +#undef HAVE_LIBGEN + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIBGEN_H + +/* Define to 1 if you have the `intl' library (-lintl). */ +#undef HAVE_LIBINTL + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIBINTL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIBIO_H + +/* Define to 1 if you have the `m' library (-lm). */ +#undef HAVE_LIBM + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIMITS_H + +/* Define to 1 if the system has the type `long double'. */ +#undef HAVE_LONG_DOUBLE + +/* Define to 1 if the type `long double' works and has more range or precision + than `double'. */ +#undef HAVE_LONG_DOUBLE_WIDER + +/* Define to 1 if the system has the type `long long'. */ +#undef HAVE_LONG_LONG + +/* Define to 1 if the system has the type 'long long int'. */ +#undef HAVE_LONG_LONG_INT + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the `mmap' function. */ +#undef HAVE_MMAP + +/* Define to 1 if you have the `modfl' function. */ +#undef HAVE_MODFL + +/* Define to 1 if you have the header file, and it defines `DIR'. */ +#undef HAVE_NDIR_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETINET_IN_H + +/* Define this if pathfind(3) works */ +#undef HAVE_PATHFIND + +/* Define to 1 if the system has the type `pid_t'. */ +#undef HAVE_PID_T + +/* Define to 1 if the system has the type `ptrdiff_t'. */ +#undef HAVE_PTRDIFF_T + +/* Define to 1 if you have the `putenv' function. */ +#undef HAVE_PUTENV + +/* Define this if we have a functional realpath(3C) */ +#undef HAVE_REALPATH + +/* Define to 1 if you have the header file. */ +#undef HAVE_RUNETYPE_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SETJMP_H + +/* Define to 1 if the system has the type `size_t'. */ +#undef HAVE_SIZE_T + +/* Define to 1 if you have the `snprintf' function. */ +#undef HAVE_SNPRINTF + +/* Define this if sysinfo(2) is Solaris */ +#undef HAVE_SOLARIS_SYSINFO + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDARG_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDBOOL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `strchr' function. */ +#undef HAVE_STRCHR + +/* Define this if strcspn matches prototype and works */ +#undef HAVE_STRCSPN + +/* Define to 1 if you have the `strdup' function. */ +#undef HAVE_STRDUP + +/* Define this if strftime() works */ +#undef HAVE_STRFTIME + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strlcpy' function. */ +#undef HAVE_STRLCPY + +/* Define to 1 if you have the `strrchr' function. */ +#undef HAVE_STRRCHR + +/* Define to 1 if you have the `strsignal' function. */ +#undef HAVE_STRSIGNAL + +/* Define to 1 if you have the `strtoul' function. */ +#undef HAVE_STRTOUL + +/* Define to 1 if `st_mtim' is a member of `struct stat'. */ +#undef HAVE_STRUCT_STAT_ST_MTIM + +/* Define to 1 if `st_mtimensec' is a member of `struct stat'. */ +#undef HAVE_STRUCT_STAT_ST_MTIMENSEC + +/* Define to 1 if `st_mtimespec' is a member of `struct stat'. */ +#undef HAVE_STRUCT_STAT_ST_MTIMESPEC + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYSEXITS_H + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#undef HAVE_SYS_DIR_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_LIMITS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_MMAN_H + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#undef HAVE_SYS_NDIR_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_PARAM_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_POLL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_PROCSET_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_RESOURCE_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SELECT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_SOCKET_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STROPTS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_UN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_WAIT_H + +/* Define to 1 if the system has the type `uint16_t'. */ +#undef HAVE_UINT16_T + +/* Define to 1 if the system has the type `uint32_t'. */ +#undef HAVE_UINT32_T + +/* Define to 1 if the system has the type `uint8_t'. */ +#undef HAVE_UINT8_T + +/* Define to 1 if the system has the type `uintmax_t'. */ +#undef HAVE_UINTMAX_T + +/* Define to 1 if the system has the type `uintptr_t'. */ +#undef HAVE_UINTPTR_T + +/* Define to 1 if the system has the type `uint_t'. */ +#undef HAVE_UINT_T + +/* Define this if uname(2) is POSIX */ +#undef HAVE_UNAME_SYSCALL + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if the system has the type 'unsigned long long int'. */ +#undef HAVE_UNSIGNED_LONG_LONG_INT + +/* Define to 1 if you have the `utimensat' function. */ +#undef HAVE_UTIMENSAT + +/* Define to 1 if you have the `utimes' function. */ +#undef HAVE_UTIMES + +/* Define to 1 if you have the header file. */ +#undef HAVE_UTIME_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_VALUES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_VARARGS_H + +/* Define to 1 if you have the `vfork' function. */ +#undef HAVE_VFORK + +/* Define to 1 if you have the header file. */ +#undef HAVE_VFORK_H + +/* Define to 1 if you have the `vprintf' function. */ +#undef HAVE_VPRINTF + +/* Define to 1 if you have the header file. */ +#undef HAVE_WCHAR_H + +/* Define to 1 if the system has the type `wchar_t'. */ +#undef HAVE_WCHAR_T + +/* Define to 1 if the system has the type `wint_t'. */ +#undef HAVE_WINT_T + +/* Define to 1 if `fork' works. */ +#undef HAVE_WORKING_FORK + +/* [setjmp links okay] */ +#undef HAVE_WORKING_SETJMP + +/* [sigsetjmp links okay] */ +#undef HAVE_WORKING_SIGSETJMP + +/* Define to 1 if `vfork' works. */ +#undef HAVE_WORKING_VFORK + +/* Define to the sub-directory where libtool stores uninstalled libraries. */ +#undef LT_OBJDIR + +/* Define if typedefs for the funopen function pointers are required. */ +#undef NEED_COOKIE_FUNCTION_TYPEDEFS + +/* Define this if optional arguments are disallowed */ +#undef NO_OPTIONAL_OPT_ARGS + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the home page for this package. */ +#undef PACKAGE_URL + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* define to a working POSIX compliant shell */ +#undef POSIX_SHELL + +/* name of regex header file */ +#undef REGEX_HEADER + +/* Define if shell scripts are enabled */ +#undef SHELL_ENABLED + +/* The size of `char*', as computed by sizeof. */ +#undef SIZEOF_CHARP + +/* The size of `char *', as computed by sizeof. */ +#undef SIZEOF_CHAR_P + +/* The size of `int', as computed by sizeof. */ +#undef SIZEOF_INT + +/* The size of `long', as computed by sizeof. */ +#undef SIZEOF_LONG + +/* The size of `short', as computed by sizeof. */ +#undef SIZEOF_SHORT + +/* define to static or static inline */ +#undef SNV_INLINE + +/* Define this to the long+double type */ +#undef SNV_LONG_DOUBLE + +/* Define this if statically link autogen to libopts */ +#undef STATIC_AUTOGEN_ENABLED + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define this if specify an autogen timeout */ +#undef TIMEOUT_ENABLED + +/* Enable extensions on AIX 3, Interix. */ +#ifndef _ALL_SOURCE +# undef _ALL_SOURCE +#endif +/* Enable general extensions on macOS. */ +#ifndef _DARWIN_C_SOURCE +# undef _DARWIN_C_SOURCE +#endif +/* Enable GNU extensions on systems that have them. */ +#ifndef _GNU_SOURCE +# undef _GNU_SOURCE +#endif +/* Enable NetBSD extensions on NetBSD. */ +#ifndef _NETBSD_SOURCE +# undef _NETBSD_SOURCE +#endif +/* Enable OpenBSD extensions on NetBSD. */ +#ifndef _OPENBSD_SOURCE +# undef _OPENBSD_SOURCE +#endif +/* Enable threading extensions on Solaris. */ +#ifndef _POSIX_PTHREAD_SEMANTICS +# undef _POSIX_PTHREAD_SEMANTICS +#endif +/* Enable extensions specified by ISO/IEC TS 18661-5:2014. */ +#ifndef __STDC_WANT_IEC_60559_ATTRIBS_EXT__ +# undef __STDC_WANT_IEC_60559_ATTRIBS_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TS 18661-1:2014. */ +#ifndef __STDC_WANT_IEC_60559_BFP_EXT__ +# undef __STDC_WANT_IEC_60559_BFP_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TS 18661-2:2015. */ +#ifndef __STDC_WANT_IEC_60559_DFP_EXT__ +# undef __STDC_WANT_IEC_60559_DFP_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TS 18661-4:2015. */ +#ifndef __STDC_WANT_IEC_60559_FUNCS_EXT__ +# undef __STDC_WANT_IEC_60559_FUNCS_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TS 18661-3:2015. */ +#ifndef __STDC_WANT_IEC_60559_TYPES_EXT__ +# undef __STDC_WANT_IEC_60559_TYPES_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TR 24731-2:2010. */ +#ifndef __STDC_WANT_LIB_EXT2__ +# undef __STDC_WANT_LIB_EXT2__ +#endif +/* Enable extensions specified by ISO/IEC 24747:2009. */ +#ifndef __STDC_WANT_MATH_SPEC_FUNCS__ +# undef __STDC_WANT_MATH_SPEC_FUNCS__ +#endif +/* Enable extensions on HP NonStop. */ +#ifndef _TANDEM_SOURCE +# undef _TANDEM_SOURCE +#endif +/* Enable X/Open extensions if necessary. HP-UX 11.11 defines + mbstate_t only if _XOPEN_SOURCE is defined to 500, regardless of + whether compiling with -Ae or -D_HPUX_SOURCE=1. */ +#ifndef _XOPEN_SOURCE +# undef _XOPEN_SOURCE +#endif +/* Enable X/Open compliant socket functions that do not require linking + with -lxnet on HP-UX 11.11. */ +#ifndef _HPUX_ALT_XOPEN_SOCKET_API +# undef _HPUX_ALT_XOPEN_SOCKET_API +#endif +/* Enable general extensions on Solaris. */ +#ifndef __EXTENSIONS__ +# undef __EXTENSIONS__ +#endif + + +/* Define to 1 if you want getc etc. to use unlocked I/O if available. + Unlocked I/O can improve performance in unithreaded apps, but it is not + safe for multithreaded apps. */ +#undef USE_UNLOCKED_IO + +/* Version number of package */ +#undef VERSION + +/* Define if using the dmalloc debugging malloc package */ +#undef WITH_DMALLOC + +/* Define this if a working libregex can be found */ +#undef WITH_LIBREGEX + +/* Define this if name of the packager of this software is supplied */ +#undef WITH_PACKAGER + +/* Define this if bug reporting URI/e-mail/etc. is supplied */ +#undef WITH_PACKAGER_BUG_REPORTS + +/* Define this if packager-specific version information is supplied */ +#undef WITH_PACKAGER_VERSION + +/* Define to 1 if on MINIX. */ +#undef _MINIX + +/* Define to 1 to make NetBSD features available. MINIX 3 needs this. */ +#undef _NETBSD_SOURCE + +/* Define to 2 if the system does not provide POSIX.1 features except with + this defined. */ +#undef _POSIX_1_SOURCE + +/* Define to 1 if you need to in order for 'stat' and other things to work. */ +#undef _POSIX_SOURCE + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to `int' if doesn't define. */ +#undef gid_t + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +#undef inline +#endif + +/* Define to `int' if does not define. */ +#undef mode_t + +/* Define to `int' if does not define. */ +#undef pid_t + +/* Define to `unsigned int' if does not define. */ +#undef size_t + +/* Define to `int' if doesn't define. */ +#undef uid_t + +/* Define as `fork' if `vfork' does not work. */ +#undef vfork + +#endif /* AUTOGEN_CONFIG_H */ diff --git a/config/ag_macros.m4 b/config/ag_macros.m4 new file mode 100644 index 0000000..ccce347 --- /dev/null +++ b/config/ag_macros.m4 @@ -0,0 +1,605 @@ + +dnl do always before generated macros: +dnl +AC_DEFUN([INVOKE_AG_MACROS_FIRST],[ + stat_nsec_found=no + AC_CHECK_MEMBERS( + [struct stat.st_mtim, struct stat.st_mtimensec, struct stat.st_mtimespec], + [stat_nsec_found=yes], [], [[#include ]]) + AC_CHECK_FUNCS(strchr strlcpy snprintf dlopen utimensat clock_gettime) + AC_SEARCH_LIBS(copysign, [m], + [AC_DEFINE(HAVE_COPYSIGN, 1, + [Define to 1 if you have the `copysign' function.])]) + AC_SEARCH_LIBS(copysignl, [m], + [AC_DEFINE(HAVE_COPYSIGNL, 1, + [Define to 1 if you have the `copysignl' function.])]) + AC_SEARCH_LIBS(modfl, [m], + [AC_DEFINE(HAVE_MODFL, 1, + [Define to 1 if you have the `modfl' function.])]) + + # ---------------------------------------------------------------------- + # Check for the functions needed from libgen and libdl + # ---------------------------------------------------------------------- + + AM_CONDITIONAL([NEED_PATHFIND], [test X$ac_cv_func_pathfind = Xyes]) + [if test X$ac_cv_func_dlopen = Xyes + then DYNAMIC_AG=-export-dynamic + else DYNAMIC_AG="" + fi] + AC_SUBST(DYNAMIC_AG) + + AC_CHECK_HEADERS([libio.h ctype.h assert.h sys/resource.h]) + AC_CHECK_DECLS([sigsetjmp],,, [#include ]) + AC_DECL_SYS_SIGLIST + AC_CHECK_FUNCS([putenv getdate_r utimes futimes]) + + AC_C_INLINE + AC_TYPE_LONG_LONG_INT + + AC_PROG_GREP + AC_PROG_EGREP + AC_PROG_FGREP +]) + + + +dnl +dnl do always after generated macros: +dnl +AC_DEFUN([INVOKE_AG_MACROS_LAST],[ +[if test X${INVOKE_AG_MACROS_LAST_done} != Xyes ; then] + GUILE_FLAGS + [test -x "${PKG_CONFIG}" || { + test -z "${PKG_CONFIG}" && PKG_CONFIG=pkg-config + f=`command -v ${PKG_CONFIG}` + test -x "${f}" && PKG_CONFIG="$f" + } + # Grab the first "-I" option that works + # + ag_gv=`gdir=\`${PKG_CONFIG} --cflags-only-I \ + guile-${GUILE_EFFECTIVE_VERSION} | \ + sed 's/ *-I/ /g'\` + test ${#gdir} -gt 1 || gdir=/usr/include + for d in $gdir + do test -f "$d/libguile/version.h" && gdir=$d && break + done + gdir=\`awk '/SCM_MICRO_VERSION/{ print @S|@3 }' \ + "${gdir}/libguile/version.h"\` + test -n "$gdir" || exit 1 + IFS=' .' + set -- ${GUILE_EFFECTIVE_VERSION} + printf '%u%02u%03u' ${1} ${2} ${gdir} + ` + + test -n "$ag_gv" || ]AC_MSG_FAILURE([cannot determine Guile version], 1) + test ${ag_gv} -ge 200000 || AC_MSG_FAILURE([cannot use pre-2.0 Guile]) + AC_DEFINE_UNQUOTED(GUILE_VERSION, ${ag_gv}, + [define to a single number for Guile version]) + INVOKE_LIBOPTS_MACROS + + [test "X${ac_cv_header_sys_wait_h}" = Xyes || \ + ]AC_MSG_ERROR([you must have sys/wait.h on your system]) + + AC_CHECK_FUNCS([fopencookie funopen], [break]) + case "${ac_cv_func_fopencookie}${ac_cv_func_funopen}" in + *yes* ) + AC_DEFINE([ENABLE_FMEMOPEN], 1, "Define if we can use it") + ;; + esac + + # Note that BSD does not typedef these in its headers, but instead + # calls for them to be identical in signature to read(2), write(2), + # lseek(2), and close(2). Newlib however does include typedefs + # in its stdio.h for these, and they do not match the signatures + # of the BSD implementation. So this test relies on the fact + # that any typedef will succeed for BSD, while only one that + # matches the existing definitions in stdio.h will succeed for + # a newlib system. + + if test "X${ac_cv_func_funopen}" = Xyes; then + AC_CACHE_CHECK([for cookie_function_t type], + [ag_cv_cookie_function_t], + [AC_TRY_COMPILE([#include + typedef int cookie_read_function_t (void *, char *, int); + ], [], ag_cv_cookie_function_t="bsd", + AC_TRY_COMPILE([#include + typedef ssize_t cookie_read_function_t (void *, char *, size_t); + ], [], ag_cv_cookie_function_t="newlib", + AC_MSG_ERROR([Unknown flavor of cookie_XXX_t types])))]) + fi + if test "X${ag_cv_cookie_function_t}" = Xbsd; then + AC_DEFINE([NEED_COOKIE_FUNCTION_TYPEDEFS], [1], + [Define if typedefs for the funopen function pointers are required.]) + fi + + AC_CACHE_CHECK([for static inline], [snv_cv_static_inline], [ + AC_TRY_COMPILE([static inline foo(bar) int bar; { return bar; }], + [return foo(0);], + [snv_cv_static_inline='static inline'], + [snv_cv_static_inline='static']) + ]) + AC_DEFINE_UNQUOTED(SNV_INLINE, ${snv_cv_static_inline}, + [define to static or static inline]) + [if test "X${libopts_cv_with_libregex}" = Xno + then + echo "A POSIX compliant regcomp/regexec routine is required. + These are required for AutoGen to work correctly. If you have + such a library present on your system, you must specify it by + setting the LIBS environment variable, e.g., \"LIBS='-lregex'\". + If you do not have such a library on your system, then you should + download and install, for example, the one from: + ftp://ftp.gnu.org/gnu/rx/" >&2] + AC_MSG_ERROR([Cannot find working POSIX regex library]) + [fi] +[ INVOKE_AG_MACROS_LAST_done=yes +fi]]) + +dnl +dnl @synopsis INVOKE_AG_MACROS +dnl +dnl This macro will invoke the AutoConf macros specified in misc.def +dnl that have not been disabled with "omit-invocation". +dnl +AC_DEFUN([AG_DISABLE_SHELL],[ + AC_ARG_ENABLE([shell], + AS_HELP_STRING([--disable-shell], [shell scripts are desired]), + [ag_cv_enable_shell=${enable_shell}], + AC_CACHE_CHECK([whether shell scripts are desired], ag_cv_enable_shell, + ag_cv_enable_shell=yes) + ) # end of AC_ARG_ENABLE + if test "X${ag_cv_enable_shell}" != Xno + then + AC_FUNC_FORK + fi + +]) # end of AC_DEFUN of AG_DISABLE_SHELL + + +AC_DEFUN([AG_TEST_DO_SHELL],[ + AC_MSG_CHECKING([whether using shell scripts]) + AC_CACHE_VAL([ag_cv_test_do_shell],[ + ag_cv_test_do_shell=`exec 2> /dev/null +test "x$ac_cv_func_fork_works" != xyes && \\ + test "x$ac_cv_func_vfork_works" != xyes && exit 1 +test "x$ag_cv_enable_shell" = xyes || exit 1 +echo yes` + if test $? -ne 0 || test -z "$ag_cv_test_do_shell" + then ag_cv_test_do_shell=no + fi + ]) # end of CACHE_VAL of ag_cv_test_do_shell + AC_MSG_RESULT([${ag_cv_test_do_shell}]) + if test "X${ag_cv_test_do_shell}" != Xno + then + AC_SUBST(OPTS_TESTDIR) +AC_SUBST(AGEN5_TESTS) +AC_DEFINE([SHELL_ENABLED], [1], [Define if shell scripts are enabled]) +OPTS_TESTDIR=test +AGEN5_TESTS='$(SHELL_TESTS) $(NOSHELL_TESTS)' + else + OPTS_TESTDIR= +AGEN5_TESTS='$(NOSHELL_TESTS)' + fi + AM_CONDITIONAL([DO_SHELL_CMDS],[test "X${ag_cv_test_do_shell}" != Xno]) + +]) # end of AC_DEFUN of AG_TEST_DO_SHELL + + +AC_DEFUN([AG_ENABLE_STATIC_AUTOGEN],[ + AC_ARG_ENABLE([static-autogen], + AS_HELP_STRING([--enable-static-autogen], [statically link autogen to libopts]), + [ag_cv_enable_static_autogen=${enable_static_autogen}], + AC_CACHE_CHECK([whether statically link autogen to libopts], ag_cv_enable_static_autogen, + ag_cv_enable_static_autogen=no) + ) # end of AC_ARG_ENABLE + if test "X${ag_cv_enable_static_autogen}" != Xno + then + AC_DEFINE([STATIC_AUTOGEN_ENABLED],[1], + [Define this if statically link autogen to libopts]) + AG_STATIC_AUTOGEN="-static" + else + AG_STATIC_AUTOGEN='' + fi + AC_SUBST([AG_STATIC_AUTOGEN]) + +]) # end of AC_DEFUN of AG_ENABLE_STATIC_AUTOGEN + + +AC_DEFUN([AG_LINK_SETJMP],[ + AC_MSG_CHECKING([whether setjmp() links okay]) + AC_CACHE_VAL([ag_cv_link_setjmp],[ + AC_LINK_IFELSE( + AC_LANG_PROGRAM([@%:@include ], + [jmp_buf bf; +if (setjmp(bf)) + return 0; +return 0;]), + [ag_cv_link_setjmp=yes], + [ag_cv_link_setjmp=no] + ) # end of AC_LINK_IFELSE + ]) # end of AC_CACHE_VAL for ag_cv_link_setjmp + AC_MSG_RESULT([${ag_cv_link_setjmp}]) + if test "X${ag_cv_link_setjmp}" != Xno + then + AC_DEFINE(HAVE_WORKING_SETJMP, 1, @<:@setjmp links okay@:>@) + fi + +]) # end of AC_DEFUN of AG_LINK_SETJMP + + +AC_DEFUN([AG_COMPILE_FORMAT_ARG],[ + AC_MSG_CHECKING([whether __attribute__((format_arg(n))) works]) + AC_CACHE_VAL([ag_cv_compile_format_arg],[ + AC_COMPILE_IFELSE( + AC_LANG_PROGRAM([@%:@include +char const * foo(char const * fmt, int v) __attribute__((format_arg(1)));], + [ int i = 0; + printf(foo("argc is %d\n", i), i);]), + [ag_cv_compile_format_arg=yes], + [ag_cv_compile_format_arg=no] + ) # end of AC_COMPILE_IFELSE + ]) # end of AC_CACHE_VAL for ag_cv_compile_format_arg + AC_MSG_RESULT([${ag_cv_compile_format_arg}]) + if test "X${ag_cv_compile_format_arg}" != Xno + then + format_arg_expansion="__attribute__((format_arg(_a)))" + else + format_arg_expansion="" + fi + AC_DEFINE_UNQUOTED([ATTRIBUTE_FORMAT_ARG(_a)], + [${format_arg_expansion}], + [format_arg attribute wrapper]) + +]) # end of AC_DEFUN of AG_COMPILE_FORMAT_ARG + + +AC_DEFUN([AG_LINK_SIGSETJMP],[ + AC_MSG_CHECKING([whether sigsetjmp() links okay]) + AC_CACHE_VAL([ag_cv_link_sigsetjmp],[ + AC_LINK_IFELSE( + AC_LANG_PROGRAM([@%:@include ], + [sigjmp_buf bf; +if (sigsetjmp(bf,0)) + return 0; +return 0;]), + [ag_cv_link_sigsetjmp=yes], + [ag_cv_link_sigsetjmp=no] + ) # end of AC_LINK_IFELSE + ]) # end of AC_CACHE_VAL for ag_cv_link_sigsetjmp + AC_MSG_RESULT([${ag_cv_link_sigsetjmp}]) + if test "X${ag_cv_link_sigsetjmp}" != Xno + then + AC_DEFINE(HAVE_WORKING_SIGSETJMP, 1, @<:@sigsetjmp links okay@:>@) + fi + +]) # end of AC_DEFUN of AG_LINK_SIGSETJMP + + +AC_DEFUN([AG_WITHLIB_XML2],[ + AC_ARG_WITH([libxml2], + AS_HELP_STRING([--with-libxml2], [libxml2 installation prefix]), + [ag_cv_with_libxml2_root=${with_libxml2}], + AC_CACHE_CHECK([whether with-libxml2 was specified], ag_cv_with_libxml2_root, + ag_cv_with_libxml2_root=no) + ) # end of AC_ARG_WITH libxml2 + + if test "${with_libxml2+set}" = set && \ + test "X${withval}" = Xno + then ## disabled by request + ag_cv_with_libxml2_root=no + ag_cv_with_libxml2_cflags=no + ag_cv_with_libxml2_libs=no + else + + AC_ARG_WITH([libxml2-cflags], + AS_HELP_STRING([--with-libxml2-cflags], [libxml2 compile flags]), + [ag_cv_with_libxml2_cflags=${with_libxml2_cflags}], + AC_CACHE_CHECK([whether with-libxml2-cflags was specified], ag_cv_with_libxml2_cflags, + ag_cv_with_libxml2_cflags=no) + ) # end of AC_ARG_WITH libxml2-cflags + + AC_ARG_WITH([libxml2-libs], + AS_HELP_STRING([--with-libxml2-libs], [libxml2 link command arguments]), + [ag_cv_with_libxml2_libs=${with_libxml2_libs}], + AC_CACHE_CHECK([whether with-libxml2-libs was specified], ag_cv_with_libxml2_libs, + ag_cv_with_libxml2_libs=no) + ) # end of AC_ARG_WITH libxml2-libs + + case "X${ag_cv_with_libxml2_cflags}" in + Xyes|Xno|X ) + case "X${ag_cv_with_libxml2_root}" in + Xyes|Xno|X ) ag_cv_with_libxml2_cflags=no ;; + * ) ag_cv_with_libxml2_cflags=-I${ag_cv_with_libxml2_root}/include ;; + esac + esac + case "X${ag_cv_with_libxml2_libs}" in + Xyes|Xno|X ) + case "X${ag_cv_with_libxml2_root}" in + Xyes|Xno|X ) ag_cv_with_libxml2_libs=no ;; + * ) ag_cv_with_libxml2_libs="-L${ag_cv_with_libxml2_root}/lib -lxml2" ;; + esac + esac + ag_save_CPPFLAGS="${CPPFLAGS}" + ag_save_LIBS="${LIBS}" + case "X${ag_cv_with_libxml2_cflags}" in + Xyes|Xno|X ) + f=`xml2-config --cflags 2>/dev/null` || f='' + test -n "${f}" && ag_cv_with_libxml2_cflags="${f}" && \ + AC_MSG_NOTICE([xml2-config used for CFLAGS: $f]) ;; + esac + case "X${ag_cv_with_libxml2_libs}" in + Xyes|Xno|X ) + f=`xml2-config --libs 2>/dev/null` || f='' + test -n "${f}" && ag_cv_with_libxml2_libs="${f}" && \ + AC_MSG_NOTICE([xml2-config used for LIBS: $f]) ;; + esac + case "X${ag_cv_with_libxml2_cflags}" in + Xyes|Xno|X ) + ag_cv_with_libxml2_cflags="" ;; + * ) CPPFLAGS="${CPPFLAGS} ${ag_cv_with_libxml2_cflags}" ;; + esac + case "X${ag_cv_with_libxml2_libs}" in + Xyes|Xno|X ) + LIBS="${LIBS} -lxml2" + ag_cv_with_libxml2_libs="-lxml2" ;; + * ) + LIBS="${LIBS} ${ag_cv_with_libxml2_libs}" ;; + esac + LIBXML2_CFLAGS="" + LIBXML2_LIBS="" + AC_MSG_CHECKING([whether libxml2 can be linked with]) + AC_CACHE_VAL([ag_cv_with_libxml2],[ + AC_LINK_IFELSE( + [AC_LANG_SOURCE([[@%:@include +@%:@include + +int main () { +xmlDocPtr p = xmlParseFile( "mumble.xml" ); }]])], + [ag_cv_with_libxml2=yes], + [ag_cv_with_libxml2=no]) # end of AC_LINK_IFELSE + ]) # end of AC_CACHE_VAL for ag_cv_with_libxml2 + fi ## disabled by request + AC_MSG_RESULT([${ag_cv_with_libxml2}]) + AC_SUBST([LIBXML2_CFLAGS]) + AC_SUBST([LIBXML2_LIBS]) + if test "X${ag_cv_with_libxml2}" != Xno + then[ + LIBXML2_CFLAGS="${ag_cv_with_libxml2_cflags}" + LIBXML2_LIBS="${ag_cv_with_libxml2_libs}"] + CPPFLAGS="@S|@{ag_save_CPPFLAGS}" + LIBS="@S|@{ag_save_LIBS}" + + else + CPPFLAGS="${ag_save_CPPFLAGS}" + LIBS="${ag_save_LIBS}" + LIBXML2_CFLAGS='' + LIBXML2_LIBS='' + fi + AC_SUBST([AG_XML2]) + AM_CONDITIONAL([HAVE_XML_LIB],[test "X${ag_cv_with_libxml2}" != Xno]) + +]) # end of AC_DEFUN of AG_WITHLIB_XML2 + + +AC_DEFUN([AG_RUN_SOLARIS_SYSINFO],[ + AC_MSG_CHECKING([whether sysinfo(2) is Solaris]) + AC_CACHE_VAL([ag_cv_run_solaris_sysinfo],[ + AC_RUN_IFELSE([AC_LANG_SOURCE([@%:@include +int main() { char z@<:@ 256 @:>@; +long sz = sysinfo(SI_SYSNAME, z, sizeof(z)); +return (sz > 0) ? 0 : 1; }] )], + [ag_cv_run_solaris_sysinfo=yes],[ag_cv_run_solaris_sysinfo=no],[ag_cv_run_solaris_sysinfo=no] + ) # end of RUN_IFELSE + ]) # end of AC_CACHE_VAL for ag_cv_run_solaris_sysinfo + AC_MSG_RESULT([${ag_cv_run_solaris_sysinfo}]) + if test "X${ag_cv_run_solaris_sysinfo}" != Xno + then + AC_DEFINE([HAVE_SOLARIS_SYSINFO],[1], + [Define this if sysinfo(2) is Solaris]) + fi + +]) # end of AC_DEFUN of AG_RUN_SOLARIS_SYSINFO + + +AC_DEFUN([AG_ENABLE_TIMEOUT],[ + AC_ARG_ENABLE([timeout], + AS_HELP_STRING([--enable-timeout], [specify an autogen timeout]), + [ag_cv_enable_timeout=${enable_timeout}], + AC_CACHE_CHECK([whether specify an autogen timeout], ag_cv_enable_timeout, + ag_cv_enable_timeout=no) + ) # end of AC_ARG_ENABLE + if test "X${ag_cv_enable_timeout}" != Xno + then + AC_DEFINE([TIMEOUT_ENABLED],[1], + [Define this if specify an autogen timeout]) + AG_TIMEOUT="@S|@{ag_cv_enable_timeout}" + else + AG_TIMEOUT='' + fi + AC_SUBST([AG_TIMEOUT]) + +]) # end of AC_DEFUN of AG_ENABLE_TIMEOUT + + +AC_DEFUN([AG_RUN_STRCSPN],[ + AC_MSG_CHECKING([whether strcspn matches prototype and works]) + AC_CACHE_VAL([ag_cv_run_strcspn],[ + AC_RUN_IFELSE([AC_LANG_SOURCE([@%:@include +int main (int argc, char ** argv) { + char zRej@<:@@:>@ = reject; + char zAcc@<:@@:>@ = "a-ok-eject"; + return strcspn( zAcc, zRej ) - 5; +}] )] + [ag_cv_run_strcspn=yes],[ag_cv_run_strcspn=no],[ag_cv_run_strcspn=no] + ) # end of RUN_IFELSE + ]) # end of AC_CACHE_VAL for ag_cv_run_strcspn + AC_MSG_RESULT([${ag_cv_run_strcspn}]) + if test "X${ag_cv_run_strcspn}" != Xno + then + AC_DEFINE([HAVE_STRCSPN],[1], + [Define this if strcspn matches prototype and works]) + else + COMPATOBJ="@S|@COMPATOBJ strcspn.lo" + fi + +]) # end of AC_DEFUN of AG_RUN_STRCSPN + + +AC_DEFUN([AG_RUN_UNAME_SYSCALL],[ + AC_MSG_CHECKING([whether uname(2) is POSIX]) + AC_CACHE_VAL([ag_cv_run_uname_syscall],[ + AC_RUN_IFELSE([AC_LANG_SOURCE([@%:@include +int main() { struct utsname unm; +return uname( &unm ); }] )], + [ag_cv_run_uname_syscall=yes],[ag_cv_run_uname_syscall=no],[ag_cv_run_uname_syscall=no] + ) # end of RUN_IFELSE + ]) # end of AC_CACHE_VAL for ag_cv_run_uname_syscall + AC_MSG_RESULT([${ag_cv_run_uname_syscall}]) + if test "X${ag_cv_run_uname_syscall}" != Xno + then + AC_DEFINE([HAVE_UNAME_SYSCALL],[1], + [Define this if uname(2) is POSIX]) + fi + +]) # end of AC_DEFUN of AG_RUN_UNAME_SYSCALL + + +AC_DEFUN([AG_TEST_LDFLAGS],[ + AC_MSG_CHECKING([whether runtime library dirs can be specified]) + AC_CACHE_VAL([ag_cv_test_ldflags],[ + ag_cv_test_ldflags=`exec 2> /dev/null +echo 'int main() { return 0; }' > conftest.$ac_ext +libs="${LIBS}" +LIBS="${LIBS} -Wl,-R/tmp" +if (eval $ac_link) > /dev/null 2>&1 +then echo '-Wl,-R${libdir}' ; rm -f conftest* ; exit 0 ; fi +LIBS="${libs} -R/tmp" +if (eval $ac_link) > /dev/null 2>&1 +then echo '-R${libdir}' ; rm -f conftest* ; exit 0 ; fi +rm -f conftest* ; exit 1` + if test $? -ne 0 || test -z "$ag_cv_test_ldflags" + then ag_cv_test_ldflags=no + fi + ]) # end of CACHE_VAL of ag_cv_test_ldflags + AC_MSG_RESULT([${ag_cv_test_ldflags}]) + if test "X${ag_cv_test_ldflags}" != Xno + then + AG_LDFLAGS="@S|@{ag_cv_test_ldflags}" + else + AG_LDFLAGS='' + fi + AC_SUBST([AG_LDFLAGS]) + +]) # end of AC_DEFUN of AG_TEST_LDFLAGS + + +AC_DEFUN([AG_ENABLE_DEBUG],[ + AC_ARG_ENABLE([debug], + AS_HELP_STRING([--enable-debug], [wanting autogen debugging]), + [ag_cv_enable_debug=${enable_debug}], + AC_CACHE_CHECK([whether wanting autogen debugging], ag_cv_enable_debug, + ag_cv_enable_debug=no) + ) # end of AC_ARG_ENABLE + if test "X${ag_cv_enable_debug}" != Xno + then + AC_DEFINE([DEBUG_ENABLED],[1], + [Define this if wanting autogen debugging]) + AC_DEFINE([DEBUG_ENABLED], [1], + [Define this if debugging is enabled]) + [f=`which dmalloc 2>/dev/null` + test -n "$f" && LIBS="${LIBS} -ldmalloc"] + fi + +]) # end of AC_DEFUN of AG_ENABLE_DEBUG + + +AC_DEFUN([AG_WITH_GROUP_PACKAGER],[ + AC_ARG_WITH([packager], + AS_HELP_STRING([--with-packager], [name of the packager of this software is supplied]), + [ag_cv_with_group_packager=${with_packager}], + AC_CACHE_CHECK([whether name of the packager of this software is supplied], ag_cv_with_group_packager, + ag_cv_with_group_packager=no) + ) # end of AC_ARG_WITH + if test "X${ag_cv_with_group_packager}" != Xno + then + AC_DEFINE_UNQUOTED([WITH_PACKAGER],["${withval}"], + [Define this if name of the packager of this software is supplied]) + fi + AC_ARG_WITH([packager-version], + AS_HELP_STRING([--with-packager-version], [packager-specific version information is supplied]), + [ag_cv_with_group_packager_version=${with_packager_version}], + AC_CACHE_CHECK([whether packager-specific version information is supplied], ag_cv_with_group_packager_version, + ag_cv_with_group_packager_version=no) + ) # end of AC_ARG_WITH + if test "X${ag_cv_with_group_packager_version}" != Xno + then + AC_DEFINE_UNQUOTED([WITH_PACKAGER_VERSION],["${withval}"], + [Define this if packager-specific version information is supplied]) + fi + AC_ARG_WITH([packager-bug-reports], + AS_HELP_STRING([--with-packager-bug-reports], [bug reporting URI/e-mail/etc. is supplied]), + [ag_cv_with_group_packager_bug_reports=${with_packager_bug_reports}], + AC_CACHE_CHECK([whether bug reporting URI/e-mail/etc. is supplied], ag_cv_with_group_packager_bug_reports, + ag_cv_with_group_packager_bug_reports=no) + ) # end of AC_ARG_WITH + if test "X${ag_cv_with_group_packager_bug_reports}" != Xno + then + AC_DEFINE_UNQUOTED([WITH_PACKAGER_BUG_REPORTS],["${withval}"], + [Define this if bug reporting URI/e-mail/etc. is supplied]) + fi + if test "X$with_packager" != "X" || \ + test "X$with_packager_version$with_packager_bug_reports" = "X" + then : + else + + AC_MSG_ERROR([--with-packager-{bug-reports,version} require --with-packager]) + fi + +]) # end of AC_DEFUN of AG_WITH_GROUP_PACKAGER + + +AC_DEFUN([INVOKE_AG_MACROS],[ + AC_REQUIRE([INVOKE_AG_MACROS_FIRST]) + # Check to see if shell scripts are desired. + AG_DISABLE_SHELL + + # Check to see if using shell scripts. + AG_TEST_DO_SHELL + + # Check to see if statically link autogen to libopts. + AG_ENABLE_STATIC_AUTOGEN + + # Check to see if setjmp() links okay. + AG_LINK_SETJMP + + # Check to see if __attribute__((format_arg(n))) works. + AG_COMPILE_FORMAT_ARG + + # Check to see if sigsetjmp() links okay. + AG_LINK_SIGSETJMP + + # Check to see if a working libxml2 can be found. + AG_WITHLIB_XML2 + + # Check to see if sysinfo(2) is Solaris. + AG_RUN_SOLARIS_SYSINFO + + # Check to see if specify an autogen timeout. + AG_ENABLE_TIMEOUT + + # Check to see if strcspn matches prototype and works. + AG_RUN_STRCSPN + + # Check to see if uname(2) is POSIX. + AG_RUN_UNAME_SYSCALL + + # Check to see if runtime library dirs can be specified. + AG_TEST_LDFLAGS + + # Check to see if wanting autogen debugging. + AG_ENABLE_DEBUG + + # Check to see if name of the packager of this software is supplied. + AG_WITH_GROUP_PACKAGER + + INVOKE_AG_MACROS_LAST +]) # end AC_DEFUN of INVOKE_AG_MACROS diff --git a/config/asm-underscore.m4 b/config/asm-underscore.m4 new file mode 100644 index 0000000..58a5299 --- /dev/null +++ b/config/asm-underscore.m4 @@ -0,0 +1,72 @@ +# asm-underscore.m4 serial 4 +dnl Copyright (C) 2010-2018 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 From Bruno Haible. Based on as-underscore.m4 in GNU clisp. + +# gl_ASM_SYMBOL_PREFIX +# Tests for the prefix of C symbols at the assembly language level and the +# linker level. This prefix is either an underscore or empty. Defines the +# C macro USER_LABEL_PREFIX to this prefix, and sets ASM_SYMBOL_PREFIX to +# a stringified variant of this prefix. + +AC_DEFUN([gl_ASM_SYMBOL_PREFIX], +[ + AC_REQUIRE([AC_PROG_EGREP]) + dnl We don't use GCC's __USER_LABEL_PREFIX__ here, because + dnl 1. It works only for GCC. + dnl 2. It is incorrectly defined on some platforms, in some GCC versions. + AC_REQUIRE([gl_C_ASM]) + AC_CACHE_CHECK( + [whether C symbols are prefixed with underscore at the linker level], + [gl_cv_prog_as_underscore], + [cat > conftest.c </dev/null 2>&1 + if LC_ALL=C $EGREP '(^|[[^a-zA-Z0-9_]])_foo([[^a-zA-Z0-9_]]|$)' conftest.$gl_asmext >/dev/null; then + gl_cv_prog_as_underscore=yes + else + gl_cv_prog_as_underscore=no + fi + rm -f conftest* + ]) + if test $gl_cv_prog_as_underscore = yes; then + USER_LABEL_PREFIX=_ + else + USER_LABEL_PREFIX= + fi + AC_DEFINE_UNQUOTED([USER_LABEL_PREFIX], [$USER_LABEL_PREFIX], + [Define to the prefix of C symbols at the assembler and linker level, + either an underscore or empty.]) + ASM_SYMBOL_PREFIX='"'${USER_LABEL_PREFIX}'"' + AC_SUBST([ASM_SYMBOL_PREFIX]) +]) + +# gl_C_ASM +# Determines how to produce an assembly language file from C source code. +# Sets the variables: +# gl_asmext - the extension of assembly language output, +# gl_c_asm_opt - the C compiler option that produces assembly language output. + +AC_DEFUN([gl_C_ASM], +[ + AC_EGREP_CPP([MicrosoftCompiler], + [ +#ifdef _MSC_VER +MicrosoftCompiler +#endif + ], + [gl_asmext='asm' + gl_c_asm_opt='-c -Fa' + ], + [gl_asmext='s' + gl_c_asm_opt='-S' + ]) +]) diff --git a/config/bootstrap b/config/bootstrap new file mode 100755 index 0000000..793579a --- /dev/null +++ b/config/bootstrap @@ -0,0 +1,209 @@ +#! /bin/bash +# -*- Mode: Shell-script -*- +# +# bootstrap --- maintainer's bootstrap script +# +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . + +# This script is designed to find any directories which contain a +# configure.ac in script, and to run the autotools programs from each +# of those directories to make sure they are in a state ready to +# 'configure; make; make install' +# +# Often this process involves more than `libtoolize; automake; autoconf', +# so supplementary actions can be placed in a bootstrap.local script +# in the same directory as this script, and anywhere in the source tree +# in bootstrap.dir files. The bootstrap.local script will be sourced +# twice; first with BOOTSTRAP=pre before the main part is run, and then +# again with BOOTSTRAP=post after the main part has finished. This makes +# it possible to set up any links or temporary files required for this +# script to work before it has executed, and then remove them when it +# has finished. The bootstrap.dir files are also sourced, in a random +# order, as they are found in the tree just before the BOOTSTRAP=post +# phase. This allows a developer to put any peculiar bootstrap actions +# required by individual directories where they can be seen (and not +# forgotten!). +# +# In an ideal world, running this bootstrap script (including any extra +# scripts it executes) should leave a freshly checked out repository tree +# in the same state as a freshly unrolled tarball. In this way, one +# no longer has to maintain generated files under source control, they +# can be generated after checkout using this bootstrap procedure. + +PS4='+BS=${FUNCNAME:-=}-$LINENO> ' + +top_srcdir=$( + cd $(dirname $0)/.. >/dev/null || kill -9 $$ + pwd ) +top_builddir=${top_srcdir} + +PS4='+shlib=${FUNCNAME:-=}-$LINENO> ' \ + source config/bootstrap.shlib + +config_tools() +{ + config_file=configure.ac + conf_dir=${top_srcdir}/config + test -f "${top_srcdir}/${config_file}.pre" || \ + die "${config_file}.pre not in ${top_srcdir}" + + # This missing function is used in many places + # + export config_file top_srcdir top_builddir + + # ------------------------------------------------------------------ + # Make sure all of the maintainer tools required for bootstrap are + # available on the host machine. + # ------------------------------------------------------------------ + # + tools="autoconf autoheader aclocal automake libtoolize" + for f in $tools + do + tool=$(command -v ${f}) > /dev/null || die "No $f found" + eval ${f}_reqver=$( + set -- $(${tool} --version | sed 1q) + eval echo \${$#}) + eval $(echo $f | tr '[a-z]' '[A-Z]')=${tool} + done + + char_mapper=$(command -v char-mapper) 2>/dev/null + test -x "${char_mapper}" || { + char_mapper=$( + cd add-on/char-mapper >&2 + make char-mapper >&2 || die "cannot make char-mapper" + echo ${PWD}/char-mapper) + } + export char_mapper + + echo bootstrapping in ${PWD} + if test -d "${TEMP_DIR}" + then + i_made_temp_dir=false + + else + TEMP_DIR=`mktemp -d ${TMPDIR:-/tmp}/bs-XXXXXX` + i_made_temp_dir=true + export TEMP_DIR + fi + test -d "$TEMP_DIR" || { + temp_dir=${TMP:-/tmp}/bs-$$ + rm -rf ${TEMP_DIR} + mkdir ${TEMP_DIR} + chmod 700 ${TEMP_DIR} + } + + trap "rm -rf ${TEMP_DIR}" 0 + set +e +} + +# Source any local scripts which add to the bootstrap procedure. +# The bootstrap.local script should test the value of the BOOTSTRAP +# environment variable to see whether it should run the sections +# to be called before the main script, or afterwards. +# +source_bs() { + local file=${2} + cd ${file%/*} + file=${file##*/} + test -f $file && ( + PS4="+${1#./}=\${FUNCNAME:-=}-\$LINENO> " + shift 2 + : IN $PWD sourcing $file + source ${PWD}/${file} ${1+"$@"} || die ${file} failed + ) + file=${PWD##*/} + cd - >/dev/null +} + +pre_local() +{ + BOOTSTRAP=pre REQUEST_METHOD= + export BOOTSTRAP + unset REQUEST_METHOD + source_bs pbs ${conf_dir}/bootstrap.local pre + source_bs aobs autoopts/bootstrap.dir aoconf +} + +post_local() +{ + bslist=`find . -name bootstrap.dir` + for f in ${bslist} + do + source_bs ${f%/bootstrap.dir} $f recursive + done + + source_bs Abs ${conf_dir}/bootstrap.local post +} + +filter_chaff() { + cat > ${TEMP_DIR}/config-log.txt + if test -f configure + then + sedcmd='/configure.ac:.*no .* detected/,/configure.ac:.*top level/d' + sed "$sedcmd" ${TEMP_DIR}/config-log.txt + else + cat ${TEMP_DIR}/config-log.txt + fi +} + +run_autotools() +{ + cd ${top_builddir} + # remove any stale config.cache + doit rm -f config.cache + + test -n "$auxdir" || auxdir=${top_srcdir} + test -d $auxdir || auxdir=. + + doit $LIBTOOLIZE --force + doit $ACLOCAL -I config + doit $AUTOHEADER + doit $AUTOMAKE --gnu --add-missing + test -f libtool || cp -fp $(command -v libtool) . + doit $AUTOCONF + sedcmd='s/^PS4=/## PS4=/' + shopt -qo xtrace && { + sedcmd+=$';/SHELL.*CONFIG_STATUS/{\n' + sedcmd+='s/^/ PS4="+csts=\\${FUNCNAME:-=}-\\$LINENO> " /' + sedcmd+=$'\ns/SHELL /SHELL -x /\n}' + } + sed -i "$sedcmd" configure +} + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# M A I N +# +{ + config_tools + pre_local + ( run_autotools 2>&1 ) | filter_chaff + post_local + + trap '' 0 + echo 'bootstrap complete' + ${i_made_temp_dir} && rm -rf ${TEMP_DIR} + : ; exit +} +# Local Variables: +# mode:shell-script +# sh-indentation:4 +# sh-basic-offset:4 +# indent-tabs-mode: nil +# End: + +# bootstrap ends here diff --git a/config/bootstrap.local b/config/bootstrap.local new file mode 100644 index 0000000..fd50f3a --- /dev/null +++ b/config/bootstrap.local @@ -0,0 +1,277 @@ +#! /bin/echo This_file_must_be_sourced,_not_executed +# +# config/bootstrap.local --- maintainer's bootstrap script +# +# Author: Bruce Korb +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . + +locate_exe() +{ + if [ -x "$1" ] + then + echo "$1" + return 0 + fi + + case "${1}" in + */* ) + echo "Cannot find ${1}" >&2 + return 1 + ;; + "" ) + echo "USAGE: locate_exe " >&2 + exit 1 + ;; + * ) + name="${1}" + ;; + esac + + SV="${IFS}" + IFS=" :" + set -- ${PATH} + for f + do + if [ -x ${f}/${name} ] + then + echo ${f}/${name} + return 0 + fi + done + return 1 +} + +install_m4() { + local d= m4=$1 ; shift + set -- ${1+"$@"} /usr/local/share /usr/share + for d + do + test -f "$d/aclocal/$m4" || continue + echo "Installing $m4" + cp "$d/aclocal/$m4" config/. + return 0 + done + return 1 +} + +one_year_limit() { + ( + set +x + year_ago=$(( $(date +%s) - (60 * 60 * 24 * 365) )) + limit=$(date --date=@${year_ago} +%Y-%M-%d) + while IFS= read -r line + do + if [[ "$line" =~ ^[12].* ]] + then + set -- $line + [[ "$1" < "$limit" ]] && exit 0 + fi + + echo "$line" + done + ) +} + +find_gnulib() { + test -z "$GNULIBDIR" && { + local gld=$(command -v gnulib-tool) + test "X$gld" = "X" || gld=$(dirname "$gld") + for d in $HOME/tools/gnulib ~gnu/proj/gnulib /usr/share/gnulib \ + ${gld:+"$gld"} + do + test -d "$d" && GNULIBDIR=$d && break + done + test -z "$GNULIBDIR" && die "cannot find GNULIBDIR" + } + unset LANG || LANG='' + for f in gnulib-tool m4/lib-link.m4 build-aux/config.rpath \ + build-aux/git-version-gen + do test -s ${GNULIBDIR}/$f || die "not found: ${GNULIBDIR}/$f" + g=${f##*/} ; g=${g%%.*} ; g=${g//-/_} + eval export GL_${g^^}=${GNULIBDIR}/$f + done +} + +set_ag_ver() { + local cmt= ver=$( + \cd ${SOURCE_DIR} + ${GL_GIT_VERSION_GEN} ZZJUNK) + + export AG_MAJOR_VERSION=${ver%%.*} + ver=${ver#${AG_MAJOR_VERSION}.} + local scmd="s/^AG_MAJOR_VERSION=.*/AG_MAJOR_VERSION=${AG_MAJOR_VERSION}/" + + export AG_MINOR_VERSION=${ver%%.*} + ver=${ver#${AG_MINOR_VERSION}} + scmd+=";s/^AG_MINOR_VERSION=.*/AG_MINOR_VERSION=${AG_MINOR_VERSION}/" + + ver=${ver#.} + export AG_PATCHLEVEL= + if test ${#ver} -eq 0 + then + export AG_PATCHLEVEL= + else + export AG_PATCHLEVEL=.${ver%%.*} + ver=${ver#${AG_PATCHLEVEL#.}} + test ${#ver} -gt 0 && { + ver=${ver#.} + AG_PATCHLEVEL+=.$(printf %03u ${ver%%-*}) + } + fi + scmd+=";s/^AG_PATCHLEVEL=.*/AG_PATCHLEVEL=${AG_PATCHLEVEL}/" + sed "$scmd" VERSION.pre > VERSION + eval "$(egrep '^[A-Z][A-Z0-9_]+=' VERSION | sed 's/^/export /')" + test ${#AGexe} -eq 0 && AGexe=autogen + f=$(command -v ${AGexe}) + if test -x "$f" + then AGexe="$f" + else AGexe=$(command -v autogen) + fi +} + +config_versions() { + find_gnulib + set_ag_ver + unset LANG || LANG='' + + sedcmd="s/^AC_INIT(.*/AC_INIT([${PACKAGE}],[${AG_VERSION}],[${EADDR}])/" + + sed "$sedcmd" ${config_file}.pre > ${config_file} + sedcmd="/eaddr *=/s/= .*/= '${EADDR}';/" + for f in $(egrep -l 'eaddr +=' */*opts.def) + do sed "$sedcmd" $f > X ; mv -f X $f + done + + sed "1s/__CURRENT_VERSION__.*/${AG_VERSION} - $(date '+%B %Y')/" NEWS.pre > NEWS + + cd ${top_srcdir} + + cp snprintfv/snprintfv.m4 config/. + f=$(exec 2>/dev/null ; command -v guile) + test ${#f} -gt 0 && f=${f%/guile} && f=${f%/bin} + install_m4 guile.m4 $f + install_m4 pkg.m4 + + marker='=== Component Todo:' + sedcmd="/${marker}/,\$d" + rm -f TODO + { + sed "$sedcmd" TODO-top + for f in */TODO + do + test -s $f || continue + echo ; echo ${marker} ${f} '===' + cat ${f} + done + } > TODO + cd ${top_srcdir} + + glopts=' + --import + --lgpl=2 + --lib=do_not_make_me + --libtool + --local-dir=tmp + --m4-base=config + --makefile-name=gnulib.mk + --no-changelog + --source-base=autoopts + --symlink' + glmods=' + extensions + gendocs + gettext-h + havelib + parse-duration + snippet/_Noreturn + stdnoreturn' + cmd=$(echo ${GL_GNULIB_TOOL} $glopts $glmods) + echo GNULIB-TOOL: $cmd + ${cmd} + sed -i 's/do_not_make_me_.*_SOURCES/EXTRA_DIST/;/do_not_make_me/d' \ + autoopts/gnulib.mk + sedcmd=$(cat <<- \_EndOfSed + s@/config/snippet/@/compat/@ + \@begin .*snippet/_Noreturn@,\@end .*snippet/_Noreturn@ { + /^##/d + p + } + \@begin .* module stdnoreturn@,\@end .* module stdnoreturn@ { + /^##/d + p + } + _EndOfSed + ) + sedcmd='s@/config/snippet/@/compat/@' + sedcmd+=$'\n\@begin .*snippet/_Noreturn@,\@end .*snippet/_Noreturn@ p' + sedcmd+=$'\n\@begin .* module stdnoreturn@,\@end .* module stdnoreturn@ p' + sed -n "$sedcmd" autoopts/gnulib.mk | \ + grep -v '^##' > pkg/libopts/stdnoreturn.mk + cp autoopts/gnulib.mk /tmp + cp ${GNULIBDIR}/build-aux/config.rpath ${GNULIBDIR}/m4/lib-link.m4 config/. + + ${GNULIBDIR}/build-aux/gitlog-to-changelog | \ + one_year_limit > ${top_srcdir}/ChangeLog + echo GNULIB-TOOL-DONE +} + +tweak_Makefile_am() +{ + # IF the source dir is not known, + # THEN it is the directory above the directory of this file. + # + test -z "${top_srcdir}" && \ + top_srcdir=$({ \cd $(dirname $0) ; \cd .. ; } >/dev/null ; pwd) + cd ${top_srcdir}/pkg + { + sed '/^LIBOPTS_FILES *=/{ + s/=.*/= \\/ + q + }' Makefile.am.pre + + find libopts -type f -name '[a-zA-Z]*' | \ + columns --spread=1 -I4 --line=' \' + echo + + sed '1,/LIBOPTS_FILES *=/d' Makefile.am.pre + } > Makefile.am + cd ${top_srcdir} + cp agen5/Makefile.am.pre agen5/Makefile.am +} + +cd ${top_srcdir} + +case "${1}" in +( pre ) + echo '@setfilename autogen.info' > doc/autogen.texi + test -f ${top_srcdir}/configure && rm -f ${top_srcdir}/configure + config_versions + tweak_Makefile_am + ;; + +( post ) + rm -f doc/autogen.texi + ;; +esac + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# indent-tabs-mode: nil +# End: + +# config/bootstrap.local ends here diff --git a/config/bootstrap.shlib b/config/bootstrap.shlib new file mode 100644 index 0000000..26aeb04 --- /dev/null +++ b/config/bootstrap.shlib @@ -0,0 +1,256 @@ +#! /bin/echo This_file_must_be_sourced,_not_executed +# config/bootstrap.local --- maintainer's bootstrap script +# +# Author: Bruce Korb +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . + +# This file contains various utility functions for the "bootstrap" scripts +# that are scattered about. + +mainpid=$$ + +die() { + echo "bootstrap failure: $*" >&2 + kill -9 ${mainpid} + exit 1 +} + +doit () +{ + if test "x$1" != x: + then + echo "RUN: $*" + eval "$@" || die "FAILURE $?: $*" + fi +} + +case `set -o` in +*posix*) set -o posix ;; +*) exec bash $0 ${1+"$@"} ;; +esac + +case "${SHELL}" in +*[akz]sh) : ;; +*) + while : ; do + SHELL=`which bash 2>/dev/null` + test -x "${SHELL}" && break + + SHELL=`which ksh 2>/dev/null` + test -x "${SHELL}" && break + + SHELL=/usr/xpg4/bin/sh + test -x "${SHELL}" && break + + SHELL=`which sh 2>/dev/null` + test -x "${SHELL}" && break + + die "unable to determine which shell to use" + done + ;; +esac + +case "${VERBOSE}" in +[tTyY1]* ) VERBOSE=true ;; +[fFnN0]* ) VERBOSE=false ;; +* ) + case "$-" in + *x* ) VERBOSE=true ;; + * ) VERBOSE=false ;; + esac +esac + +if ${VERBOSE} +then setx=set\ -x dashx=-x ; set -x +else setx=: dashx= ; set +x +fi + +test -z "${BASH_VERSION}" && \ + local() { "$@" ; } + +# Setup run_ag +test ${#top_srcdir} -eq 0 && { + echo "NO TOP DIRECTORY in $PWD" + exit 1 +} 1>&2 +f=$(\cd ${top_srcdir}/autoopts/tpl >/dev/null && pwd) +test ${#top_builddir} -eq 0 && { + echo "NO BUILD DIRECTORY in $PWD" + exit 1 +} 1>&2 +g=$(\cd ${top_builddir}/autoopts/tpl >/dev/null && pwd) +tpl_dir='-L'$f +test "X$f" = "X$g" || tpl_dir=$tpl_dir' -L'$g +readonly tpl_dir + +if ${VERBOSE} +then + # vgopts='--suppressions=/old-home/bkorb/ag/valgrind.conf --leak-check=yes' + # valgrind ${vgopts} --log-file=${vgfile} \ + + run_ag() + { + local tag=${1} ; shift + # local vgfile=/tmp/vglog/${tag}-%p.txt + local tfile='>>'ag-${tag}-$$.log + if test -n "$DEPFILE" + then tag="-MTstamp-${tag} -MF${DEPFILE} -MP" + else tag="-MFstamp-${tag} -MP" + fi + tag="${tag} --trace=every --trace-out=${tfile}" + + MALLOC_CHECK_=2 \ + ${AGexe} ${tpl_dir} ${tag} "$@" || die "FAILED: ${AGexe} $*" + } +else + run_ag() + { + # local vgfile=/tmp/vglog/${1}-%p.txt + if test -n "$DEPFILE" + then tag="-MTstamp-${1} -MF${DEPFILE} -MP" + else tag="-MFstamp-${1} -MP" + fi + shift + + echo ${AGexe} ${tpl_dir} ${tag} "$@" + ${AGexe} ${tpl_dir} ${tag} "$@" || die "FAILED: ${AGexe} $*" + } +fi + +trap 'die "trapped exit signal"' 0 + +test "X${CDPATH}" = X || { + ( unset CDPATH ) > /dev/null 2>&1 && unset CDPATH || CDPATH='' +} + +nl=$'\n' +ht=$'\t' +GREP=$(command -v grep) +EGREP=${GREP}\ -E +FGREP=${GREP}\ -F + +# Check for AutoGen version 5. +# +skip_gen=false +test -x "${AGexe}" || { + AGexe=${AGexe:-$(command -v autogen)} + test -x "$AGexe" || { + skip_gen=true + AGexe='die "AutoGen requires autogen to bootstrap"' + GDexe=${AGexe} + CLexe=${AGexe} + } +} + +${skip_gen} || { + v="$($AGexe --version || :)" + v=$(echo "$v" | sed 's/.* //;1q') + case "$v" in + 5.* ) : ;; + * ) die "OUT OF DATE AutoGen: $v" ;; + esac + + GDexe=${AGexe%/*}/getdefs + CLexe=${AGexe%/*}/columns + test -x "${GDexe}" -a -x "${CLexe}" || \ + die "autogen support programs are missing" +} + +export AGexe GDexe CLexe setx dashx VERBOSE nl ht + +untar_touch() { + list=`tar -xzvf "$@"` + touch $list +} + +# # # # # # # # # # # # # # # # # # # +# +# Make the option processing files: +# +make_opts() +{ + # Make the option processing files: + # + if ${skip_gen} + then untar_touch ${PWD##*/}-opts.tgz + else run_ag opts ${DEBUG_OPTS} *opts.def + fi +} + +# # # # # # # # # # # # # # # # # # # +# +# Extract all the static procedure declarations into a "proto.h" header. +# These functions are shared throughout the autoopts code. +# +make_proto() +{ + local temp_proto=proto-h$$ proto_h=proto.h + + exec 5> $temp_proto + + local files=`ls -1 *.c | grep -v 'fsm\.c$'` + local base_dir=`basename \`pwd\`` + local marker=`echo ${base_dir} | tr '[a-z]' '[A-Z]'`_PROTO_H_GUARD + + cat >&5 <<- _EOF_ + /* -*- buffer-read-only: t -*- vi: set ro: + * + * Prototypes for ${base_dir} + * Generated `date` + */ + #ifndef ${marker} + #define ${marker} 1 + + _EOF_ + + deplist= + local sed_static='\@^\(noreturn \)\?static @, \@^{@ p' + local sed_trim='s/)$/);/;s/^{.*//' + + for f in ${files} + do + grep -q 'buffer-read-only:' $f && continue + + txt=$(sed -n "$sed_static" $f | sed "$sed_trim") + test ${#txt} -gt 4 && { + printf '\n/*\n * Static declarations from %s\n */\n' $f + echo "$txt" + } >&5 + done + cat >&5 <<- _EOF + + #endif /* ${marker} */ + _EOF + exec 5>&- + + if test -f ${proto_h} && cmp -s ${temp_proto} ${proto_h} + then + rm -f ${temp_proto} + touch ${proto_h} + else + mv -f ${temp_proto} ${proto_h} + fi +} + +# Local Variables: +# mode:shell-script +# sh-indentation:4 +# sh-basic-offset:4 +# indent-tabs-mode: nil +# End: + +# bootstrap.shlib ends here diff --git a/config/compile b/config/compile new file mode 100755 index 0000000..99e5052 --- /dev/null +++ b/config/compile @@ -0,0 +1,348 @@ +#! /bin/sh +# Wrapper for compilers which do not understand '-c -o'. + +scriptversion=2018-03-07.03; # UTC + +# Copyright (C) 1999-2018 Free Software Foundation, Inc. +# Written by Tom Tromey . +# +# 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, see . + +# 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 file is maintained in Automake, please report +# bugs to or send patches to +# . + +nl=' +' + +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent tools from complaining about whitespace usage. +IFS=" "" $nl" + +file_conv= + +# func_file_conv build_file lazy +# Convert a $build file to $host form and store it in $file +# Currently only supports Windows hosts. If the determined conversion +# type is listed in (the comma separated) LAZY, no conversion will +# take place. +func_file_conv () +{ + file=$1 + case $file in + / | /[!/]*) # absolute file, and not a UNC file + if test -z "$file_conv"; then + # lazily determine how to convert abs files + case `uname -s` in + MINGW*) + file_conv=mingw + ;; + CYGWIN*) + file_conv=cygwin + ;; + *) + file_conv=wine + ;; + esac + fi + case $file_conv/,$2, in + *,$file_conv,*) + ;; + mingw/*) + file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` + ;; + cygwin/*) + file=`cygpath -m "$file" || echo "$file"` + ;; + wine/*) + file=`winepath -w "$file" || echo "$file"` + ;; + esac + ;; + esac +} + +# func_cl_dashL linkdir +# Make cl look for libraries in LINKDIR +func_cl_dashL () +{ + func_file_conv "$1" + if test -z "$lib_path"; then + lib_path=$file + else + lib_path="$lib_path;$file" + fi + linker_opts="$linker_opts -LIBPATH:$file" +} + +# func_cl_dashl library +# Do a library search-path lookup for cl +func_cl_dashl () +{ + lib=$1 + found=no + save_IFS=$IFS + IFS=';' + for dir in $lib_path $LIB + do + IFS=$save_IFS + if $shared && test -f "$dir/$lib.dll.lib"; then + found=yes + lib=$dir/$lib.dll.lib + break + fi + if test -f "$dir/$lib.lib"; then + found=yes + lib=$dir/$lib.lib + break + fi + if test -f "$dir/lib$lib.a"; then + found=yes + lib=$dir/lib$lib.a + break + fi + done + IFS=$save_IFS + + if test "$found" != yes; then + lib=$lib.lib + fi +} + +# func_cl_wrapper cl arg... +# Adjust compile command to suit cl +func_cl_wrapper () +{ + # Assume a capable shell + lib_path= + shared=: + linker_opts= + for arg + do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + eat=1 + case $2 in + *.o | *.[oO][bB][jJ]) + func_file_conv "$2" + set x "$@" -Fo"$file" + shift + ;; + *) + func_file_conv "$2" + set x "$@" -Fe"$file" + shift + ;; + esac + ;; + -I) + eat=1 + func_file_conv "$2" mingw + set x "$@" -I"$file" + shift + ;; + -I*) + func_file_conv "${1#-I}" mingw + set x "$@" -I"$file" + shift + ;; + -l) + eat=1 + func_cl_dashl "$2" + set x "$@" "$lib" + shift + ;; + -l*) + func_cl_dashl "${1#-l}" + set x "$@" "$lib" + shift + ;; + -L) + eat=1 + func_cl_dashL "$2" + ;; + -L*) + func_cl_dashL "${1#-L}" + ;; + -static) + shared=false + ;; + -Wl,*) + arg=${1#-Wl,} + save_ifs="$IFS"; IFS=',' + for flag in $arg; do + IFS="$save_ifs" + linker_opts="$linker_opts $flag" + done + IFS="$save_ifs" + ;; + -Xlinker) + eat=1 + linker_opts="$linker_opts $2" + ;; + -*) + set x "$@" "$1" + shift + ;; + *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) + func_file_conv "$1" + set x "$@" -Tp"$file" + shift + ;; + *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) + func_file_conv "$1" mingw + set x "$@" "$file" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift + done + if test -n "$linker_opts"; then + linker_opts="-link$linker_opts" + fi + exec "$@" $linker_opts + exit 1 +} + +eat= + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: compile [--help] [--version] PROGRAM [ARGS] + +Wrapper for compilers which do not understand '-c -o'. +Remove '-o dest.o' from ARGS, run PROGRAM with the remaining +arguments, and rename the output as expected. + +If you are trying to build a whole package this is not the +right script to run: please start by reading the file 'INSTALL'. + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "compile $scriptversion" + exit $? + ;; + cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \ + icl | *[/\\]icl | icl.exe | *[/\\]icl.exe ) + func_cl_wrapper "$@" # Doesn't return... + ;; +esac + +ofile= +cfile= + +for arg +do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + # So we strip '-o arg' only if arg is an object. + eat=1 + case $2 in + *.o | *.obj) + ofile=$2 + ;; + *) + set x "$@" -o "$2" + shift + ;; + esac + ;; + *.c) + cfile=$1 + set x "$@" "$1" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift +done + +if test -z "$ofile" || test -z "$cfile"; then + # If no '-o' option was seen then we might have been invoked from a + # pattern rule where we don't need one. That is ok -- this is a + # normal compilation that the losing compiler can handle. If no + # '.c' file was seen then we are probably linking. That is also + # ok. + exec "$@" +fi + +# Name of file we expect compiler to create. +cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` + +# Create the lock directory. +# Note: use '[/\\:.-]' here to ensure that we don't use the same name +# that we are using for the .o file. Also, base the name on the expected +# object file name, since that is what matters with a parallel build. +lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d +while true; do + if mkdir "$lockdir" >/dev/null 2>&1; then + break + fi + sleep 1 +done +# FIXME: race condition here if user kills between mkdir and trap. +trap "rmdir '$lockdir'; exit 1" 1 2 15 + +# Run the compile. +"$@" +ret=$? + +if test -f "$cofile"; then + test "$cofile" = "$ofile" || mv "$cofile" "$ofile" +elif test -f "${cofile}bj"; then + test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" +fi + +rmdir "$lockdir" +exit $ret + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/config/config.guess b/config/config.guess new file mode 100755 index 0000000..256083a --- /dev/null +++ b/config/config.guess @@ -0,0 +1,1476 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright 1992-2018 Free Software Foundation, Inc. + +timestamp='2018-03-08' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# 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 Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). +# +# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. +# +# You can get the latest version of this script from: +# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess +# +# Please send patches to . + + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Options: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright 1992-2018 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." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > "$dummy.c" ; + for c in cc gcc c89 c99 ; do + if ($c -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +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 + +case "$UNAME_SYSTEM" in +Linux|GNU|GNU/*) + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + LIBC=gnu + + eval "$set_cc_for_build" + cat <<-EOF > "$dummy.c" + #include + #if defined(__UCLIBC__) + LIBC=uclibc + #elif defined(__dietlibc__) + LIBC=dietlibc + #else + LIBC=gnu + #endif + EOF + eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`" + + # If ldd exists, use it to detect musl libc. + if command -v ldd >/dev/null && \ + ldd --version 2>&1 | grep -q ^musl + then + LIBC=musl + fi + ;; +esac + +# Note: order is significant - the case branches are not exclusive. + +case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ + "/sbin/$sysctl" 2>/dev/null || \ + "/usr/sbin/$sysctl" 2>/dev/null || \ + echo unknown)` + case "$UNAME_MACHINE_ARCH" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + earmv*) + arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` + endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` + machine="${arch}${endian}"-unknown + ;; + *) machine="$UNAME_MACHINE_ARCH"-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently (or will in the future) and ABI. + case "$UNAME_MACHINE_ARCH" in + earm*) + os=netbsdelf + ;; + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval "$set_cc_for_build" + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # Determine ABI tags. + case "$UNAME_MACHINE_ARCH" in + earm*) + expr='s/^earmv[0-9]/-eabi/;s/eb$//' + abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "$UNAME_VERSION" in + Debian*) + release='-gnu' + ;; + *) + release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "$machine-${os}${release}${abi}" + exit ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE" + exit ;; + *:LibertyBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` + echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE" + exit ;; + *:MidnightBSD:*:*) + echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE" + exit ;; + *:ekkoBSD:*:*) + echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE" + exit ;; + *:SolidBSD:*:*) + echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE" + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd"$UNAME_RELEASE" + exit ;; + *:MirBSD:*:*) + echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE" + exit ;; + *:Sortix:*:*) + echo "$UNAME_MACHINE"-unknown-sortix + exit ;; + *:Redox:*:*) + echo "$UNAME_MACHINE"-unknown-redox + exit ;; + mips:OSF1:*.*) + echo mips-dec-osf1 + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE=alpha ;; + "EV4.5 (21064)") + UNAME_MACHINE=alpha ;; + "LCA4 (21066/21068)") + UNAME_MACHINE=alpha ;; + "EV5 (21164)") + UNAME_MACHINE=alphaev5 ;; + "EV5.6 (21164A)") + UNAME_MACHINE=alphaev56 ;; + "EV5.6 (21164PC)") + UNAME_MACHINE=alphapca56 ;; + "EV5.7 (21164PC)") + UNAME_MACHINE=alphapca57 ;; + "EV6 (21264)") + UNAME_MACHINE=alphaev6 ;; + "EV6.7 (21264A)") + UNAME_MACHINE=alphaev67 ;; + "EV6.8CB (21264C)") + UNAME_MACHINE=alphaev68 ;; + "EV6.8AL (21264B)") + UNAME_MACHINE=alphaev68 ;; + "EV6.8CX (21264D)") + UNAME_MACHINE=alphaev68 ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE=alphaev69 ;; + "EV7 (21364)") + UNAME_MACHINE=alphaev7 ;; + "EV7.9 (21364A)") + UNAME_MACHINE=alphaev79 ;; + esac + # A Pn.n version is a patched version. + # 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. + echo "$UNAME_MACHINE"-dec-osf"`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`" + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo "$UNAME_MACHINE"-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo "$UNAME_MACHINE"-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix"$UNAME_RELEASE" + exit ;; + arm*:riscos:*:*|arm*:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-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 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux"$UNAME_RELEASE" + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval "$set_cc_for_build" + SUN_ARCH=i386 + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != no_compiler_found ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH=x86_64 + fi + fi + echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + exit ;; + 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 ;; + 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 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos"$UNAME_RELEASE" + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /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 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos"$UNAME_RELEASE" + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint"$UNAME_RELEASE" + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint"$UNAME_RELEASE" + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint"$UNAME_RELEASE" + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint"$UNAME_RELEASE" + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint"$UNAME_RELEASE" + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint"$UNAME_RELEASE" + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten"$UNAME_RELEASE" + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten"$UNAME_RELEASE" + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix"$UNAME_RELEASE" + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix"$UNAME_RELEASE" + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix"$UNAME_RELEASE" + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #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_FOR_BUILD -o "$dummy" "$dummy.c" && + dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`"$dummy" "$dummyarg"` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos"$UNAME_RELEASE" + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ "$UNAME_PROCESSOR" = mc88100 ] || [ "$UNAME_PROCESSOR" = mc88110 ] + then + if [ "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx ] || \ + [ "$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 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix"`echo "$UNAME_RELEASE"|sed -e 's/-/_/g'`" + exit ;; + ????????: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 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" + fi + echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV" + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + 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 ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/lslpp ] ; then + IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | + awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` + else + IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" + fi + echo "$IBM_ARCH"-ibm-aix"$IBM_REV" + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd"$UNAME_RELEASE" # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` + case "$UNAME_MACHINE" in + 9000/31?) HP_ARCH=m68000 ;; + 9000/[34]??) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "$sc_cpu_version" in + 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 + 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "$sc_kernel_bits" in + 32) HP_ARCH=hppa2.0n ;; + 64) HP_ARCH=hppa2.0w ;; + '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "$HP_ARCH" = "" ]; then + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ "$HP_ARCH" = hppa2.0w ] + then + eval "$set_cc_for_build" + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH=hppa2.0w + else + HP_ARCH=hppa64 + fi + fi + echo "$HP_ARCH"-hp-hpux"$HPUX_REV" + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux"$HPUX_REV" + exit ;; + 3050*:HI-UX:*:*) + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" + #include + 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_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo "$UNAME_MACHINE"-unknown-osf1mk + else + echo "$UNAME_MACHINE"-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE" + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi"$UNAME_RELEASE" + exit ;; + *:BSD/OS:*:*) + echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE" + exit ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`/usr/bin/uname -p` + case "$UNAME_PROCESSOR" in + amd64) + UNAME_PROCESSOR=x86_64 ;; + i386) + UNAME_PROCESSOR=i586 ;; + esac + echo "$UNAME_PROCESSOR"-unknown-freebsd"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" + exit ;; + i*:CYGWIN*:*) + echo "$UNAME_MACHINE"-pc-cygwin + exit ;; + *:MINGW64*:*) + echo "$UNAME_MACHINE"-pc-mingw64 + exit ;; + *:MINGW*:*) + echo "$UNAME_MACHINE"-pc-mingw32 + exit ;; + *:MSYS*:*) + echo "$UNAME_MACHINE"-pc-msys + exit ;; + i*:PW*:*) + echo "$UNAME_MACHINE"-pc-pw32 + exit ;; + *:Interix*:*) + case "$UNAME_MACHINE" in + x86) + echo i586-pc-interix"$UNAME_RELEASE" + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix"$UNAME_RELEASE" + exit ;; + IA64) + echo ia64-unknown-interix"$UNAME_RELEASE" + exit ;; + esac ;; + i*:UWIN*:*) + echo "$UNAME_MACHINE"-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + exit ;; + *:GNU:*:*) + # the GNU system + echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-unknown-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`" + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC" + exit ;; + i*86:Minix:*:*) + echo "$UNAME_MACHINE"-pc-minix + exit ;; + aarch64:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC=gnulibc1 ; fi + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + arc:Linux:*:* | arceb:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + arm*:Linux:*:*) + eval "$set_cc_for_build" + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabi + else + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + cris:Linux:*:*) + echo "$UNAME_MACHINE"-axis-linux-"$LIBC" + exit ;; + crisv32:Linux:*:*) + echo "$UNAME_MACHINE"-axis-linux-"$LIBC" + exit ;; + e2k:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + frv:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + hexagon:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + i*86:Linux:*:*) + echo "$UNAME_MACHINE"-pc-linux-"$LIBC" + exit ;; + ia64:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + k1om:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + m32r*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + m68*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU'`" + test "x$CPU" != x && { echo "$CPU-unknown-linux-$LIBC"; exit; } + ;; + mips64el:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + openrisc*:Linux:*:*) + echo or1k-unknown-linux-"$LIBC" + exit ;; + or32:Linux:*:* | or1k*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-"$LIBC" + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-"$LIBC" + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;; + PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;; + *) echo hppa-unknown-linux-"$LIBC" ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-"$LIBC" + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-"$LIBC" + exit ;; + ppc64le:Linux:*:*) + echo powerpc64le-unknown-linux-"$LIBC" + exit ;; + ppcle:Linux:*:*) + echo powerpcle-unknown-linux-"$LIBC" + exit ;; + riscv32:Linux:*:* | riscv64:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo "$UNAME_MACHINE"-ibm-linux-"$LIBC" + exit ;; + sh64*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + sh*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + tile*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + vax:Linux:*:*) + echo "$UNAME_MACHINE"-dec-linux-"$LIBC" + exit ;; + x86_64:Linux:*:*) + echo "$UNAME_MACHINE"-pc-linux-"$LIBC" + exit ;; + xtensa*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + i*86:DYNIX/ptx:4*:*) + # 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. + echo i386-sequent-sysv4 + exit ;; + 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 ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo "$UNAME_MACHINE"-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo "$UNAME_MACHINE"-unknown-stop + exit ;; + i*86:atheos:*:*) + echo "$UNAME_MACHINE"-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo "$UNAME_MACHINE"-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos"$UNAME_RELEASE" + exit ;; + i*86:*DOS:*:*) + echo "$UNAME_MACHINE"-pc-msdosdjgpp + exit ;; + i*86:*:4.*:*) + UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL" + else + echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL" + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}{$UNAME_VERSION}" + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL" + else + echo "$UNAME_MACHINE"-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configure will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + 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 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*: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; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + 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; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos"$UNAME_RELEASE" + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos"$UNAME_RELEASE" + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos"$UNAME_RELEASE" + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos"$UNAME_RELEASE" + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv"$UNAME_RELEASE" + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *: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 ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo "$UNAME_MACHINE"-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux"$UNAME_RELEASE" + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv"$UNAME_RELEASE" + else + echo mips-unknown-sysv"$UNAME_RELEASE" + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + x86_64:Haiku:*:*) + echo x86_64-unknown-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux"$UNAME_RELEASE" + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux"$UNAME_RELEASE" + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux"$UNAME_RELEASE" + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux"$UNAME_RELEASE" + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux"$UNAME_RELEASE" + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux"$UNAME_RELEASE" + exit ;; + SX-ACE:SUPER-UX:*:*) + echo sxace-nec-superux"$UNAME_RELEASE" + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody"$UNAME_RELEASE" + exit ;; + *:Rhapsody:*:*) + echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE" + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + eval "$set_cc_for_build" + if test "$UNAME_PROCESSOR" = unknown ; then + UNAME_PROCESSOR=powerpc + fi + if test "`echo "$UNAME_RELEASE" | sed -e 's/\..*//'`" -le 10 ; then + if [ "$CC_FOR_BUILD" != no_compiler_found ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc + if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_PPC >/dev/null + then + UNAME_PROCESSOR=powerpc + fi + fi + elif test "$UNAME_PROCESSOR" = i386 ; then + # Avoid executing cc on OS X 10.9, as it ships with a stub + # that puts up a graphical alert prompting to install + # developer tools. Any system running Mac OS X 10.7 or + # later (Darwin 11 and later) is required to have a 64-bit + # processor. This is not true of the ARM version of Darwin + # that Apple uses in portable devices. + UNAME_PROCESSOR=x86_64 + fi + echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE" + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = x86; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE" + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NEO-*:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSE-*:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSR-*:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSV-*:NONSTOP_KERNEL:*:*) + echo nsv-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSX-*:NONSTOP_KERNEL:*:*) + echo nsx-tandem-nsk"$UNAME_RELEASE" + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE" + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = 386; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo "$UNAME_MACHINE"-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux"$UNAME_RELEASE" + exit ;; + *:DragonFly:*:*) + echo "$UNAME_MACHINE"-unknown-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "$UNAME_MACHINE" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`" + exit ;; + i*86:rdos:*:*) + echo "$UNAME_MACHINE"-pc-rdos + exit ;; + i*86:AROS:*:*) + echo "$UNAME_MACHINE"-pc-aros + exit ;; + x86_64:VMkernel:*:*) + echo "$UNAME_MACHINE"-unknown-esx + exit ;; + amd64:Isilon\ OneFS:*:*) + echo x86_64-unknown-onefs + exit ;; +esac + +echo "$0: unable to guess system type" >&2 + +case "$UNAME_MACHINE:$UNAME_SYSTEM" in + mips:Linux | mips64:Linux) + # If we got here on MIPS GNU/Linux, output extra information. + cat >&2 <&2 </dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = "$UNAME_MACHINE" +UNAME_RELEASE = "$UNAME_RELEASE" +UNAME_SYSTEM = "$UNAME_SYSTEM" +UNAME_VERSION = "$UNAME_VERSION" +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/config/config.rpath b/config/config.rpath new file mode 100755 index 0000000..fc5913d --- /dev/null +++ b/config/config.rpath @@ -0,0 +1,684 @@ +#! /bin/sh +# Output a system dependent set of variables, describing how to set the +# run time search path of shared libraries in an executable. +# +# Copyright 1996-2018 Free Software Foundation, Inc. +# Taken from GNU libtool, 2001 +# Originally by Gordon Matzigkeit , 1996 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. +# +# The first argument passed to this file is the canonical host specification, +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld +# should be set by the caller. +# +# The set of defined variables is at the end of this script. + +# Known limitations: +# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer +# than 256 bytes, otherwise the compiler driver will dump core. The only +# known workaround is to choose shorter directory names for the build +# directory and/or the installation directory. + +# All known linkers require a '.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a +shrext=.so + +host="$1" +host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + +# Code taken from libtool.m4's _LT_CC_BASENAME. + +for cc_temp in $CC""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'` + +# Code taken from libtool.m4's _LT_COMPILER_PIC. + +wl= +if test "$GCC" = yes; then + wl='-Wl,' +else + case "$host_os" in + aix*) + wl='-Wl,' + ;; + mingw* | cygwin* | pw32* | os2* | cegcc*) + ;; + hpux9* | hpux10* | hpux11*) + wl='-Wl,' + ;; + irix5* | irix6* | nonstopux*) + wl='-Wl,' + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu) + case $cc_basename in + ecc*) + wl='-Wl,' + ;; + icc* | ifort*) + wl='-Wl,' + ;; + lf95*) + wl='-Wl,' + ;; + nagfor*) + wl='-Wl,-Wl,,' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + wl='-Wl,' + ;; + ccc*) + wl='-Wl,' + ;; + xl* | bgxl* | bgf* | mpixl*) + wl='-Wl,' + ;; + como) + wl='-lopt=' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ F* | *Sun*Fortran*) + wl= + ;; + *Sun\ C*) + wl='-Wl,' + ;; + esac + ;; + esac + ;; + newsos6) + ;; + *nto* | *qnx*) + ;; + osf3* | osf4* | osf5*) + wl='-Wl,' + ;; + rdos*) + ;; + solaris*) + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + wl='-Qoption ld ' + ;; + *) + wl='-Wl,' + ;; + esac + ;; + sunos4*) + wl='-Qoption ld ' + ;; + sysv4 | sysv4.2uw2* | sysv4.3*) + wl='-Wl,' + ;; + sysv4*MP*) + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + wl='-Wl,' + ;; + unicos*) + wl='-Wl,' + ;; + uts4*) + ;; + esac +fi + +# Code taken from libtool.m4's _LT_LINKER_SHLIBS. + +hardcode_libdir_flag_spec= +hardcode_libdir_separator= +hardcode_direct=no +hardcode_minus_L=no + +case "$host_os" in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; +esac + +ld_shlibs=yes +if test "$with_gnu_ld" = yes; then + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + # Unlike libtool, we use -rpath here, not --rpath, since the documented + # option of GNU ld is called -rpath, not --rpath. + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + case "$host_os" in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + ld_shlibs=no + fi + ;; + amigaos*) + case "$host_cpu" in + powerpc) + ;; + m68k) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + cygwin* | mingw* | pw32* | cegcc*) + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + haiku*) + ;; + interix[3-9]*) + hardcode_direct=no + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + netbsd*) + ;; + solaris*) + if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' + else + ld_shlibs=no + fi + ;; + esac + ;; + sunos4*) + hardcode_direct=yes + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + : + else + ld_shlibs=no + fi + ;; + esac + if test "$ld_shlibs" = no; then + hardcode_libdir_flag_spec= + fi +else + case "$host_os" in + aix3*) + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$GCC" = yes; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + aix[4-9]*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + else + aix_use_runtimelinking=no + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + fi + hardcode_direct=yes + hardcode_libdir_separator=':' + if test "$GCC" = yes; then + case $host_os in aix4.[012]|aix4.[012].*) + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + fi + # Begin _LT_AC_SYS_LIBPATH_AIX. + echo 'int main () { return 0; }' > conftest.c + ${CC} ${LDFLAGS} conftest.c -o conftest + aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` + if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` + fi + if test -z "$aix_libpath"; then + aix_libpath="/usr/lib:/lib" + fi + rm -f conftest.c conftest + # End _LT_AC_SYS_LIBPATH_AIX. + if test "$aix_use_runtimelinking" = yes; then + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' + else + hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" + fi + fi + ;; + amigaos*) + case "$host_cpu" in + powerpc) + ;; + m68k) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + bsdi[45]*) + ;; + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec=' ' + libext=lib + ;; + darwin* | rhapsody*) + hardcode_direct=no + if { case $cc_basename in ifort*) true;; *) test "$GCC" = yes;; esac; }; then + : + else + ld_shlibs=no + fi + ;; + dgux*) + hardcode_libdir_flag_spec='-L$libdir' + ;; + freebsd2.[01]*) + hardcode_direct=yes + hardcode_minus_L=yes + ;; + freebsd* | dragonfly*) + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + ;; + hpux9*) + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + hpux10*) + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + hpux11*) + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + ;; + *) + hardcode_direct=yes + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + irix5* | irix6* | nonstopux*) + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + netbsd*) + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + ;; + newsos6) + hardcode_direct=yes + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + *nto* | *qnx*) + ;; + openbsd*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + else + case "$host_os" in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi + else + ld_shlibs=no + fi + ;; + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + osf3*) + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + osf4* | osf5*) + if test "$GCC" = yes; then + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + else + # Both cc and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + hardcode_libdir_separator=: + ;; + solaris*) + hardcode_libdir_flag_spec='-R$libdir' + ;; + sunos4*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + ;; + sysv4) + case $host_vendor in + sni) + hardcode_direct=yes # is this really true??? + ;; + siemens) + hardcode_direct=no + ;; + motorola) + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + ;; + sysv4.3*) + ;; + sysv4*MP*) + if test -d /usr/nec; then + ld_shlibs=yes + fi + ;; + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + ;; + sysv5* | sco3.2v5* | sco5v6*) + hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + hardcode_libdir_separator=':' + ;; + uts4*) + hardcode_libdir_flag_spec='-L$libdir' + ;; + *) + ld_shlibs=no + ;; + esac +fi + +# Check dynamic linker characteristics +# Code taken from libtool.m4's _LT_SYS_DYNAMIC_LINKER. +# Unlike libtool.m4, here we don't care about _all_ names of the library, but +# only about the one the linker finds when passed -lNAME. This is the last +# element of library_names_spec in libtool.m4, or possibly two of them if the +# linker has special search rules. +library_names_spec= # the last element of library_names_spec in libtool.m4 +libname_spec='lib$name' +case "$host_os" in + aix3*) + library_names_spec='$libname.a' + ;; + aix[4-9]*) + library_names_spec='$libname$shrext' + ;; + amigaos*) + case "$host_cpu" in + powerpc*) + library_names_spec='$libname$shrext' ;; + m68k) + library_names_spec='$libname.a' ;; + esac + ;; + beos*) + library_names_spec='$libname$shrext' + ;; + bsdi[45]*) + library_names_spec='$libname$shrext' + ;; + cygwin* | mingw* | pw32* | cegcc*) + shrext=.dll + library_names_spec='$libname.dll.a $libname.lib' + ;; + darwin* | rhapsody*) + shrext=.dylib + library_names_spec='$libname$shrext' + ;; + dgux*) + library_names_spec='$libname$shrext' + ;; + freebsd[23].*) + library_names_spec='$libname$shrext$versuffix' + ;; + freebsd* | dragonfly*) + library_names_spec='$libname$shrext' + ;; + gnu*) + library_names_spec='$libname$shrext' + ;; + haiku*) + library_names_spec='$libname$shrext' + ;; + hpux9* | hpux10* | hpux11*) + case $host_cpu in + ia64*) + shrext=.so + ;; + hppa*64*) + shrext=.sl + ;; + *) + shrext=.sl + ;; + esac + library_names_spec='$libname$shrext' + ;; + interix[3-9]*) + library_names_spec='$libname$shrext' + ;; + irix5* | irix6* | nonstopux*) + library_names_spec='$libname$shrext' + case "$host_os" in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;; + *) libsuff= shlibsuff= ;; + esac + ;; + esac + ;; + linux*oldld* | linux*aout* | linux*coff*) + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu) + library_names_spec='$libname$shrext' + ;; + knetbsd*-gnu) + library_names_spec='$libname$shrext' + ;; + netbsd*) + library_names_spec='$libname$shrext' + ;; + newsos6) + library_names_spec='$libname$shrext' + ;; + *nto* | *qnx*) + library_names_spec='$libname$shrext' + ;; + openbsd*) + library_names_spec='$libname$shrext$versuffix' + ;; + os2*) + libname_spec='$name' + shrext=.dll + library_names_spec='$libname.a' + ;; + osf3* | osf4* | osf5*) + library_names_spec='$libname$shrext' + ;; + rdos*) + ;; + solaris*) + library_names_spec='$libname$shrext' + ;; + sunos4*) + library_names_spec='$libname$shrext$versuffix' + ;; + sysv4 | sysv4.3*) + library_names_spec='$libname$shrext' + ;; + sysv4*MP*) + library_names_spec='$libname$shrext' + ;; + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + library_names_spec='$libname$shrext' + ;; + tpf*) + library_names_spec='$libname$shrext' + ;; + uts4*) + library_names_spec='$libname$shrext' + ;; +esac + +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' +escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"` +shlibext=`echo "$shrext" | sed -e 's,^\.,,'` +escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` +escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` +escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"` + +LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <. +# +# 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 Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). + + +# Please send patches to . +# +# 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. + +# You can get the latest version of this script from: +# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub + +# 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. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS + +Canonicalize a configuration name. + +Options: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright 1992-2018 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." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo "$1" + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +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 + nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ + linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \ + kopensolaris*-gnu* | cloudabi*-eabi* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + android-linux) + os=-linux-android + basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown + ;; + *) + 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 | -axis | -knuth | -cray | -microblaze*) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + ;; + -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/'` + ;; + -sco5v6*) + # 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/'` + ;; + -udk*) + 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*178) + os=-lynxos178 + ;; + -lynx*5) + os=-lynxos5 + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo "$1" | sed -e 's/86-.*/86-sequent/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +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. + 1750a | 580 \ + | a29k \ + | aarch64 | aarch64_be \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arceb \ + | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ + | avr | avr32 \ + | ba \ + | be32 | be64 \ + | bfin \ + | c4x | c8051 | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | e2k | epiphany \ + | fido | fr30 | frv | ft32 \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i860 | i960 | ia16 | ia64 \ + | ip2k | iq2000 \ + | k1om \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa32r6 | mipsisa32r6el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64r6 | mipsisa64r6el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipsr5900 | mipsr5900el \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nios | nios2 | nios2eb | nios2el \ + | ns16k | ns32k \ + | open8 | or1k | or1knd | or32 \ + | pdp10 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pru \ + | pyramid \ + | riscv32 | riscv64 \ + | rl78 | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu \ + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ + | visium \ + | wasm32 \ + | x86 | xc16x | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + c54x) + basic_machine=tic54x-unknown + ;; + c55x) + basic_machine=tic55x-unknown + ;; + c6x) + basic_machine=tic6x-unknown + ;; + leon|leon[3-9]) + basic_machine=sparc-$basic_machine + ;; + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65) + ;; + ms1) + basic_machine=mt-unknown + ;; + + strongarm | thumb | xscale) + basic_machine=arm-unknown + ;; + xgate) + basic_machine=$basic_machine-unknown + os=-none + ;; + xscaleeb) + basic_machine=armeb-unknown + ;; + + xscaleel) + basic_machine=armel-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*86 | x86_64) + 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. + 580-* \ + | a29k-* \ + | aarch64-* | aarch64_be-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | ba-* \ + | be32-* | be64-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ + | c8051-* | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | e2k-* | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | hexagon-* \ + | i*86-* | i860-* | i960-* | ia16-* | ia64-* \ + | ip2k-* | iq2000-* \ + | k1om-* \ + | le32-* | le64-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ + | microblaze-* | microblazeel-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa32r6-* | mipsisa32r6el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64r6-* | mipsisa64r6el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipsr5900-* | mipsr5900el-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nds32-* | nds32le-* | nds32be-* \ + | nios-* | nios2-* | nios2eb-* | nios2el-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ + | or1k*-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ + | pru-* \ + | pyramid-* \ + | riscv32-* | riscv64-* \ + | rl78-* | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \ + | tahoe-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile*-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ + | visium-* \ + | wasm32-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-pc + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + asmjs) + basic_machine=asmjs-unknown + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo "$basic_machine" | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c54x-*) + basic_machine=tic54x-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + c55x-*) + basic_machine=tic55x-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + c6x-*) + basic_machine=tic6x-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + 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 | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16 | cr16-*) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2*) + basic_machine=m68k-bull + os=-sysv3 + ;; + e500v[12]) + basic_machine=powerpc-unknown + os=$os"spe" + ;; + e500v[12]-*) + basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'` + os=$os"spe" + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-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 + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; + i*86v32) + basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + leon-*|leon[3-9]-*) + basic_machine=sparc-`echo "$basic_machine" | sed 's/-.*//'` + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo "$basic_machine" | sed 's/^[^-]*-//'` + os=-linux + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + microblaze*) + basic_machine=microblaze-xilinx + ;; + mingw64) + basic_machine=x86_64-pc + os=-mingw64 + ;; + mingw32) + basic_machine=i686-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + moxiebox) + basic_machine=moxie-unknown + os=-moxiebox + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo "$basic_machine" | sed -e 's/ms1-/mt-/'` + ;; + msys) + basic_machine=i686-pc + os=-msys + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + nacl) + basic_machine=le32-unknown + os=-nacl + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + 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 + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + 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 + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + neo-tandem) + basic_machine=neo-tandem + ;; + nse-tandem) + basic_machine=nse-tandem + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + nsv-tandem) + basic_machine=nsv-tandem + ;; + nsx-tandem) + basic_machine=nsx-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo "$basic_machine" | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc | ppcbe) basic_machine=powerpc-unknown + ;; + ppc-* | ppcbe-*) + basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos | rdos64) + basic_machine=x86_64-pc + os=-rdos + ;; + rdos32) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + strongarm-* | thumb-*) + basic_machine=arm-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + 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 + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tile*) + basic_machine=$basic_machine-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + 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 + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + x64) + basic_machine=x86_64-pc + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + xscale-* | xscalee[bl]-*) + basic_machine=`echo "$basic_machine" | sed 's/^xscale/arm/'` + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + 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. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + 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. + -auroraux) + os=-auroraux + ;; + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # es1800 is here to avoid being matched by es* (a different OS) + -es1800*) + os=-ose + ;; + # Now 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* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* | -plan9* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* | -cloudabi* | -sortix* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -knetbsd* | -mirbsd* | -netbsd* \ + | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* | -hcos* \ + | -chorusos* | -chorusrdb* | -cegcc* | -glidix* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-musl* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \ + | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox* | -bme* \ + | -midnightbsd*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -xray | -os68k* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo "$os" | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -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|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4*) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -pikeos*) + # Until real need of OS specific support for + # particular features comes up, bare metal + # configurations are quite functional. + case $basic_machine in + arm*) + os=-eabi + ;; + *) + os=-elf + ;; + esac + ;; + -nacl*) + ;; + -ios) + ;; + -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 + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + c8051-*) + os=-elf + ;; + hexagon-*) + os=-elf + ;; + tic54x-*) + os=-coff + ;; + tic55x-*) + os=-coff + ;; + tic6x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + pru-*) + os=-elf + ;; + *-be) + os=-beos + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-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 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + 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 + ;; + -cnk*|-aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo "$basic_machine" | sed "s/unknown/$vendor/"` + ;; +esac + +echo "$basic_machine$os" +exit + +# Local variables: +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/config/depcomp b/config/depcomp new file mode 100755 index 0000000..65cbf70 --- /dev/null +++ b/config/depcomp @@ -0,0 +1,791 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2018-03-07.03; # UTC + +# Copyright (C) 1999-2018 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, see . + +# 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. + +# Originally written by Alexandre Oliva . + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by 'PROGRAMS ARGS'. + object Object file output by 'PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputting dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +# Get the directory component of the given path, and save it in the +# global variables '$dir'. Note that this directory component will +# be either empty or ending with a '/' character. This is deliberate. +set_dir_from () +{ + case $1 in + */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; + *) dir=;; + esac +} + +# Get the suffix-stripped basename of the given path, and save it the +# global variable '$base'. +set_base_from () +{ + base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` +} + +# If no dependency file was actually created by the compiler invocation, +# we still have to create a dummy depfile, to avoid errors with the +# Makefile "include basename.Plo" scheme. +make_dummy_depfile () +{ + echo "#dummy" > "$depfile" +} + +# Factor out some common post-processing of the generated depfile. +# Requires the auxiliary global variable '$tmpdepfile' to be set. +aix_post_process_depfile () +{ + # If the compiler actually managed to produce a dependency file, + # post-process it. + if test -f "$tmpdepfile"; then + # Each line is of the form 'foo.o: dependency.h'. + # Do two passes, one to just change these to + # $object: dependency.h + # and one to simply output + # dependency.h: + # which is needed to avoid the deleted-header problem. + { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" + sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" + } > "$depfile" + rm -f "$tmpdepfile" + else + make_dummy_depfile + fi +} + +# A tabulation character. +tab=' ' +# A newline character. +nl=' +' +# Character ranges might be problematic outside the C locale. +# These definitions help. +upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ +lower=abcdefghijklmnopqrstuvwxyz +digits=0123456789 +alpha=${upper}${lower} + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Avoid interferences from the environment. +gccflag= dashmflag= + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +cygpath_u="cygpath -u -f -" +if test "$depmode" = msvcmsys; then + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvisualcpp +fi + +if test "$depmode" = msvc7msys; then + # This is just like msvc7 but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvc7 +fi + +if test "$depmode" = xlc; then + # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. + gccflag=-qmakedep=gcc,-MF + depmode=gcc +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. +## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. +## (see the conditional assignment to $gccflag above). +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). Also, it might not be +## supported by the other compilers which use the 'gcc' depmode. +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The second -e expression handles DOS-style file names with drive + # letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the "deleted header file" problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. +## Some versions of gcc put a space before the ':'. On the theory +## that the space means something, we add a space to the output as +## well. hp depmode also adds that space, but also prefixes the VPATH +## to the object. Take care to not repeat it in the output. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like '#:fec' to the end of the + # dependency line. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ + | tr "$nl" ' ' >> "$depfile" + echo >> "$depfile" + # The second pass generates a dummy entry for each header file. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" + else + make_dummy_depfile + fi + rm -f "$tmpdepfile" + ;; + +xlc) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts '$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + set_dir_from "$object" + set_base_from "$object" + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.u + tmpdepfile2=$base.u + tmpdepfile3=$dir.libs/$base.u + "$@" -Wc,-M + else + tmpdepfile1=$dir$base.u + tmpdepfile2=$dir$base.u + tmpdepfile3=$dir$base.u + "$@" -M + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + aix_post_process_depfile + ;; + +tcc) + # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 + # FIXME: That version still under development at the moment of writing. + # Make that this statement remains true also for stable, released + # versions. + # It will wrap lines (doesn't matter whether long or short) with a + # trailing '\', as in: + # + # foo.o : \ + # foo.c \ + # foo.h \ + # + # It will put a trailing '\' even on the last line, and will use leading + # spaces rather than leading tabs (at least since its commit 0394caf7 + # "Emit spaces for -MD"). + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. + # We have to change lines of the first kind to '$object: \'. + sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" + # And for each line of the second kind, we have to emit a 'dep.h:' + # dummy dependency, to avoid the deleted-header problem. + sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" + rm -f "$tmpdepfile" + ;; + +## The order of this option in the case statement is important, since the +## shell code in configure will try each of these formats in the order +## listed in this file. A plain '-MD' option would be understood by many +## compilers, so we must ensure this comes after the gcc and icc options. +pgcc) + # Portland's C compiler understands '-MD'. + # Will always output deps to 'file.d' where file is the root name of the + # source file under compilation, even if file resides in a subdirectory. + # The object file name does not affect the name of the '.d' file. + # pgcc 10.2 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using '\' : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + set_dir_from "$object" + # Use the source, not the object, to determine the base name, since + # that's sadly what pgcc will do too. + set_base_from "$source" + tmpdepfile=$base.d + + # For projects that build the same source file twice into different object + # files, the pgcc approach of using the *source* file root name can cause + # problems in parallel builds. Use a locking strategy to avoid stomping on + # the same $tmpdepfile. + lockdir=$base.d-lock + trap " + echo '$0: caught signal, cleaning up...' >&2 + rmdir '$lockdir' + exit 1 + " 1 2 13 15 + numtries=100 + i=$numtries + while test $i -gt 0; do + # mkdir is a portable test-and-set. + if mkdir "$lockdir" 2>/dev/null; then + # This process acquired the lock. + "$@" -MD + stat=$? + # Release the lock. + rmdir "$lockdir" + break + else + # If the lock is being held by a different process, wait + # until the winning process is done or we timeout. + while test -d "$lockdir" && test $i -gt 0; do + sleep 1 + i=`expr $i - 1` + done + fi + i=`expr $i - 1` + done + trap - 1 2 13 15 + if test $i -le 0; then + echo "$0: failed to acquire lock after $numtries attempts" >&2 + echo "$0: check lockdir '$lockdir'" >&2 + exit 1 + fi + + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + set_dir_from "$object" + set_base_from "$object" + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" + # Add 'dependent.h:' lines. + sed -ne '2,${ + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" + else + make_dummy_depfile + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in 'foo.d' instead, so we check for that too. + # Subdirectories are respected. + set_dir_from "$object" + set_base_from "$object" + + if test "$libtool" = yes; then + # Libtool generates 2 separate objects for the 2 libraries. These + # two compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir$base.o.d # libtool 1.5 + tmpdepfile2=$dir.libs/$base.o.d # Likewise. + tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + # Same post-processing that is required for AIX mode. + aix_post_process_depfile + ;; + +msvc7) + if test "$libtool" = yes; then + showIncludes=-Wc,-showIncludes + else + showIncludes=-showIncludes + fi + "$@" $showIncludes > "$tmpdepfile" + stat=$? + grep -v '^Note: including file: ' "$tmpdepfile" + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The first sed program below extracts the file names and escapes + # backslashes for cygpath. The second sed program outputs the file + # name when reading, but also accumulates all include files in the + # hold buffer in order to output them again at the end. This only + # works with sed implementations that can handle large buffers. + sed < "$tmpdepfile" -n ' +/^Note: including file: *\(.*\)/ { + s//\1/ + s/\\/\\\\/g + p +}' | $cygpath_u | sort -u | sed -n ' +s/ /\\ /g +s/\(.*\)/'"$tab"'\1 \\/p +s/.\(.*\) \\/\1:/ +H +$ { + s/.*/'"$tab"'/ + G + p +}' >> "$depfile" + echo >> "$depfile" # make sure the fragment doesn't end with a backslash + rm -f "$tmpdepfile" + ;; + +msvc7msys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for ':' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. + "$@" $dashmflag | + sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this sed invocation + # correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no eat=no + for arg + do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + if test $eat = yes; then + eat=no + continue + fi + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -arch) + eat=yes ;; + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix=`echo "$object" | sed 's/^.*\././'` + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + # makedepend may prepend the VPATH from the source file name to the object. + # No need to regex-escape $object, excess matching of '.' is harmless. + sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process the last invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed '1,2d' "$tmpdepfile" \ + | tr ' ' "$nl" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E \ + | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + | sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + IFS=" " + for arg + do + case "$arg" in + -o) + shift + ;; + $object) + shift + ;; + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E 2>/dev/null | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" + echo "$tab" >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvcmsys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/config/extensions.m4 b/config/extensions.m4 new file mode 100644 index 0000000..71a854f --- /dev/null +++ b/config/extensions.m4 @@ -0,0 +1,189 @@ +# serial 18 -*- Autoconf -*- +# Enable extensions on systems that normally disable them. + +# Copyright (C) 2003, 2006-2018 Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This definition of AC_USE_SYSTEM_EXTENSIONS is stolen from git +# Autoconf. Perhaps we can remove this once we can assume Autoconf +# 2.70 or later everywhere, but since Autoconf mutates rapidly +# enough in this area it's likely we'll need to redefine +# AC_USE_SYSTEM_EXTENSIONS for quite some time. + +# If autoconf reports a warning +# warning: AC_COMPILE_IFELSE was called before AC_USE_SYSTEM_EXTENSIONS +# or warning: AC_RUN_IFELSE was called before AC_USE_SYSTEM_EXTENSIONS +# the fix is +# 1) to ensure that AC_USE_SYSTEM_EXTENSIONS is never directly invoked +# but always AC_REQUIREd, +# 2) to ensure that for each occurrence of +# AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) +# or +# AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) +# the corresponding gnulib module description has 'extensions' among +# its dependencies. This will ensure that the gl_USE_SYSTEM_EXTENSIONS +# invocation occurs in gl_EARLY, not in gl_INIT. + +# AC_USE_SYSTEM_EXTENSIONS +# ------------------------ +# Enable extensions on systems that normally disable them, +# typically due to standards-conformance issues. +# +# Remember that #undef in AH_VERBATIM gets replaced with #define by +# AC_DEFINE. The goal here is to define all known feature-enabling +# macros, then, if reports of conflicts are made, disable macros that +# cause problems on some platforms (such as __EXTENSIONS__). +AC_DEFUN_ONCE([AC_USE_SYSTEM_EXTENSIONS], +[AC_BEFORE([$0], [AC_COMPILE_IFELSE])dnl +AC_BEFORE([$0], [AC_RUN_IFELSE])dnl + + AC_CHECK_HEADER([minix/config.h], [MINIX=yes], [MINIX=]) + if test "$MINIX" = yes; then + AC_DEFINE([_POSIX_SOURCE], [1], + [Define to 1 if you need to in order for 'stat' and other + things to work.]) + AC_DEFINE([_POSIX_1_SOURCE], [2], + [Define to 2 if the system does not provide POSIX.1 features + except with this defined.]) + AC_DEFINE([_MINIX], [1], + [Define to 1 if on MINIX.]) + AC_DEFINE([_NETBSD_SOURCE], [1], + [Define to 1 to make NetBSD features available. MINIX 3 needs this.]) + fi + +dnl Use a different key than __EXTENSIONS__, as that name broke existing +dnl configure.ac when using autoheader 2.62. + AH_VERBATIM([USE_SYSTEM_EXTENSIONS], +[/* Enable extensions on AIX 3, Interix. */ +#ifndef _ALL_SOURCE +# undef _ALL_SOURCE +#endif +/* Enable general extensions on macOS. */ +#ifndef _DARWIN_C_SOURCE +# undef _DARWIN_C_SOURCE +#endif +/* Enable GNU extensions on systems that have them. */ +#ifndef _GNU_SOURCE +# undef _GNU_SOURCE +#endif +/* Enable NetBSD extensions on NetBSD. */ +#ifndef _NETBSD_SOURCE +# undef _NETBSD_SOURCE +#endif +/* Enable OpenBSD extensions on NetBSD. */ +#ifndef _OPENBSD_SOURCE +# undef _OPENBSD_SOURCE +#endif +/* Enable threading extensions on Solaris. */ +#ifndef _POSIX_PTHREAD_SEMANTICS +# undef _POSIX_PTHREAD_SEMANTICS +#endif +/* Enable extensions specified by ISO/IEC TS 18661-5:2014. */ +#ifndef __STDC_WANT_IEC_60559_ATTRIBS_EXT__ +# undef __STDC_WANT_IEC_60559_ATTRIBS_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TS 18661-1:2014. */ +#ifndef __STDC_WANT_IEC_60559_BFP_EXT__ +# undef __STDC_WANT_IEC_60559_BFP_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TS 18661-2:2015. */ +#ifndef __STDC_WANT_IEC_60559_DFP_EXT__ +# undef __STDC_WANT_IEC_60559_DFP_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TS 18661-4:2015. */ +#ifndef __STDC_WANT_IEC_60559_FUNCS_EXT__ +# undef __STDC_WANT_IEC_60559_FUNCS_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TS 18661-3:2015. */ +#ifndef __STDC_WANT_IEC_60559_TYPES_EXT__ +# undef __STDC_WANT_IEC_60559_TYPES_EXT__ +#endif +/* Enable extensions specified by ISO/IEC TR 24731-2:2010. */ +#ifndef __STDC_WANT_LIB_EXT2__ +# undef __STDC_WANT_LIB_EXT2__ +#endif +/* Enable extensions specified by ISO/IEC 24747:2009. */ +#ifndef __STDC_WANT_MATH_SPEC_FUNCS__ +# undef __STDC_WANT_MATH_SPEC_FUNCS__ +#endif +/* Enable extensions on HP NonStop. */ +#ifndef _TANDEM_SOURCE +# undef _TANDEM_SOURCE +#endif +/* Enable X/Open extensions if necessary. HP-UX 11.11 defines + mbstate_t only if _XOPEN_SOURCE is defined to 500, regardless of + whether compiling with -Ae or -D_HPUX_SOURCE=1. */ +#ifndef _XOPEN_SOURCE +# undef _XOPEN_SOURCE +#endif +/* Enable X/Open compliant socket functions that do not require linking + with -lxnet on HP-UX 11.11. */ +#ifndef _HPUX_ALT_XOPEN_SOCKET_API +# undef _HPUX_ALT_XOPEN_SOCKET_API +#endif +/* Enable general extensions on Solaris. */ +#ifndef __EXTENSIONS__ +# undef __EXTENSIONS__ +#endif +]) + AC_CACHE_CHECK([whether it is safe to define __EXTENSIONS__], + [ac_cv_safe_to_define___extensions__], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[ +# define __EXTENSIONS__ 1 + ]AC_INCLUDES_DEFAULT])], + [ac_cv_safe_to_define___extensions__=yes], + [ac_cv_safe_to_define___extensions__=no])]) + test $ac_cv_safe_to_define___extensions__ = yes && + AC_DEFINE([__EXTENSIONS__]) + AC_DEFINE([_ALL_SOURCE]) + AC_DEFINE([_DARWIN_C_SOURCE]) + AC_DEFINE([_GNU_SOURCE]) + AC_DEFINE([_NETBSD_SOURCE]) + AC_DEFINE([_OPENBSD_SOURCE]) + AC_DEFINE([_POSIX_PTHREAD_SEMANTICS]) + AC_DEFINE([__STDC_WANT_IEC_60559_ATTRIBS_EXT__]) + AC_DEFINE([__STDC_WANT_IEC_60559_BFP_EXT__]) + AC_DEFINE([__STDC_WANT_IEC_60559_DFP_EXT__]) + AC_DEFINE([__STDC_WANT_IEC_60559_FUNCS_EXT__]) + AC_DEFINE([__STDC_WANT_IEC_60559_TYPES_EXT__]) + AC_DEFINE([__STDC_WANT_LIB_EXT2__]) + AC_DEFINE([__STDC_WANT_MATH_SPEC_FUNCS__]) + AC_DEFINE([_TANDEM_SOURCE]) + AC_CACHE_CHECK([whether _XOPEN_SOURCE should be defined], + [ac_cv_should_define__xopen_source], + [ac_cv_should_define__xopen_source=no + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[ + #include + mbstate_t x;]])], + [], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[ + #define _XOPEN_SOURCE 500 + #include + mbstate_t x;]])], + [ac_cv_should_define__xopen_source=yes])])]) + test $ac_cv_should_define__xopen_source = yes && + AC_DEFINE([_XOPEN_SOURCE], [500]) + AC_DEFINE([_HPUX_ALT_XOPEN_SOCKET_API]) +])# AC_USE_SYSTEM_EXTENSIONS + +# gl_USE_SYSTEM_EXTENSIONS +# ------------------------ +# Enable extensions on systems that normally disable them, +# typically due to standards-conformance issues. +AC_DEFUN_ONCE([gl_USE_SYSTEM_EXTENSIONS], +[ + dnl Require this macro before AC_USE_SYSTEM_EXTENSIONS. + dnl gnulib does not need it. But if it gets required by third-party macros + dnl after AC_USE_SYSTEM_EXTENSIONS is required, autoconf 2.62..2.63 emit a + dnl warning: "AC_COMPILE_IFELSE was called before AC_USE_SYSTEM_EXTENSIONS". + dnl Note: We can do this only for one of the macros AC_AIX, AC_GNU_SOURCE, + dnl AC_MINIX. If people still use AC_AIX or AC_MINIX, they are out of luck. + AC_REQUIRE([AC_GNU_SOURCE]) + + AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) +]) diff --git a/config/gendocs.sh b/config/gendocs.sh new file mode 100755 index 0000000..91c058d --- /dev/null +++ b/config/gendocs.sh @@ -0,0 +1,510 @@ +#!/bin/sh -e +# gendocs.sh -- generate a GNU manual in many formats. This script is +# mentioned in maintain.texi. See the help message below for usage details. + +scriptversion=2018-03-06.19 + +# Copyright 2003-2018 Free Software Foundation, Inc. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# Original author: Mohit Agarwal. +# Send bug reports and any other correspondence to bug-gnulib@gnu.org. +# +# The latest version of this script, and the companion template, is +# available from the Gnulib repository: +# +# https://git.savannah.gnu.org/cgit/gnulib.git/tree/build-aux/gendocs.sh +# https://git.savannah.gnu.org/cgit/gnulib.git/tree/doc/gendocs_template + +# TODO: +# - image importing was only implemented for HTML generated by +# makeinfo. But it should be simple enough to adjust. +# - images are not imported in the source tarball. All the needed +# formats (PDF, PNG, etc.) should be included. + +prog=`basename "$0"` +srcdir=`pwd` + +scripturl="https://git.savannah.gnu.org/cgit/gnulib.git/plain/build-aux/gendocs.sh" +templateurl="https://git.savannah.gnu.org/cgit/gnulib.git/plain/doc/gendocs_template" + +: ${SETLANG="env LANG= LC_MESSAGES= LC_ALL= LANGUAGE="} +: ${MAKEINFO="makeinfo"} +: ${TEXI2DVI="texi2dvi"} +: ${DOCBOOK2HTML="docbook2html"} +: ${DOCBOOK2PDF="docbook2pdf"} +: ${DOCBOOK2TXT="docbook2txt"} +: ${GENDOCS_TEMPLATE_DIR="."} +: ${PERL='perl'} +: ${TEXI2HTML="texi2html"} +unset CDPATH +unset use_texi2html + +MANUAL_TITLE= +PACKAGE= +EMAIL=webmasters@gnu.org # please override with --email +commonarg= # passed to all makeinfo/texi2html invcations. +dirargs= # passed to all tools (-I dir). +dirs= # -I directories. +htmlarg="--css-ref=/software/gnulib/manual.css -c TOP_NODE_UP_URL=/manual" +default_htmlarg=true +infoarg=--no-split +generate_ascii=true +generate_html=true +generate_info=true +generate_tex=true +outdir=manual +source_extra= +split=node +srcfile= +texarg="-t @finalout" + +version="gendocs.sh $scriptversion + +Copyright 2018 Free Software Foundation, Inc. +There is NO warranty. You may redistribute this software +under the terms of the GNU General Public License. +For more information about these matters, see the files named COPYING." + +usage="Usage: $prog [OPTION]... PACKAGE MANUAL-TITLE + +Generate output in various formats from PACKAGE.texinfo (or .texi or +.txi) source. See the GNU Maintainers document for a more extensive +discussion: + https://www.gnu.org/prep/maintain_toc.html + +Options: + --email ADR use ADR as contact in generated web pages; always give this. + + -s SRCFILE read Texinfo from SRCFILE, instead of PACKAGE.{texinfo|texi|txi} + -o OUTDIR write files into OUTDIR, instead of manual/. + -I DIR append DIR to the Texinfo search path. + --common ARG pass ARG in all invocations. + --html ARG pass ARG to makeinfo or texi2html for HTML targets, + instead of '$htmlarg'. + --info ARG pass ARG to makeinfo for Info, instead of --no-split. + --no-ascii skip generating the plain text output. + --no-html skip generating the html output. + --no-info skip generating the info output. + --no-tex skip generating the dvi and pdf output. + --source ARG include ARG in tar archive of sources. + --split HOW make split HTML by node, section, chapter; default node. + --tex ARG pass ARG to texi2dvi for DVI and PDF, instead of -t @finalout. + + --texi2html use texi2html to make HTML target, with all split versions. + --docbook convert through DocBook too (xml, txt, html, pdf). + + --help display this help and exit successfully. + --version display version information and exit successfully. + +Simple example: $prog --email bug-gnu-emacs@gnu.org emacs \"GNU Emacs Manual\" + +Typical sequence: + cd PACKAGESOURCE/doc + wget \"$scripturl\" + wget \"$templateurl\" + $prog --email BUGLIST MANUAL \"GNU MANUAL - One-line description\" + +Output will be in a new subdirectory \"manual\" (by default; +use -o OUTDIR to override). Move all the new files into your web CVS +tree, as explained in the Web Pages node of maintain.texi. + +Please use the --email ADDRESS option so your own bug-reporting +address will be used in the generated HTML pages. + +MANUAL-TITLE is included as part of the HTML of the overall +manual/index.html file. It should include the name of the package being +documented. manual/index.html is created by substitution from the file +$GENDOCS_TEMPLATE_DIR/gendocs_template. (Feel free to modify the +generic template for your own purposes.) + +If you have several manuals, you'll need to run this script several +times with different MANUAL values, specifying a different output +directory with -o each time. Then write (by hand) an overall index.html +with links to them all. + +If a manual's Texinfo sources are spread across several directories, +first copy or symlink all Texinfo sources into a single directory. +(Part of the script's work is to make a tar.gz of the sources.) + +As implied above, by default monolithic Info files are generated. +If you want split Info, or other Info options, use --info to override. + +You can set the environment variables MAKEINFO, TEXI2DVI, TEXI2HTML, +and PERL to control the programs that get executed, and +GENDOCS_TEMPLATE_DIR to control where the gendocs_template file is +looked for. With --docbook, the environment variables DOCBOOK2HTML, +DOCBOOK2PDF, and DOCBOOK2TXT are also consulted. + +By default, makeinfo and texi2dvi are run in the default (English) +locale, since that's the language of most Texinfo manuals. If you +happen to have a non-English manual and non-English web site, see the +SETLANG setting in the source. + +Email bug reports or enhancement requests to bug-gnulib@gnu.org. +" + +while test $# -gt 0; do + case $1 in + -s) shift; srcfile=$1;; + -o) shift; outdir=$1;; + -I) shift; dirargs="$dirargs -I '$1'"; dirs="$dirs $1";; + --common) shift; commonarg=$1;; + --docbook) docbook=yes;; + --email) shift; EMAIL=$1;; + --html) shift; default_htmlarg=false; htmlarg=$1;; + --info) shift; infoarg=$1;; + --no-ascii) generate_ascii=false;; + --no-html) generate_ascii=false;; + --no-info) generate_info=false;; + --no-tex) generate_tex=false;; + --source) shift; source_extra=$1;; + --split) shift; split=$1;; + --tex) shift; texarg=$1;; + --texi2html) use_texi2html=1;; + + --help) echo "$usage"; exit 0;; + --version) echo "$version"; exit 0;; + -*) + echo "$0: Unknown option \`$1'." >&2 + echo "$0: Try \`--help' for more information." >&2 + exit 1;; + *) + if test -z "$PACKAGE"; then + PACKAGE=$1 + elif test -z "$MANUAL_TITLE"; then + MANUAL_TITLE=$1 + else + echo "$0: extra non-option argument \`$1'." >&2 + exit 1 + fi;; + esac + shift +done + +# makeinfo uses the dirargs, but texi2dvi doesn't. +commonarg=" $dirargs $commonarg" + +# For most of the following, the base name is just $PACKAGE +base=$PACKAGE + +if $default_htmlarg && test -n "$use_texi2html"; then + # The legacy texi2html doesn't support TOP_NODE_UP_URL + htmlarg="--css-ref=/software/gnulib/manual.css" +fi + +if test -n "$srcfile"; then + # but here, we use the basename of $srcfile + base=`basename "$srcfile"` + case $base in + *.txi|*.texi|*.texinfo) base=`echo "$base"|sed 's/\.[texinfo]*$//'`;; + esac + PACKAGE=$base +elif test -s "$srcdir/$PACKAGE.texinfo"; then + srcfile=$srcdir/$PACKAGE.texinfo +elif test -s "$srcdir/$PACKAGE.texi"; then + srcfile=$srcdir/$PACKAGE.texi +elif test -s "$srcdir/$PACKAGE.txi"; then + srcfile=$srcdir/$PACKAGE.txi +else + echo "$0: cannot find .texinfo or .texi or .txi for $PACKAGE in $srcdir." >&2 + exit 1 +fi + +if test ! -r $GENDOCS_TEMPLATE_DIR/gendocs_template; then + echo "$0: cannot read $GENDOCS_TEMPLATE_DIR/gendocs_template." >&2 + echo "$0: it is available from $templateurl." >&2 + exit 1 +fi + +# Function to return size of $1 in something resembling kilobytes. +calcsize() +{ + size=`ls -ksl $1 | awk '{print $1}'` + echo $size +} + +# copy_images OUTDIR HTML-FILE... +# ------------------------------- +# Copy all the images needed by the HTML-FILEs into OUTDIR. +# Look for them in . and the -I directories; this is simpler than what +# makeinfo supports with -I, but hopefully it will suffice. +copy_images() +{ + local odir + odir=$1 + shift + $PERL -n -e " +BEGIN { + \$me = '$prog'; + \$odir = '$odir'; + @dirs = qw(. $dirs); +} +" -e ' +/<img src="(.*?)"/g && ++$need{$1}; + +END { + #print "$me: @{[keys %need]}\n"; # for debugging, show images found. + FILE: for my $f (keys %need) { + for my $d (@dirs) { + if (-f "$d/$f") { + use File::Basename; + my $dest = dirname ("$odir/$f"); + # + use File::Path; + -d $dest || mkpath ($dest) + || die "$me: cannot mkdir $dest: $!\n"; + # + use File::Copy; + copy ("$d/$f", $dest) + || die "$me: cannot copy $d/$f to $dest: $!\n"; + next FILE; + } + } + die "$me: $ARGV: cannot find image $f\n"; + } +} +' -- "$@" || exit 1 +} + +case $outdir in + /*) abs_outdir=$outdir;; + *) abs_outdir=$srcdir/$outdir;; +esac + +echo "Making output for $srcfile" +echo " in `pwd`" +mkdir -p "$outdir/" + +# +if $generate_info; then + cmd="$SETLANG $MAKEINFO -o $PACKAGE.info $commonarg $infoarg \"$srcfile\"" + echo "Generating info... ($cmd)" + rm -f $PACKAGE.info* # get rid of any strays + eval "$cmd" + tar czf "$outdir/$PACKAGE.info.tar.gz" $PACKAGE.info* + ls -l "$outdir/$PACKAGE.info.tar.gz" + info_tgz_size=`calcsize "$outdir/$PACKAGE.info.tar.gz"` + # do not mv the info files, there's no point in having them available + # separately on the web. +fi # end info + +# +if $generate_tex; then + cmd="$SETLANG $TEXI2DVI $dirargs $texarg \"$srcfile\"" + printf "\nGenerating dvi... ($cmd)\n" + eval "$cmd" + # compress/finish dvi: + gzip -f -9 $PACKAGE.dvi + dvi_gz_size=`calcsize $PACKAGE.dvi.gz` + mv $PACKAGE.dvi.gz "$outdir/" + ls -l "$outdir/$PACKAGE.dvi.gz" + + cmd="$SETLANG $TEXI2DVI --pdf $dirargs $texarg \"$srcfile\"" + printf "\nGenerating pdf... ($cmd)\n" + eval "$cmd" + pdf_size=`calcsize $PACKAGE.pdf` + mv $PACKAGE.pdf "$outdir/" + ls -l "$outdir/$PACKAGE.pdf" +fi # end tex (dvi + pdf) + +# +if $generate_ascii; then + opt="-o $PACKAGE.txt --no-split --no-headers $commonarg" + cmd="$SETLANG $MAKEINFO $opt \"$srcfile\"" + printf "\nGenerating ascii... ($cmd)\n" + eval "$cmd" + ascii_size=`calcsize $PACKAGE.txt` + gzip -f -9 -c $PACKAGE.txt >"$outdir/$PACKAGE.txt.gz" + ascii_gz_size=`calcsize "$outdir/$PACKAGE.txt.gz"` + mv $PACKAGE.txt "$outdir/" + ls -l "$outdir/$PACKAGE.txt" "$outdir/$PACKAGE.txt.gz" +fi + +# + +if $generate_html; then +# Split HTML at level $1. Used for texi2html. +html_split() +{ + opt="--split=$1 --node-files $commonarg $htmlarg" + cmd="$SETLANG $TEXI2HTML --output $PACKAGE.html $opt \"$srcfile\"" + printf "\nGenerating html by $1... ($cmd)\n" + eval "$cmd" + split_html_dir=$PACKAGE.html + ( + cd ${split_html_dir} || exit 1 + ln -sf ${PACKAGE}.html index.html + tar -czf "$abs_outdir/${PACKAGE}.html_$1.tar.gz" -- *.html + ) + eval html_$1_tgz_size=`calcsize "$outdir/${PACKAGE}.html_$1.tar.gz"` + rm -f "$outdir"/html_$1/*.html + mkdir -p "$outdir/html_$1/" + mv ${split_html_dir}/*.html "$outdir/html_$1/" + rmdir ${split_html_dir} +} + +if test -z "$use_texi2html"; then + opt="--no-split --html -o $PACKAGE.html $commonarg $htmlarg" + cmd="$SETLANG $MAKEINFO $opt \"$srcfile\"" + printf "\nGenerating monolithic html... ($cmd)\n" + rm -rf $PACKAGE.html # in case a directory is left over + eval "$cmd" + html_mono_size=`calcsize $PACKAGE.html` + gzip -f -9 -c $PACKAGE.html >"$outdir/$PACKAGE.html.gz" + html_mono_gz_size=`calcsize "$outdir/$PACKAGE.html.gz"` + copy_images "$outdir/" $PACKAGE.html + mv $PACKAGE.html "$outdir/" + ls -l "$outdir/$PACKAGE.html" "$outdir/$PACKAGE.html.gz" + + # Before Texinfo 5.0, makeinfo did not accept a --split=HOW option, + # it just always split by node. So if we're splitting by node anyway, + # leave it out. + if test "x$split" = xnode; then + split_arg= + else + split_arg=--split=$split + fi + # + opt="--html -o $PACKAGE.html $split_arg $commonarg $htmlarg" + cmd="$SETLANG $MAKEINFO $opt \"$srcfile\"" + printf "\nGenerating html by $split... ($cmd)\n" + eval "$cmd" + split_html_dir=$PACKAGE.html + copy_images $split_html_dir/ $split_html_dir/*.html + ( + cd $split_html_dir || exit 1 + tar -czf "$abs_outdir/$PACKAGE.html_$split.tar.gz" -- * + ) + eval \ + html_${split}_tgz_size=`calcsize "$outdir/$PACKAGE.html_$split.tar.gz"` + rm -rf "$outdir/html_$split/" + mv $split_html_dir "$outdir/html_$split/" + du -s "$outdir/html_$split/" + ls -l "$outdir/$PACKAGE.html_$split.tar.gz" + +else # use texi2html: + opt="--output $PACKAGE.html $commonarg $htmlarg" + cmd="$SETLANG $TEXI2HTML $opt \"$srcfile\"" + printf "\nGenerating monolithic html with texi2html... ($cmd)\n" + rm -rf $PACKAGE.html # in case a directory is left over + eval "$cmd" + html_mono_size=`calcsize $PACKAGE.html` + gzip -f -9 -c $PACKAGE.html >"$outdir/$PACKAGE.html.gz" + html_mono_gz_size=`calcsize "$outdir/$PACKAGE.html.gz"` + mv $PACKAGE.html "$outdir/" + + html_split node + html_split chapter + html_split section +fi +fi # end html + +# +printf "\nMaking .tar.gz for sources...\n" +d=`dirname $srcfile` +( + cd "$d" + srcfiles=`ls -d *.texinfo *.texi *.txi *.eps $source_extra 2>/dev/null` || true + tar czfh "$abs_outdir/$PACKAGE.texi.tar.gz" $srcfiles + ls -l "$abs_outdir/$PACKAGE.texi.tar.gz" +) +texi_tgz_size=`calcsize "$outdir/$PACKAGE.texi.tar.gz"` + +# +# Do everything again through docbook. +if test -n "$docbook"; then + opt="-o - --docbook $commonarg" + cmd="$SETLANG $MAKEINFO $opt \"$srcfile\" >${srcdir}/$PACKAGE-db.xml" + printf "\nGenerating docbook XML... ($cmd)\n" + eval "$cmd" + docbook_xml_size=`calcsize $PACKAGE-db.xml` + gzip -f -9 -c $PACKAGE-db.xml >"$outdir/$PACKAGE-db.xml.gz" + docbook_xml_gz_size=`calcsize "$outdir/$PACKAGE-db.xml.gz"` + mv $PACKAGE-db.xml "$outdir/" + + split_html_db_dir=html_node_db + opt="$commonarg -o $split_html_db_dir" + cmd="$DOCBOOK2HTML $opt \"${outdir}/$PACKAGE-db.xml\"" + printf "\nGenerating docbook HTML... ($cmd)\n" + eval "$cmd" + ( + cd ${split_html_db_dir} || exit 1 + tar -czf "$abs_outdir/${PACKAGE}.html_node_db.tar.gz" -- *.html + ) + html_node_db_tgz_size=`calcsize "$outdir/${PACKAGE}.html_node_db.tar.gz"` + rm -f "$outdir"/html_node_db/*.html + mkdir -p "$outdir/html_node_db" + mv ${split_html_db_dir}/*.html "$outdir/html_node_db/" + rmdir ${split_html_db_dir} + + cmd="$DOCBOOK2TXT \"${outdir}/$PACKAGE-db.xml\"" + printf "\nGenerating docbook ASCII... ($cmd)\n" + eval "$cmd" + docbook_ascii_size=`calcsize $PACKAGE-db.txt` + mv $PACKAGE-db.txt "$outdir/" + + cmd="$DOCBOOK2PDF \"${outdir}/$PACKAGE-db.xml\"" + printf "\nGenerating docbook PDF... ($cmd)\n" + eval "$cmd" + docbook_pdf_size=`calcsize $PACKAGE-db.pdf` + mv $PACKAGE-db.pdf "$outdir/" +fi + +# +printf "\nMaking index.html for $PACKAGE...\n" +if test -z "$use_texi2html"; then + CONDS="/%%IF *HTML_SECTION%%/,/%%ENDIF *HTML_SECTION%%/d;\ + /%%IF *HTML_CHAPTER%%/,/%%ENDIF *HTML_CHAPTER%%/d" +else + # should take account of --split here. + CONDS="/%%ENDIF.*%%/d;/%%IF *HTML_SECTION%%/d;/%%IF *HTML_CHAPTER%%/d" +fi + +curdate=`$SETLANG date '+%B %d, %Y'` +sed \ + -e "s!%%TITLE%%!$MANUAL_TITLE!g" \ + -e "s!%%EMAIL%%!$EMAIL!g" \ + -e "s!%%PACKAGE%%!$PACKAGE!g" \ + -e "s!%%DATE%%!$curdate!g" \ + -e "s!%%HTML_MONO_SIZE%%!$html_mono_size!g" \ + -e "s!%%HTML_MONO_GZ_SIZE%%!$html_mono_gz_size!g" \ + -e "s!%%HTML_NODE_TGZ_SIZE%%!$html_node_tgz_size!g" \ + -e "s!%%HTML_SECTION_TGZ_SIZE%%!$html_section_tgz_size!g" \ + -e "s!%%HTML_CHAPTER_TGZ_SIZE%%!$html_chapter_tgz_size!g" \ + -e "s!%%INFO_TGZ_SIZE%%!$info_tgz_size!g" \ + -e "s!%%DVI_GZ_SIZE%%!$dvi_gz_size!g" \ + -e "s!%%PDF_SIZE%%!$pdf_size!g" \ + -e "s!%%ASCII_SIZE%%!$ascii_size!g" \ + -e "s!%%ASCII_GZ_SIZE%%!$ascii_gz_size!g" \ + -e "s!%%TEXI_TGZ_SIZE%%!$texi_tgz_size!g" \ + -e "s!%%DOCBOOK_HTML_NODE_TGZ_SIZE%%!$html_node_db_tgz_size!g" \ + -e "s!%%DOCBOOK_ASCII_SIZE%%!$docbook_ascii_size!g" \ + -e "s!%%DOCBOOK_PDF_SIZE%%!$docbook_pdf_size!g" \ + -e "s!%%DOCBOOK_XML_SIZE%%!$docbook_xml_size!g" \ + -e "s!%%DOCBOOK_XML_GZ_SIZE%%!$docbook_xml_gz_size!g" \ + -e "s,%%SCRIPTURL%%,$scripturl,g" \ + -e "s!%%SCRIPTNAME%%!$prog!g" \ + -e "$CONDS" \ +$GENDOCS_TEMPLATE_DIR/gendocs_template >"$outdir/index.html" + +echo "Done, see $outdir/ subdirectory for new files." + +# Local variables: +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/config/gnulib-cache.m4 b/config/gnulib-cache.m4 new file mode 100644 index 0000000..2ec4643 --- /dev/null +++ b/config/gnulib-cache.m4 @@ -0,0 +1,73 @@ +# Copyright (C) 2002-2018 Free Software Foundation, Inc. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This file is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this file. If not, see <https://www.gnu.org/licenses/>. +# +# As a special exception to the GNU General Public License, +# this file may be distributed as part of a program that +# contains a configuration script generated by Autoconf, under +# the same distribution terms as the rest of that program. +# +# Generated by gnulib-tool. +# +# This file represents the specification of how gnulib-tool is used. +# It acts as a cache: It is written and read by gnulib-tool. +# In projects that use version control, this file is meant to be put under +# version control, like the configure.ac and various Makefile.am files. + + +# Specification in the form of a command-line invocation: +# gnulib-tool --import --local-dir=tmp \ +# --lib=do_not_make_me \ +# --source-base=autoopts \ +# --m4-base=config \ +# --doc-base=doc \ +# --tests-base=tests \ +# --aux-dir=config \ +# --lgpl=2 \ +# --makefile-name=gnulib.mk \ +# --no-conditional-dependencies \ +# --libtool \ +# --macro-prefix=gl \ +# extensions \ +# gendocs \ +# gettext-h \ +# havelib \ +# parse-duration \ +# snippet/_Noreturn \ +# stdnoreturn + +# Specification in the form of a few gnulib-tool.m4 macro invocations: +gl_LOCAL_DIR([tmp]) +gl_MODULES([ + extensions + gendocs + gettext-h + havelib + parse-duration + snippet/_Noreturn + stdnoreturn +]) +gl_AVOID([]) +gl_SOURCE_BASE([autoopts]) +gl_M4_BASE([config]) +gl_PO_BASE([]) +gl_DOC_BASE([doc]) +gl_TESTS_BASE([tests]) +gl_LIB([do_not_make_me]) +gl_LGPL([2]) +gl_MAKEFILE_NAME([gnulib.mk]) +gl_LIBTOOL +gl_MACRO_PREFIX([gl]) +gl_PO_DOMAIN([]) +gl_WITNESS_C_MACRO([]) diff --git a/config/gnulib-comp.m4 b/config/gnulib-comp.m4 new file mode 100644 index 0000000..399e98e --- /dev/null +++ b/config/gnulib-comp.m4 @@ -0,0 +1,230 @@ +# DO NOT EDIT! GENERATED AUTOMATICALLY! +# Copyright (C) 2002-2018 Free Software Foundation, Inc. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This file is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this file. If not, see <https://www.gnu.org/licenses/>. +# +# As a special exception to the GNU General Public License, +# this file may be distributed as part of a program that +# contains a configuration script generated by Autoconf, under +# the same distribution terms as the rest of that program. +# +# Generated by gnulib-tool. +# +# This file represents the compiled summary of the specification in +# gnulib-cache.m4. It lists the computed macro invocations that need +# to be invoked from configure.ac. +# In projects that use version control, this file can be treated like +# other built files. + + +# This macro should be invoked from ./configure.ac, in the section +# "Checks for programs", right after AC_PROG_CC, and certainly before +# any checks for libraries, header files, types and library functions. +AC_DEFUN([gl_EARLY], +[ + m4_pattern_forbid([^gl_[A-Z]])dnl the gnulib macro namespace + m4_pattern_allow([^gl_ES$])dnl a valid locale name + m4_pattern_allow([^gl_LIBOBJS$])dnl a variable + m4_pattern_allow([^gl_LTLIBOBJS$])dnl a variable + + # Pre-early section. + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + AC_REQUIRE([gl_PROG_AR_RANLIB]) + + # Code from module extensions: + # Code from module gendocs: + # Code from module gettext-h: + # Code from module havelib: + # Code from module host-cpu-c-abi: + # Code from module intprops: + # Code from module parse-duration: + # Code from module snippet/_Noreturn: + # Code from module stdnoreturn: +]) + +# This macro should be invoked from ./configure.ac, in the section +# "Check for header files, types and library functions". +AC_DEFUN([gl_INIT], +[ + AM_CONDITIONAL([GL_COND_LIBTOOL], [true]) + gl_cond_libtool=true + gl_m4_base='config' + m4_pushdef([AC_LIBOBJ], m4_defn([gl_LIBOBJ])) + m4_pushdef([AC_REPLACE_FUNCS], m4_defn([gl_REPLACE_FUNCS])) + m4_pushdef([AC_LIBSOURCES], m4_defn([gl_LIBSOURCES])) + m4_pushdef([gl_LIBSOURCES_LIST], []) + m4_pushdef([gl_LIBSOURCES_DIR], []) + gl_COMMON + gl_source_base='autoopts' + AC_SUBST([LIBINTL]) + AC_SUBST([LTLIBINTL]) + AC_REQUIRE([gl_HOST_CPU_C_ABI]) + gl_STDNORETURN_H + # End of code from modules + m4_ifval(gl_LIBSOURCES_LIST, [ + m4_syscmd([test ! -d ]m4_defn([gl_LIBSOURCES_DIR])[ || + for gl_file in ]gl_LIBSOURCES_LIST[ ; do + if test ! -r ]m4_defn([gl_LIBSOURCES_DIR])[/$gl_file ; then + echo "missing file ]m4_defn([gl_LIBSOURCES_DIR])[/$gl_file" >&2 + exit 1 + fi + done])dnl + m4_if(m4_sysval, [0], [], + [AC_FATAL([expected source file, required through AC_LIBSOURCES, not found])]) + ]) + m4_popdef([gl_LIBSOURCES_DIR]) + m4_popdef([gl_LIBSOURCES_LIST]) + m4_popdef([AC_LIBSOURCES]) + m4_popdef([AC_REPLACE_FUNCS]) + m4_popdef([AC_LIBOBJ]) + AC_CONFIG_COMMANDS_PRE([ + gl_libobjs= + gl_ltlibobjs= + if test -n "$gl_LIBOBJS"; then + # Remove the extension. + sed_drop_objext='s/\.o$//;s/\.obj$//' + for i in `for i in $gl_LIBOBJS; do echo "$i"; done | sed -e "$sed_drop_objext" | sort | uniq`; do + gl_libobjs="$gl_libobjs $i.$ac_objext" + gl_ltlibobjs="$gl_ltlibobjs $i.lo" + done + fi + AC_SUBST([gl_LIBOBJS], [$gl_libobjs]) + AC_SUBST([gl_LTLIBOBJS], [$gl_ltlibobjs]) + ]) + gltests_libdeps= + gltests_ltlibdeps= + m4_pushdef([AC_LIBOBJ], m4_defn([gltests_LIBOBJ])) + m4_pushdef([AC_REPLACE_FUNCS], m4_defn([gltests_REPLACE_FUNCS])) + m4_pushdef([AC_LIBSOURCES], m4_defn([gltests_LIBSOURCES])) + m4_pushdef([gltests_LIBSOURCES_LIST], []) + m4_pushdef([gltests_LIBSOURCES_DIR], []) + gl_COMMON + gl_source_base='tests' +changequote(,)dnl + gltests_WITNESS=IN_`echo "${PACKAGE-$PACKAGE_TARNAME}" | LC_ALL=C tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ | LC_ALL=C sed -e 's/[^A-Z0-9_]/_/g'`_GNULIB_TESTS +changequote([, ])dnl + AC_SUBST([gltests_WITNESS]) + gl_module_indicator_condition=$gltests_WITNESS + m4_pushdef([gl_MODULE_INDICATOR_CONDITION], [$gl_module_indicator_condition]) + m4_popdef([gl_MODULE_INDICATOR_CONDITION]) + m4_ifval(gltests_LIBSOURCES_LIST, [ + m4_syscmd([test ! -d ]m4_defn([gltests_LIBSOURCES_DIR])[ || + for gl_file in ]gltests_LIBSOURCES_LIST[ ; do + if test ! -r ]m4_defn([gltests_LIBSOURCES_DIR])[/$gl_file ; then + echo "missing file ]m4_defn([gltests_LIBSOURCES_DIR])[/$gl_file" >&2 + exit 1 + fi + done])dnl + m4_if(m4_sysval, [0], [], + [AC_FATAL([expected source file, required through AC_LIBSOURCES, not found])]) + ]) + m4_popdef([gltests_LIBSOURCES_DIR]) + m4_popdef([gltests_LIBSOURCES_LIST]) + m4_popdef([AC_LIBSOURCES]) + m4_popdef([AC_REPLACE_FUNCS]) + m4_popdef([AC_LIBOBJ]) + AC_CONFIG_COMMANDS_PRE([ + gltests_libobjs= + gltests_ltlibobjs= + if test -n "$gltests_LIBOBJS"; then + # Remove the extension. + sed_drop_objext='s/\.o$//;s/\.obj$//' + for i in `for i in $gltests_LIBOBJS; do echo "$i"; done | sed -e "$sed_drop_objext" | sort | uniq`; do + gltests_libobjs="$gltests_libobjs $i.$ac_objext" + gltests_ltlibobjs="$gltests_ltlibobjs $i.lo" + done + fi + AC_SUBST([gltests_LIBOBJS], [$gltests_libobjs]) + AC_SUBST([gltests_LTLIBOBJS], [$gltests_ltlibobjs]) + ]) +]) + +# Like AC_LIBOBJ, except that the module name goes +# into gl_LIBOBJS instead of into LIBOBJS. +AC_DEFUN([gl_LIBOBJ], [ + AS_LITERAL_IF([$1], [gl_LIBSOURCES([$1.c])])dnl + gl_LIBOBJS="$gl_LIBOBJS $1.$ac_objext" +]) + +# Like AC_REPLACE_FUNCS, except that the module name goes +# into gl_LIBOBJS instead of into LIBOBJS. +AC_DEFUN([gl_REPLACE_FUNCS], [ + m4_foreach_w([gl_NAME], [$1], [AC_LIBSOURCES(gl_NAME[.c])])dnl + AC_CHECK_FUNCS([$1], , [gl_LIBOBJ($ac_func)]) +]) + +# Like AC_LIBSOURCES, except the directory where the source file is +# expected is derived from the gnulib-tool parameterization, +# and alloca is special cased (for the alloca-opt module). +# We could also entirely rely on EXTRA_lib..._SOURCES. +AC_DEFUN([gl_LIBSOURCES], [ + m4_foreach([_gl_NAME], [$1], [ + m4_if(_gl_NAME, [alloca.c], [], [ + m4_define([gl_LIBSOURCES_DIR], [autoopts]) + m4_append([gl_LIBSOURCES_LIST], _gl_NAME, [ ]) + ]) + ]) +]) + +# Like AC_LIBOBJ, except that the module name goes +# into gltests_LIBOBJS instead of into LIBOBJS. +AC_DEFUN([gltests_LIBOBJ], [ + AS_LITERAL_IF([$1], [gltests_LIBSOURCES([$1.c])])dnl + gltests_LIBOBJS="$gltests_LIBOBJS $1.$ac_objext" +]) + +# Like AC_REPLACE_FUNCS, except that the module name goes +# into gltests_LIBOBJS instead of into LIBOBJS. +AC_DEFUN([gltests_REPLACE_FUNCS], [ + m4_foreach_w([gl_NAME], [$1], [AC_LIBSOURCES(gl_NAME[.c])])dnl + AC_CHECK_FUNCS([$1], , [gltests_LIBOBJ($ac_func)]) +]) + +# Like AC_LIBSOURCES, except the directory where the source file is +# expected is derived from the gnulib-tool parameterization, +# and alloca is special cased (for the alloca-opt module). +# We could also entirely rely on EXTRA_lib..._SOURCES. +AC_DEFUN([gltests_LIBSOURCES], [ + m4_foreach([_gl_NAME], [$1], [ + m4_if(_gl_NAME, [alloca.c], [], [ + m4_define([gltests_LIBSOURCES_DIR], [tests]) + m4_append([gltests_LIBSOURCES_LIST], _gl_NAME, [ ]) + ]) + ]) +]) + +# This macro records the list of files which have been installed by +# gnulib-tool and may be removed by future gnulib-tool invocations. +AC_DEFUN([gl_FILE_LIST], [ + build-aux/config.rpath + build-aux/gendocs.sh + doc/gendocs_template + doc/gendocs_template_min + lib/_Noreturn.h + lib/gettext.h + lib/intprops.h + lib/parse-duration.c + lib/parse-duration.h + lib/stdnoreturn.in.h + m4/00gnulib.m4 + m4/asm-underscore.m4 + m4/extensions.m4 + m4/gnulib-common.m4 + m4/host-cpu-c-abi.m4 + m4/lib-ld.m4 + m4/lib-link.m4 + m4/lib-prefix.m4 + m4/onceonly.m4 + m4/stdnoreturn.m4 +]) diff --git a/config/guile.m4 b/config/guile.m4 new file mode 100644 index 0000000..89823e9 --- /dev/null +++ b/config/guile.m4 @@ -0,0 +1,394 @@ +## Autoconf macros for working with Guile. +## +## Copyright (C) 1998,2001, 2006, 2010, 2012, 2013, 2014 Free Software Foundation, Inc. +## +## This library is free software; you can redistribute it and/or +## modify it under the terms of the GNU Lesser General Public License +## as published by the Free Software Foundation; either version 3 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 +## Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public +## License along with this library; if not, write to the Free Software +## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +## 02110-1301 USA + +# serial 10 + +## Index +## ----- +## +## GUILE_PKG -- find Guile development files +## GUILE_PROGS -- set paths to Guile interpreter, config and tool programs +## GUILE_FLAGS -- set flags for compiling and linking with Guile +## GUILE_SITE_DIR -- find path to Guile "site" directories +## GUILE_CHECK -- evaluate Guile Scheme code and capture the return value +## GUILE_MODULE_CHECK -- check feature of a Guile Scheme module +## GUILE_MODULE_AVAILABLE -- check availability of a Guile Scheme module +## GUILE_MODULE_REQUIRED -- fail if a Guile Scheme module is unavailable +## GUILE_MODULE_EXPORTS -- check if a module exports a variable +## GUILE_MODULE_REQUIRED_EXPORT -- fail if a module doesn't export a variable + +## Code +## ---- + +## NOTE: Comments preceding an AC_DEFUN (starting from "Usage:") are massaged +## into doc/ref/autoconf-macros.texi (see Makefile.am in that directory). + +# GUILE_PKG -- find Guile development files +# +# Usage: GUILE_PKG([VERSIONS]) +# +# This macro runs the @code{pkg-config} tool to find development files +# for an available version of Guile. +# +# By default, this macro will search for the latest stable version of +# Guile (e.g. 2.2), falling back to the previous stable version +# (e.g. 2.0) if it is available. If no guile-@var{VERSION}.pc file is +# found, an error is signalled. The found version is stored in +# @var{GUILE_EFFECTIVE_VERSION}. +# +# If @code{GUILE_PROGS} was already invoked, this macro ensures that the +# development files have the same effective version as the Guile +# program. +# +# @var{GUILE_EFFECTIVE_VERSION} is marked for substitution, as by +# @code{AC_SUBST}. +# +AC_DEFUN([GUILE_PKG], + [PKG_PROG_PKG_CONFIG + _guile_versions_to_search="m4_default([$1], [2.2 2.0 1.8])" + if test -n "$GUILE_EFFECTIVE_VERSION"; then + _guile_tmp="" + for v in $_guile_versions_to_search; do + if test "$v" = "$GUILE_EFFECTIVE_VERSION"; then + _guile_tmp=$v + fi + done + if test -z "$_guile_tmp"; then + AC_MSG_FAILURE([searching for guile development files for versions $_guile_versions_to_search, but previously found $GUILE version $GUILE_EFFECTIVE_VERSION]) + fi + _guile_versions_to_search=$GUILE_EFFECTIVE_VERSION + fi + GUILE_EFFECTIVE_VERSION="" + _guile_errors="" + for v in $_guile_versions_to_search; do + if test -z "$GUILE_EFFECTIVE_VERSION"; then + AC_MSG_NOTICE([checking for guile $v]) + PKG_CHECK_EXISTS([guile-$v], [GUILE_EFFECTIVE_VERSION=$v], []) + fi + done + + if test -z "$GUILE_EFFECTIVE_VERSION"; then + AC_MSG_ERROR([ +No Guile development packages were found. + +Please verify that you have Guile installed. If you installed Guile +from a binary distribution, please verify that you have also installed +the development packages. If you installed it yourself, you might need +to adjust your PKG_CONFIG_PATH; see the pkg-config man page for more. +]) + fi + AC_MSG_NOTICE([found guile $GUILE_EFFECTIVE_VERSION]) + AC_SUBST([GUILE_EFFECTIVE_VERSION]) + ]) + +# GUILE_FLAGS -- set flags for compiling and linking with Guile +# +# Usage: GUILE_FLAGS +# +# This macro runs the @code{pkg-config} tool to find out how to compile +# and link programs against Guile. It sets four variables: +# @var{GUILE_CFLAGS}, @var{GUILE_LDFLAGS}, @var{GUILE_LIBS}, and +# @var{GUILE_LTLIBS}. +# +# @var{GUILE_CFLAGS}: flags to pass to a C or C++ compiler to build code that +# uses Guile header files. This is almost always just one or more @code{-I} +# flags. +# +# @var{GUILE_LDFLAGS}: flags to pass to the compiler to link a program +# against Guile. This includes @code{-lguile-@var{VERSION}} for the +# Guile library itself, and may also include one or more @code{-L} flag +# to tell the compiler where to find the libraries. But it does not +# include flags that influence the program's runtime search path for +# libraries, and will therefore lead to a program that fails to start, +# unless all necessary libraries are installed in a standard location +# such as @file{/usr/lib}. +# +# @var{GUILE_LIBS} and @var{GUILE_LTLIBS}: flags to pass to the compiler or to +# libtool, respectively, to link a program against Guile. It includes flags +# that augment the program's runtime search path for libraries, so that shared +# libraries will be found at the location where they were during linking, even +# in non-standard locations. @var{GUILE_LIBS} is to be used when linking the +# program directly with the compiler, whereas @var{GUILE_LTLIBS} is to be used +# when linking the program is done through libtool. +# +# The variables are marked for substitution, as by @code{AC_SUBST}. +# +AC_DEFUN([GUILE_FLAGS], + [AC_REQUIRE([GUILE_PKG]) + PKG_CHECK_MODULES(GUILE, [guile-$GUILE_EFFECTIVE_VERSION]) + + dnl GUILE_CFLAGS and GUILE_LIBS are already defined and AC_SUBST'd by + dnl PKG_CHECK_MODULES. But GUILE_LIBS to pkg-config is GUILE_LDFLAGS + dnl to us. + + GUILE_LDFLAGS=$GUILE_LIBS + + dnl Determine the platform dependent parameters needed to use rpath. + dnl AC_LIB_LINKFLAGS_FROM_LIBS is defined in gnulib/m4/lib-link.m4 and needs + dnl the file gnulib/build-aux/config.rpath. + AC_LIB_LINKFLAGS_FROM_LIBS([GUILE_LIBS], [$GUILE_LDFLAGS], []) + GUILE_LIBS="$GUILE_LDFLAGS $GUILE_LIBS" + AC_LIB_LINKFLAGS_FROM_LIBS([GUILE_LTLIBS], [$GUILE_LDFLAGS], [yes]) + GUILE_LTLIBS="$GUILE_LDFLAGS $GUILE_LTLIBS" + + AC_SUBST([GUILE_EFFECTIVE_VERSION]) + AC_SUBST([GUILE_CFLAGS]) + AC_SUBST([GUILE_LDFLAGS]) + AC_SUBST([GUILE_LIBS]) + AC_SUBST([GUILE_LTLIBS]) + ]) + +# GUILE_SITE_DIR -- find path to Guile site directories +# +# Usage: GUILE_SITE_DIR +# +# This looks for Guile's "site" directories. The variable @var{GUILE_SITE} will +# be set to Guile's "site" directory for Scheme source files (usually something +# like PREFIX/share/guile/site). @var{GUILE_SITE_CCACHE} will be set to the +# directory for compiled Scheme files also known as @code{.go} files +# (usually something like +# PREFIX/lib/guile/@var{GUILE_EFFECTIVE_VERSION}/site-ccache). +# @var{GUILE_EXTENSION} will be set to the directory for compiled C extensions +# (usually something like +# PREFIX/lib/guile/@var{GUILE_EFFECTIVE_VERSION}/extensions). The latter two +# are set to blank if the particular version of Guile does not support +# them. Note that this macro will run the macros @code{GUILE_PKG} and +# @code{GUILE_PROGS} if they have not already been run. +# +# The variables are marked for substitution, as by @code{AC_SUBST}. +# +AC_DEFUN([GUILE_SITE_DIR], + [AC_REQUIRE([GUILE_PKG]) + AC_REQUIRE([GUILE_PROGS]) + AC_MSG_CHECKING(for Guile site directory) + GUILE_SITE=`$PKG_CONFIG --print-errors --variable=sitedir guile-$GUILE_EFFECTIVE_VERSION` + AC_MSG_RESULT($GUILE_SITE) + if test "$GUILE_SITE" = ""; then + AC_MSG_FAILURE(sitedir not found) + fi + AC_SUBST(GUILE_SITE) + AC_MSG_CHECKING([for Guile site-ccache directory using pkgconfig]) + GUILE_SITE_CCACHE=`$PKG_CONFIG --variable=siteccachedir guile-$GUILE_EFFECTIVE_VERSION` + if test "$GUILE_SITE_CCACHE" = ""; then + AC_MSG_RESULT(no) + AC_MSG_CHECKING([for Guile site-ccache directory using interpreter]) + GUILE_SITE_CCACHE=`$GUILE -c "(display (if (defined? '%site-ccache-dir) (%site-ccache-dir) \"\"))"` + if test $? != "0" -o "$GUILE_SITE_CCACHE" = ""; then + AC_MSG_RESULT(no) + GUILE_SITE_CCACHE="" + AC_MSG_WARN([siteccachedir not found]) + fi + fi + AC_MSG_RESULT($GUILE_SITE_CCACHE) + AC_SUBST([GUILE_SITE_CCACHE]) + AC_MSG_CHECKING(for Guile extensions directory) + GUILE_EXTENSION=`$PKG_CONFIG --print-errors --variable=extensiondir guile-$GUILE_EFFECTIVE_VERSION` + AC_MSG_RESULT($GUILE_EXTENSION) + if test "$GUILE_EXTENSION" = ""; then + GUILE_EXTENSION="" + AC_MSG_WARN(extensiondir not found) + fi + AC_SUBST(GUILE_EXTENSION) + ]) + +# GUILE_PROGS -- set paths to Guile interpreter, config and tool programs +# +# Usage: GUILE_PROGS([VERSION]) +# +# This macro looks for programs @code{guile} and @code{guild}, setting +# variables @var{GUILE} and @var{GUILD} to their paths, respectively. +# The macro will attempt to find @code{guile} with the suffix of +# @code{-X.Y}, followed by looking for it with the suffix @code{X.Y}, and +# then fall back to looking for @code{guile} with no suffix. If +# @code{guile} is still not found, signal an error. The suffix, if any, +# that was required to find @code{guile} will be used for @code{guild} +# as well. +# +# By default, this macro will search for the latest stable version of +# Guile (e.g. 2.2). x.y or x.y.z versions can be specified. If an older +# version is found, the macro will signal an error. +# +# The effective version of the found @code{guile} is set to +# @var{GUILE_EFFECTIVE_VERSION}. This macro ensures that the effective +# version is compatible with the result of a previous invocation of +# @code{GUILE_FLAGS}, if any. +# +# As a legacy interface, it also looks for @code{guile-config} and +# @code{guile-tools}, setting @var{GUILE_CONFIG} and @var{GUILE_TOOLS}. +# +# The variables are marked for substitution, as by @code{AC_SUBST}. +# +AC_DEFUN([GUILE_PROGS], + [_guile_required_version="m4_default([$1], [$GUILE_EFFECTIVE_VERSION])" + if test -z "$_guile_required_version"; then + _guile_required_version=2.2 + fi + + _guile_candidates=guile + _tmp= + for v in `echo "$_guile_required_version" | tr . ' '`; do + if test -n "$_tmp"; then _tmp=$_tmp.; fi + _tmp=$_tmp$v + _guile_candidates="guile-$_tmp guile$_tmp $_guile_candidates" + done + + AC_PATH_PROGS(GUILE,[$_guile_candidates]) + if test -z "$GUILE"; then + AC_MSG_ERROR([guile required but not found]) + fi + + _guile_suffix=`echo "$GUILE" | sed -e 's,^.*/guile\(.*\)$,\1,'` + _guile_effective_version=`$GUILE -c "(display (effective-version))"` + if test -z "$GUILE_EFFECTIVE_VERSION"; then + GUILE_EFFECTIVE_VERSION=$_guile_effective_version + elif test "$GUILE_EFFECTIVE_VERSION" != "$_guile_effective_version"; then + AC_MSG_ERROR([found development files for Guile $GUILE_EFFECTIVE_VERSION, but $GUILE has effective version $_guile_effective_version]) + fi + + _guile_major_version=`$GUILE -c "(display (major-version))"` + _guile_minor_version=`$GUILE -c "(display (minor-version))"` + _guile_micro_version=`$GUILE -c "(display (micro-version))"` + _guile_prog_version="$_guile_major_version.$_guile_minor_version.$_guile_micro_version" + + AC_MSG_CHECKING([for Guile version >= $_guile_required_version]) + _major_version=`echo $_guile_required_version | cut -d . -f 1` + _minor_version=`echo $_guile_required_version | cut -d . -f 2` + _micro_version=`echo $_guile_required_version | cut -d . -f 3` + if test "$_guile_major_version" -gt "$_major_version"; then + true + elif test "$_guile_major_version" -eq "$_major_version"; then + if test "$_guile_minor_version" -gt "$_minor_version"; then + true + elif test "$_guile_minor_version" -eq "$_minor_version"; then + if test -n "$_micro_version"; then + if test "$_guile_micro_version" -lt "$_micro_version"; then + AC_MSG_ERROR([Guile $_guile_required_version required, but $_guile_prog_version found]) + fi + fi + elif test "$GUILE_EFFECTIVE_VERSION" = "$_major_version.$_minor_version" -a -z "$_micro_version"; then + # Allow prereleases that have the right effective version. + true + else + as_fn_error $? "Guile $_guile_required_version required, but $_guile_prog_version found" "$LINENO" 5 + fi + elif test "$GUILE_EFFECTIVE_VERSION" = "$_major_version.$_minor_version" -a -z "$_micro_version"; then + # Allow prereleases that have the right effective version. + true + else + AC_MSG_ERROR([Guile $_guile_required_version required, but $_guile_prog_version found]) + fi + AC_MSG_RESULT([$_guile_prog_version]) + + AC_PATH_PROG(GUILD,[guild$_guile_suffix]) + AC_SUBST(GUILD) + + AC_PATH_PROG(GUILE_CONFIG,[guile-config$_guile_suffix]) + AC_SUBST(GUILE_CONFIG) + if test -n "$GUILD"; then + GUILE_TOOLS=$GUILD + else + AC_PATH_PROG(GUILE_TOOLS,[guile-tools$_guile_suffix]) + fi + AC_SUBST(GUILE_TOOLS) + ]) + +# GUILE_CHECK -- evaluate Guile Scheme code and capture the return value +# +# Usage: GUILE_CHECK_RETVAL(var,check) +# +# @var{var} is a shell variable name to be set to the return value. +# @var{check} is a Guile Scheme expression, evaluated with "$GUILE -c", and +# returning either 0 or non-#f to indicate the check passed. +# Non-0 number or #f indicates failure. +# Avoid using the character "#" since that confuses autoconf. +# +AC_DEFUN([GUILE_CHECK], + [AC_REQUIRE([GUILE_PROGS]) + $GUILE -c "$2" > /dev/null 2>&1 + $1=$? + ]) + +# GUILE_MODULE_CHECK -- check feature of a Guile Scheme module +# +# Usage: GUILE_MODULE_CHECK(var,module,featuretest,description) +# +# @var{var} is a shell variable name to be set to "yes" or "no". +# @var{module} is a list of symbols, like: (ice-9 common-list). +# @var{featuretest} is an expression acceptable to GUILE_CHECK, q.v. +# @var{description} is a present-tense verb phrase (passed to AC_MSG_CHECKING). +# +AC_DEFUN([GUILE_MODULE_CHECK], + [AC_MSG_CHECKING([if $2 $4]) + GUILE_CHECK($1,(use-modules $2) (exit ((lambda () $3)))) + if test "$$1" = "0" ; then $1=yes ; else $1=no ; fi + AC_MSG_RESULT($$1) + ]) + +# GUILE_MODULE_AVAILABLE -- check availability of a Guile Scheme module +# +# Usage: GUILE_MODULE_AVAILABLE(var,module) +# +# @var{var} is a shell variable name to be set to "yes" or "no". +# @var{module} is a list of symbols, like: (ice-9 common-list). +# +AC_DEFUN([GUILE_MODULE_AVAILABLE], + [GUILE_MODULE_CHECK($1,$2,0,is available) + ]) + +# GUILE_MODULE_REQUIRED -- fail if a Guile Scheme module is unavailable +# +# Usage: GUILE_MODULE_REQUIRED(symlist) +# +# @var{symlist} is a list of symbols, WITHOUT surrounding parens, +# like: ice-9 common-list. +# +AC_DEFUN([GUILE_MODULE_REQUIRED], + [GUILE_MODULE_AVAILABLE(ac_guile_module_required, ($1)) + if test "$ac_guile_module_required" = "no" ; then + AC_MSG_ERROR([required guile module not found: ($1)]) + fi + ]) + +# GUILE_MODULE_EXPORTS -- check if a module exports a variable +# +# Usage: GUILE_MODULE_EXPORTS(var,module,modvar) +# +# @var{var} is a shell variable to be set to "yes" or "no". +# @var{module} is a list of symbols, like: (ice-9 common-list). +# @var{modvar} is the Guile Scheme variable to check. +# +AC_DEFUN([GUILE_MODULE_EXPORTS], + [GUILE_MODULE_CHECK($1,$2,$3,exports `$3') + ]) + +# GUILE_MODULE_REQUIRED_EXPORT -- fail if a module doesn't export a variable +# +# Usage: GUILE_MODULE_REQUIRED_EXPORT(module,modvar) +# +# @var{module} is a list of symbols, like: (ice-9 common-list). +# @var{modvar} is the Guile Scheme variable to check. +# +AC_DEFUN([GUILE_MODULE_REQUIRED_EXPORT], + [GUILE_MODULE_EXPORTS(guile_module_required_export,$1,$2) + if test "$guile_module_required_export" = "no" ; then + AC_MSG_ERROR([module $1 does not export $2; required]) + fi + ]) + +## guile.m4 ends here diff --git a/config/host-cpu-c-abi.m4 b/config/host-cpu-c-abi.m4 new file mode 100644 index 0000000..3fac6f7 --- /dev/null +++ b/config/host-cpu-c-abi.m4 @@ -0,0 +1,456 @@ +# host-cpu-c-abi.m4 serial 10 +dnl Copyright (C) 2002-2018 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 From Bruno Haible and Sam Steingold. + +dnl Sets the HOST_CPU variable to the canonical name of the CPU. +dnl Sets the HOST_CPU_C_ABI variable to the canonical name of the CPU with its +dnl C language ABI (application binary interface). +dnl Also defines __${HOST_CPU}__ and __${HOST_CPU_C_ABI}__ as C macros in +dnl config.h. +dnl +dnl This canonical name can be used to select a particular assembly language +dnl source file that will interoperate with C code on the given host. +dnl +dnl For example: +dnl * 'i386' and 'sparc' are different canonical names, because code for i386 +dnl will not run on SPARC CPUs and vice versa. They have different +dnl instruction sets. +dnl * 'sparc' and 'sparc64' are different canonical names, because code for +dnl 'sparc' and code for 'sparc64' cannot be linked together: 'sparc' code +dnl contains 32-bit instructions, whereas 'sparc64' code contains 64-bit +dnl instructions. A process on a SPARC CPU can be in 32-bit mode or in 64-bit +dnl mode, but not both. +dnl * 'mips' and 'mipsn32' are different canonical names, because they use +dnl different argument passing and return conventions for C functions, and +dnl although the instruction set of 'mips' is a large subset of the +dnl instruction set of 'mipsn32'. +dnl * 'mipsn32' and 'mips64' are different canonical names, because they use +dnl different sizes for the C types like 'int' and 'void *', and although +dnl the instruction sets of 'mipsn32' and 'mips64' are the same. +dnl * The same canonical name is used for different endiannesses. You can +dnl determine the endianness through preprocessor symbols: +dnl - 'arm': test __ARMEL__. +dnl - 'mips', 'mipsn32', 'mips64': test _MIPSEB vs. _MIPSEL. +dnl - 'powerpc64': test _BIG_ENDIAN vs. _LITTLE_ENDIAN. +dnl * The same name 'i386' is used for CPUs of type i386, i486, i586 +dnl (Pentium), AMD K7, Pentium II, Pentium IV, etc., because +dnl - Instructions that do not exist on all of these CPUs (cmpxchg, +dnl MMX, SSE, SSE2, 3DNow! etc.) are not frequently used. If your +dnl assembly language source files use such instructions, you will +dnl need to make the distinction. +dnl - Speed of execution of the common instruction set is reasonable across +dnl the entire family of CPUs. If you have assembly language source files +dnl that are optimized for particular CPU types (like GNU gmp has), you +dnl will need to make the distinction. +dnl See <https://en.wikipedia.org/wiki/X86_instruction_listings>. +AC_DEFUN([gl_HOST_CPU_C_ABI], +[ + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([gl_C_ASM]) + AC_CACHE_CHECK([host CPU and C ABI], [gl_cv_host_cpu_c_abi], + [case "$host_cpu" in + +changequote(,)dnl + i[4567]86 ) +changequote([,])dnl + gl_cv_host_cpu_c_abi=i386 + ;; + + x86_64 ) + # On x86_64 systems, the C compiler may be generating code in one of + # these ABIs: + # - 64-bit instruction set, 64-bit pointers, 64-bit 'long': x86_64. + # - 64-bit instruction set, 64-bit pointers, 32-bit 'long': x86_64 + # with native Windows (mingw, MSVC). + # - 64-bit instruction set, 32-bit pointers, 32-bit 'long': x86_64-x32. + # - 32-bit instruction set, 32-bit pointers, 32-bit 'long': i386. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if (defined __x86_64__ || defined __amd64__ \ + || defined _M_X64 || defined _M_AMD64) + int ok; + #else + error fail + #endif + ]])], + [AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __ILP32__ || defined _ILP32 + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=x86_64-x32], + [gl_cv_host_cpu_c_abi=x86_64])], + [gl_cv_host_cpu_c_abi=i386]) + ;; + +changequote(,)dnl + alphaev[4-8] | alphaev56 | alphapca5[67] | alphaev6[78] ) +changequote([,])dnl + gl_cv_host_cpu_c_abi=alpha + ;; + + arm* | aarch64 ) + # Assume arm with EABI. + # On arm64 systems, the C compiler may be generating code in one of + # these ABIs: + # - aarch64 instruction set, 64-bit pointers, 64-bit 'long': arm64. + # - aarch64 instruction set, 32-bit pointers, 32-bit 'long': arm64-ilp32. + # - 32-bit instruction set, 32-bit pointers, 32-bit 'long': arm or armhf. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#ifdef __aarch64__ + int ok; + #else + error fail + #endif + ]])], + [AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __ILP32__ || defined _ILP32 + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=arm64-ilp32], + [gl_cv_host_cpu_c_abi=arm64])], + [# Don't distinguish little-endian and big-endian arm, since they + # don't require different machine code for simple operations and + # since the user can distinguish them through the preprocessor + # defines __ARMEL__ vs. __ARMEB__. + # But distinguish arm which passes floating-point arguments and + # return values in integer registers (r0, r1, ...) - this is + # gcc -mfloat-abi=soft or gcc -mfloat-abi=softfp - from arm which + # passes them in float registers (s0, s1, ...) and double registers + # (d0, d1, ...) - this is gcc -mfloat-abi=hard. GCC 4.6 or newer + # sets the preprocessor defines __ARM_PCS (for the first case) and + # __ARM_PCS_VFP (for the second case), but older GCC does not. + echo 'double ddd; void func (double dd) { ddd = dd; }' > conftest.c + # Look for a reference to the register d0 in the .s file. + AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS $gl_c_asm_opt conftest.c) >/dev/null 2>&1 + if LC_ALL=C grep 'd0,' conftest.$gl_asmext >/dev/null; then + gl_cv_host_cpu_c_abi=armhf + else + gl_cv_host_cpu_c_abi=arm + fi + rm -f conftest* + ]) + ;; + + hppa1.0 | hppa1.1 | hppa2.0* | hppa64 ) + # On hppa, the C compiler may be generating 32-bit code or 64-bit + # code. In the latter case, it defines _LP64 and __LP64__. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#ifdef __LP64__ + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=hppa64], + [gl_cv_host_cpu_c_abi=hppa]) + ;; + + ia64* ) + # On ia64 on HP-UX, the C compiler may be generating 64-bit code or + # 32-bit code. In the latter case, it defines _ILP32. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#ifdef _ILP32 + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=ia64-ilp32], + [gl_cv_host_cpu_c_abi=ia64]) + ;; + + mips* ) + # We should also check for (_MIPS_SZPTR == 64), but gcc keeps this + # at 32. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined _MIPS_SZLONG && (_MIPS_SZLONG == 64) + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=mips64], + [# In the n32 ABI, _ABIN32 is defined, _ABIO32 is not defined (but + # may later get defined by <sgidefs.h>), and _MIPS_SIM == _ABIN32. + # In the 32 ABI, _ABIO32 is defined, _ABIN32 is not defined (but + # may later get defined by <sgidefs.h>), and _MIPS_SIM == _ABIO32. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if (_MIPS_SIM == _ABIN32) + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=mipsn32], + [gl_cv_host_cpu_c_abi=mips])]) + ;; + + powerpc* ) + # Different ABIs are in use on AIX vs. Mac OS X vs. Linux,*BSD. + # No need to distinguish them here; the caller may distinguish + # them based on the OS. + # On powerpc64 systems, the C compiler may still be generating + # 32-bit code. And on powerpc-ibm-aix systems, the C compiler may + # be generating 64-bit code. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __powerpc64__ || defined _ARCH_PPC64 + int ok; + #else + error fail + #endif + ]])], + [# On powerpc64, there are two ABIs on Linux: The AIX compatible + # one and the ELFv2 one. The latter defines _CALL_ELF=2. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined _CALL_ELF && _CALL_ELF == 2 + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=powerpc64-elfv2], + [gl_cv_host_cpu_c_abi=powerpc64]) + ], + [gl_cv_host_cpu_c_abi=powerpc]) + ;; + + rs6000 ) + gl_cv_host_cpu_c_abi=powerpc + ;; + + riscv32 | riscv64 ) + # There are 2 architectures (with variants): rv32* and rv64*. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if __riscv_xlen == 64 + int ok; + #else + error fail + #endif + ]])], + [cpu=riscv64], + [cpu=riscv32]) + # There are 6 ABIs: ilp32, ilp32f, ilp32d, lp64, lp64f, lp64d. + # Size of 'long' and 'void *': + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __LP64__ + int ok; + #else + error fail + #endif + ]])], + [main_abi=lp64], + [main_abi=ilp32]) + # Float ABIs: + # __riscv_float_abi_double: + # 'float' and 'double' are passed in floating-point registers. + # __riscv_float_abi_single: + # 'float' are passed in floating-point registers. + # __riscv_float_abi_soft: + # No values are passed in floating-point registers. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __riscv_float_abi_double + int ok; + #else + error fail + #endif + ]])], + [float_abi=d], + [AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __riscv_float_abi_single + int ok; + #else + error fail + #endif + ]])], + [float_abi=f], + [float_abi='']) + ]) + gl_cv_host_cpu_c_abi="${cpu}-${main_abi}${float_abi}" + ;; + + s390* ) + # On s390x, the C compiler may be generating 64-bit (= s390x) code + # or 31-bit (= s390) code. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __LP64__ || defined __s390x__ + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=s390x], + [gl_cv_host_cpu_c_abi=s390]) + ;; + + sparc | sparc64 ) + # UltraSPARCs running Linux have `uname -m` = "sparc64", but the + # C compiler still generates 32-bit code. + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __sparcv9 || defined __arch64__ + int ok; + #else + error fail + #endif + ]])], + [gl_cv_host_cpu_c_abi=sparc64], + [gl_cv_host_cpu_c_abi=sparc]) + ;; + + *) + gl_cv_host_cpu_c_abi="$host_cpu" + ;; + esac + ]) + + dnl In most cases, $HOST_CPU and $HOST_CPU_C_ABI are the same. + HOST_CPU=`echo "$gl_cv_host_cpu_c_abi" | sed -e 's/-.*//'` + HOST_CPU_C_ABI="$gl_cv_host_cpu_c_abi" + AC_SUBST([HOST_CPU]) + AC_SUBST([HOST_CPU_C_ABI]) + + # This was + # AC_DEFINE_UNQUOTED([__${HOST_CPU}__]) + # AC_DEFINE_UNQUOTED([__${HOST_CPU_C_ABI}__]) + # earlier, but KAI C++ 3.2d doesn't like this. + sed -e 's/-/_/g' >> confdefs.h <<EOF +#ifndef __${HOST_CPU}__ +#define __${HOST_CPU}__ 1 +#endif +#ifndef __${HOST_CPU_C_ABI}__ +#define __${HOST_CPU_C_ABI}__ 1 +#endif +EOF + AH_TOP([/* CPU and C ABI indicator */ +#ifndef __i386__ +#undef __i386__ +#endif +#ifndef __x86_64_x32__ +#undef __x86_64_x32__ +#endif +#ifndef __x86_64__ +#undef __x86_64__ +#endif +#ifndef __alpha__ +#undef __alpha__ +#endif +#ifndef __arm__ +#undef __arm__ +#endif +#ifndef __armhf__ +#undef __armhf__ +#endif +#ifndef __arm64_ilp32__ +#undef __arm64_ilp32__ +#endif +#ifndef __arm64__ +#undef __arm64__ +#endif +#ifndef __hppa__ +#undef __hppa__ +#endif +#ifndef __hppa64__ +#undef __hppa64__ +#endif +#ifndef __ia64_ilp32__ +#undef __ia64_ilp32__ +#endif +#ifndef __ia64__ +#undef __ia64__ +#endif +#ifndef __m68k__ +#undef __m68k__ +#endif +#ifndef __mips__ +#undef __mips__ +#endif +#ifndef __mipsn32__ +#undef __mipsn32__ +#endif +#ifndef __mips64__ +#undef __mips64__ +#endif +#ifndef __powerpc__ +#undef __powerpc__ +#endif +#ifndef __powerpc64__ +#undef __powerpc64__ +#endif +#ifndef __powerpc64_elfv2__ +#undef __powerpc64_elfv2__ +#endif +#ifndef __riscv32__ +#undef __riscv32__ +#endif +#ifndef __riscv64__ +#undef __riscv64__ +#endif +#ifndef __riscv32_ilp32__ +#undef __riscv32_ilp32__ +#endif +#ifndef __riscv32_ilp32f__ +#undef __riscv32_ilp32f__ +#endif +#ifndef __riscv32_ilp32d__ +#undef __riscv32_ilp32d__ +#endif +#ifndef __riscv64_ilp32__ +#undef __riscv64_ilp32__ +#endif +#ifndef __riscv64_ilp32f__ +#undef __riscv64_ilp32f__ +#endif +#ifndef __riscv64_ilp32d__ +#undef __riscv64_ilp32d__ +#endif +#ifndef __riscv64_lp64__ +#undef __riscv64_lp64__ +#endif +#ifndef __riscv64_lp64f__ +#undef __riscv64_lp64f__ +#endif +#ifndef __riscv64_lp64d__ +#undef __riscv64_lp64d__ +#endif +#ifndef __s390__ +#undef __s390__ +#endif +#ifndef __s390x__ +#undef __s390x__ +#endif +#ifndef __sh__ +#undef __sh__ +#endif +#ifndef __sparc__ +#undef __sparc__ +#endif +#ifndef __sparc64__ +#undef __sparc64__ +#endif +]) + +]) diff --git a/config/install-defs.sh b/config/install-defs.sh new file mode 100644 index 0000000..f61f924 --- /dev/null +++ b/config/install-defs.sh @@ -0,0 +1,17 @@ +#! /bin/sh +# AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +sedcmd= +nl=' +' +eval `egrep '^SED=' ${top_builddir}/config/shdefs` + +for v in srcdir top_srcdir top_builddir +do + eval val=\"\${$v}\" + val=`cd ${val} >/dev/null && pwd` + sedcmd="${sedcmd}/: .{$v=/s@=[^}]*}@=$val}@$nl" +done + +${SED} "$sedcmd" $1 > ./.defs$$ +mv .defs$$ defs +chmod +x ${srcdir}/*.test >/dev/null 2>&1 diff --git a/config/install-sh b/config/install-sh new file mode 100755 index 0000000..8175c64 --- /dev/null +++ b/config/install-sh @@ -0,0 +1,518 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2018-03-11.20; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# 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. + +tab=' ' +nl=' +' +IFS=" $tab$nl" + +# Set DOITPROG to "echo" to test this script. + +doit=${DOITPROG-} +doit_exec=${doit:-exec} + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +is_target_a_directory=possibly + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) + is_target_a_directory=always + dst_arg=$2 + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + shift;; + + -T) is_target_a_directory=never;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +# We allow the use of options -d and -T together, by making -d +# take the precedence; this is for compatibility with GNU install. + +if test -n "$dir_arg"; then + if test -n "$dst_arg"; then + echo "$0: target directory not allowed when installing a directory." >&2 + exit 1 + fi +fi + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call 'install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + if test $# -gt 1 || test "$is_target_a_directory" = always; then + if test ! -d "$dst_arg"; then + echo "$0: $dst_arg: Is not a directory." >&2 + exit 1 + fi + fi +fi + +if test -z "$dir_arg"; then + do_exit='(exit $ret); exit $ret' + trap "ret=129; $do_exit" 1 + trap "ret=130; $do_exit" 2 + trap "ret=141; $do_exit" 13 + trap "ret=143; $do_exit" 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names problematic for 'test' and other utilities. + case $src in + -* | [=\(\)!]) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + dst=$dst_arg + + # If destination is a directory, append the input filename. + if test -d "$dst"; then + if test "$is_target_a_directory" = never; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dstbase=`basename "$src"` + case $dst in + */) dst=$dst$dstbase;; + *) dst=$dst/$dstbase;; + esac + dstdir_status=0 + else + dstdir=`dirname "$dst"` + test -d "$dstdir" + dstdir_status=$? + fi + fi + + case $dstdir in + */) dstdirslash=$dstdir;; + *) dstdirslash=$dstdir/;; + esac + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + # Note that $RANDOM variable is not portable (e.g. dash); Use it + # here however when possible just to lower collision chance. + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + + trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0 + + # Because "mkdir -p" follows existing symlinks and we likely work + # directly in world-writeable /tmp, make sure that the '$tmpdir' + # directory is successfully created first before we actually test + # 'mkdir -p' feature. + if (umask $mkdir_umask && + $mkdirprog $mkdir_mode "$tmpdir" && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + test_tmpdir="$tmpdir/a" + ls_ld_tmpdir=`ls -ld "$test_tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + [-=\(\)!]*) prefix='./';; + *) prefix='';; + esac + + oIFS=$IFS + IFS=/ + set -f + set fnord $dstdir + shift + set +f + IFS=$oIFS + + prefixes= + + for d + do + test X"$d" = X && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=${dstdirslash}_inst.$$_ + rmtmp=${dstdirslash}_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # 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 $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + set +f && + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/config/lib-ld.m4 b/config/lib-ld.m4 new file mode 100644 index 0000000..1244ff8 --- /dev/null +++ b/config/lib-ld.m4 @@ -0,0 +1,168 @@ +# lib-ld.m4 serial 9 +dnl Copyright (C) 1996-2003, 2009-2018 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 Subroutines of libtool.m4, +dnl with replacements s/_*LT_PATH/AC_LIB_PROG/ and s/lt_/acl_/ to avoid +dnl collision with libtool.m4. + +dnl From libtool-2.4. Sets the variable with_gnu_ld to yes or no. +AC_DEFUN([AC_LIB_PROG_LD_GNU], +[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], [acl_cv_prog_gnu_ld], +[# I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 </dev/null` in +*GNU* | *'with BFD'*) + acl_cv_prog_gnu_ld=yes + ;; +*) + acl_cv_prog_gnu_ld=no + ;; +esac]) +with_gnu_ld=$acl_cv_prog_gnu_ld +]) + +dnl From libtool-2.4. Sets the variable LD. +AC_DEFUN([AC_LIB_PROG_LD], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl + +AC_ARG_WITH([gnu-ld], + [AS_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld [default=no]])], + [test "$withval" = no || with_gnu_ld=yes], + [with_gnu_ld=no])dnl + +# Prepare PATH_SEPARATOR. +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which + # contains only /bin. Note that ksh looks also at the FPATH variable, + # so we have to set that as well for the test. + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ + && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ + || PATH_SEPARATOR=';' + } +fi + +if test -n "$LD"; then + AC_MSG_CHECKING([for ld]) +elif test "$GCC" = yes; then + AC_MSG_CHECKING([for ld used by $CC]) +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +if test -n "$LD"; then + # Let the user override the test with a path. + : +else + AC_CACHE_VAL([acl_cv_path_LD], + [ + acl_cv_path_LD= # Final result of this test + ac_prog=ld # Program to search in $PATH + if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + acl_output=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + acl_output=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $acl_output in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + acl_output=`echo "$acl_output" | sed 's%\\\\%/%g'` + while echo "$acl_output" | grep "$re_direlt" > /dev/null 2>&1; do + acl_output=`echo $acl_output | sed "s%$re_direlt%/%"` + done + # Got the pathname. No search in PATH is needed. + acl_cv_path_LD="$acl_output" + ac_prog= + ;; + "") + # If it fails, then pretend we aren't using GCC. + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac + fi + if test -n "$ac_prog"; then + # Search for $ac_prog in $PATH. + acl_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$acl_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + acl_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$acl_cv_path_LD" -v 2>&1 </dev/null` in + *GNU* | *'with BFD'*) + test "$with_gnu_ld" != no && break + ;; + *) + test "$with_gnu_ld" != yes && break + ;; + esac + fi + done + IFS="$acl_save_ifs" + fi + case $host in + *-*-aix*) + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __powerpc64__ || defined _ARCH_PPC64 + int ok; + #else + error fail + #endif + ]])], + [# The compiler produces 64-bit code. Add option '-b64' so that the + # linker groks 64-bit object files. + case "$acl_cv_path_LD " in + *" -b64 "*) ;; + *) acl_cv_path_LD="$acl_cv_path_LD -b64" ;; + esac + ], []) + ;; + sparc64-*-netbsd*) + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#if defined __sparcv9 || defined __arch64__ + int ok; + #else + error fail + #endif + ]])], + [], + [# The compiler produces 32-bit code. Add option '-m elf32_sparc' + # so that the linker groks 32-bit object files. + case "$acl_cv_path_LD " in + *" -m elf32_sparc "*) ;; + *) acl_cv_path_LD="$acl_cv_path_LD -m elf32_sparc" ;; + esac + ]) + ;; + esac + ]) + LD="$acl_cv_path_LD" +fi +if test -n "$LD"; then + AC_MSG_RESULT([$LD]) +else + AC_MSG_RESULT([no]) + AC_MSG_ERROR([no acceptable ld found in \$PATH]) +fi +AC_LIB_PROG_LD_GNU +]) diff --git a/config/lib-link.m4 b/config/lib-link.m4 new file mode 100644 index 0000000..df77db9 --- /dev/null +++ b/config/lib-link.m4 @@ -0,0 +1,777 @@ +# lib-link.m4 serial 26 (gettext-0.18.2) +dnl Copyright (C) 2001-2018 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 From Bruno Haible. + +AC_PREREQ([2.54]) + +dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and +dnl the libraries corresponding to explicit and implicit dependencies. +dnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and +dnl augments the CPPFLAGS variable. +dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname +dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem. +AC_DEFUN([AC_LIB_LINKFLAGS], +[ + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + pushdef([Name],[m4_translit([$1],[./+-], [____])]) + pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) + AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [ + AC_LIB_LINKFLAGS_BODY([$1], [$2]) + ac_cv_lib[]Name[]_libs="$LIB[]NAME" + ac_cv_lib[]Name[]_ltlibs="$LTLIB[]NAME" + ac_cv_lib[]Name[]_cppflags="$INC[]NAME" + ac_cv_lib[]Name[]_prefix="$LIB[]NAME[]_PREFIX" + ]) + LIB[]NAME="$ac_cv_lib[]Name[]_libs" + LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs" + INC[]NAME="$ac_cv_lib[]Name[]_cppflags" + LIB[]NAME[]_PREFIX="$ac_cv_lib[]Name[]_prefix" + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) + AC_SUBST([LIB]NAME) + AC_SUBST([LTLIB]NAME) + AC_SUBST([LIB]NAME[_PREFIX]) + dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the + dnl results of this search when this library appears as a dependency. + HAVE_LIB[]NAME=yes + popdef([NAME]) + popdef([Name]) +]) + +dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode, [missing-message]) +dnl searches for libname and the libraries corresponding to explicit and +dnl implicit dependencies, together with the specified include files and +dnl the ability to compile and link the specified testcode. The missing-message +dnl defaults to 'no' and may contain additional hints for the user. +dnl If found, it sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME} +dnl and LTLIB${NAME} variables and augments the CPPFLAGS variable, and +dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs +dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty. +dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname +dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem. +AC_DEFUN([AC_LIB_HAVE_LINKFLAGS], +[ + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + AC_REQUIRE([AC_LIB_RPATH]) + pushdef([Name],[m4_translit([$1],[./+-], [____])]) + pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) + + dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME + dnl accordingly. + AC_LIB_LINKFLAGS_BODY([$1], [$2]) + + dnl Add $INC[]NAME to CPPFLAGS before performing the following checks, + dnl because if the user has installed lib[]Name and not disabled its use + dnl via --without-lib[]Name-prefix, he wants to use it. + ac_save_CPPFLAGS="$CPPFLAGS" + AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME) + + AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [ + ac_save_LIBS="$LIBS" + dnl If $LIB[]NAME contains some -l options, add it to the end of LIBS, + dnl because these -l options might require -L options that are present in + dnl LIBS. -l options benefit only from the -L options listed before it. + dnl Otherwise, add it to the front of LIBS, because it may be a static + dnl library that depends on another static library that is present in LIBS. + dnl Static libraries benefit only from the static libraries listed after + dnl it. + case " $LIB[]NAME" in + *" -l"*) LIBS="$LIBS $LIB[]NAME" ;; + *) LIBS="$LIB[]NAME $LIBS" ;; + esac + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[$3]], [[$4]])], + [ac_cv_lib[]Name=yes], + [ac_cv_lib[]Name='m4_if([$5], [], [no], [[$5]])']) + LIBS="$ac_save_LIBS" + ]) + if test "$ac_cv_lib[]Name" = yes; then + HAVE_LIB[]NAME=yes + AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the lib][$1 library.]) + AC_MSG_CHECKING([how to link with lib[]$1]) + AC_MSG_RESULT([$LIB[]NAME]) + else + HAVE_LIB[]NAME=no + dnl If $LIB[]NAME didn't lead to a usable library, we don't need + dnl $INC[]NAME either. + CPPFLAGS="$ac_save_CPPFLAGS" + LIB[]NAME= + LTLIB[]NAME= + LIB[]NAME[]_PREFIX= + fi + AC_SUBST([HAVE_LIB]NAME) + AC_SUBST([LIB]NAME) + AC_SUBST([LTLIB]NAME) + AC_SUBST([LIB]NAME[_PREFIX]) + popdef([NAME]) + popdef([Name]) +]) + +dnl Determine the platform dependent parameters needed to use rpath: +dnl acl_libext, +dnl acl_shlibext, +dnl acl_libname_spec, +dnl acl_library_names_spec, +dnl acl_hardcode_libdir_flag_spec, +dnl acl_hardcode_libdir_separator, +dnl acl_hardcode_direct, +dnl acl_hardcode_minus_L. +AC_DEFUN([AC_LIB_RPATH], +[ + dnl Tell automake >= 1.10 to complain if config.rpath is missing. + m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([config.rpath])]) + AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS + AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld + AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host + AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir + AC_CACHE_CHECK([for shared library run path origin], [acl_cv_rpath], [ + CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ + ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh + . ./conftest.sh + rm -f ./conftest.sh + acl_cv_rpath=done + ]) + wl="$acl_cv_wl" + acl_libext="$acl_cv_libext" + acl_shlibext="$acl_cv_shlibext" + acl_libname_spec="$acl_cv_libname_spec" + acl_library_names_spec="$acl_cv_library_names_spec" + acl_hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" + acl_hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" + acl_hardcode_direct="$acl_cv_hardcode_direct" + acl_hardcode_minus_L="$acl_cv_hardcode_minus_L" + dnl Determine whether the user wants rpath handling at all. + AC_ARG_ENABLE([rpath], + [ --disable-rpath do not hardcode runtime library paths], + :, enable_rpath=yes) +]) + +dnl AC_LIB_FROMPACKAGE(name, package) +dnl declares that libname comes from the given package. The configure file +dnl will then not have a --with-libname-prefix option but a +dnl --with-package-prefix option. Several libraries can come from the same +dnl package. This declaration must occur before an AC_LIB_LINKFLAGS or similar +dnl macro call that searches for libname. +AC_DEFUN([AC_LIB_FROMPACKAGE], +[ + pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) + define([acl_frompackage_]NAME, [$2]) + popdef([NAME]) + pushdef([PACK],[$2]) + pushdef([PACKUP],[m4_translit(PACK,[abcdefghijklmnopqrstuvwxyz./+-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) + define([acl_libsinpackage_]PACKUP, + m4_ifdef([acl_libsinpackage_]PACKUP, [m4_defn([acl_libsinpackage_]PACKUP)[, ]],)[lib$1]) + popdef([PACKUP]) + popdef([PACK]) +]) + +dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and +dnl the libraries corresponding to explicit and implicit dependencies. +dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables. +dnl Also, sets the LIB${NAME}_PREFIX variable to nonempty if libname was found +dnl in ${LIB${NAME}_PREFIX}/$acl_libdirstem. +AC_DEFUN([AC_LIB_LINKFLAGS_BODY], +[ + AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) + pushdef([NAME],[m4_translit([$1],[abcdefghijklmnopqrstuvwxyz./+-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) + pushdef([PACK],[m4_ifdef([acl_frompackage_]NAME, [acl_frompackage_]NAME, lib[$1])]) + pushdef([PACKUP],[m4_translit(PACK,[abcdefghijklmnopqrstuvwxyz./+-], + [ABCDEFGHIJKLMNOPQRSTUVWXYZ____])]) + pushdef([PACKLIBS],[m4_ifdef([acl_frompackage_]NAME, [acl_libsinpackage_]PACKUP, lib[$1])]) + dnl Autoconf >= 2.61 supports dots in --with options. + pushdef([P_A_C_K],[m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.61]),[-1],[m4_translit(PACK,[.],[_])],PACK)]) + dnl By default, look in $includedir and $libdir. + use_additional=yes + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + AC_ARG_WITH(P_A_C_K[-prefix], +[[ --with-]]P_A_C_K[[-prefix[=DIR] search for ]PACKLIBS[ in DIR/include and DIR/lib + --without-]]P_A_C_K[[-prefix don't search for ]PACKLIBS[ in includedir and libdir]], +[ + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + else + additional_includedir="$withval/include" + additional_libdir="$withval/$acl_libdirstem" + if test "$acl_libdirstem2" != "$acl_libdirstem" \ + && test ! -d "$withval/$acl_libdirstem"; then + additional_libdir="$withval/$acl_libdirstem2" + fi + fi + fi +]) + dnl Search the library and its dependencies in $additional_libdir and + dnl $LDFLAGS. Using breadth-first-seach. + LIB[]NAME= + LTLIB[]NAME= + INC[]NAME= + LIB[]NAME[]_PREFIX= + dnl HAVE_LIB${NAME} is an indicator that LIB${NAME}, LTLIB${NAME} have been + dnl computed. So it has to be reset here. + HAVE_LIB[]NAME= + rpathdirs= + ltrpathdirs= + names_already_handled= + names_next_round='$1 $2' + while test -n "$names_next_round"; do + names_this_round="$names_next_round" + names_next_round= + for name in $names_this_round; do + already_handled= + for n in $names_already_handled; do + if test "$n" = "$name"; then + already_handled=yes + break + fi + done + if test -z "$already_handled"; then + names_already_handled="$names_already_handled $name" + dnl See if it was already located by an earlier AC_LIB_LINKFLAGS + dnl or AC_LIB_HAVE_LINKFLAGS call. + uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./+-|ABCDEFGHIJKLMNOPQRSTUVWXYZ____|'` + eval value=\"\$HAVE_LIB$uppername\" + if test -n "$value"; then + if test "$value" = yes; then + eval value=\"\$LIB$uppername\" + test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value" + eval value=\"\$LTLIB$uppername\" + test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value" + else + dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined + dnl that this library doesn't exist. So just drop it. + : + fi + else + dnl Search the library lib$name in $additional_libdir and $LDFLAGS + dnl and the already constructed $LIBNAME/$LTLIBNAME. + found_dir= + found_la= + found_so= + found_a= + eval libname=\"$acl_libname_spec\" # typically: libname=lib$name + if test -n "$acl_shlibext"; then + shrext=".$acl_shlibext" # typically: shrext=.so + else + shrext= + fi + if test $use_additional = yes; then + dir="$additional_libdir" + dnl The same code as in the loop below: + dnl First look for a shared library. + if test -n "$acl_shlibext"; then + if test -f "$dir/$libname$shrext"; then + found_dir="$dir" + found_so="$dir/$libname$shrext" + else + if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then + ver=`(cd "$dir" && \ + for f in "$libname$shrext".*; do echo "$f"; done \ + | sed -e "s,^$libname$shrext\\\\.,," \ + | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ + | sed 1q ) 2>/dev/null` + if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then + found_dir="$dir" + found_so="$dir/$libname$shrext.$ver" + fi + else + eval library_names=\"$acl_library_names_spec\" + for f in $library_names; do + if test -f "$dir/$f"; then + found_dir="$dir" + found_so="$dir/$f" + break + fi + done + fi + fi + fi + dnl Then look for a static library. + if test "X$found_dir" = "X"; then + if test -f "$dir/$libname.$acl_libext"; then + found_dir="$dir" + found_a="$dir/$libname.$acl_libext" + fi + fi + if test "X$found_dir" != "X"; then + if test -f "$dir/$libname.la"; then + found_la="$dir/$libname.la" + fi + fi + fi + if test "X$found_dir" = "X"; then + for x in $LDFLAGS $LTLIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + case "$x" in + -L*) + dir=`echo "X$x" | sed -e 's/^X-L//'` + dnl First look for a shared library. + if test -n "$acl_shlibext"; then + if test -f "$dir/$libname$shrext"; then + found_dir="$dir" + found_so="$dir/$libname$shrext" + else + if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then + ver=`(cd "$dir" && \ + for f in "$libname$shrext".*; do echo "$f"; done \ + | sed -e "s,^$libname$shrext\\\\.,," \ + | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \ + | sed 1q ) 2>/dev/null` + if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then + found_dir="$dir" + found_so="$dir/$libname$shrext.$ver" + fi + else + eval library_names=\"$acl_library_names_spec\" + for f in $library_names; do + if test -f "$dir/$f"; then + found_dir="$dir" + found_so="$dir/$f" + break + fi + done + fi + fi + fi + dnl Then look for a static library. + if test "X$found_dir" = "X"; then + if test -f "$dir/$libname.$acl_libext"; then + found_dir="$dir" + found_a="$dir/$libname.$acl_libext" + fi + fi + if test "X$found_dir" != "X"; then + if test -f "$dir/$libname.la"; then + found_la="$dir/$libname.la" + fi + fi + ;; + esac + if test "X$found_dir" != "X"; then + break + fi + done + fi + if test "X$found_dir" != "X"; then + dnl Found the library. + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name" + if test "X$found_so" != "X"; then + dnl Linking with a shared library. We attempt to hardcode its + dnl directory into the executable's runpath, unless it's the + dnl standard /usr/lib. + if test "$enable_rpath" = no \ + || test "X$found_dir" = "X/usr/$acl_libdirstem" \ + || test "X$found_dir" = "X/usr/$acl_libdirstem2"; then + dnl No hardcoding is needed. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + dnl Use an explicit option to hardcode DIR into the resulting + dnl binary. + dnl Potentially add DIR to ltrpathdirs. + dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $found_dir" + fi + dnl The hardcoding into $LIBNAME is system dependent. + if test "$acl_hardcode_direct" = yes; then + dnl Using DIR/libNAME.so during linking hardcodes DIR into the + dnl resulting binary. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then + dnl Use an explicit option to hardcode DIR into the resulting + dnl binary. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + dnl Potentially add DIR to rpathdirs. + dnl The rpathdirs will be appended to $LIBNAME at the end. + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $found_dir" + fi + else + dnl Rely on "-L$found_dir". + dnl But don't add it if it's already contained in the LDFLAGS + dnl or the already constructed $LIBNAME + haveit= + for x in $LDFLAGS $LIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$found_dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir" + fi + if test "$acl_hardcode_minus_L" != no; then + dnl FIXME: Not sure whether we should use + dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" + dnl here. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so" + else + dnl We cannot use $acl_hardcode_runpath_var and LD_RUN_PATH + dnl here, because this doesn't fit in flags passed to the + dnl compiler. So give up. No hardcoding. This affects only + dnl very old systems. + dnl FIXME: Not sure whether we should use + dnl "-L$found_dir -l$name" or "-L$found_dir $found_so" + dnl here. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" + fi + fi + fi + fi + else + if test "X$found_a" != "X"; then + dnl Linking with a static library. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a" + else + dnl We shouldn't come here, but anyway it's good to have a + dnl fallback. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name" + fi + fi + dnl Assume the include files are nearby. + additional_includedir= + case "$found_dir" in + */$acl_libdirstem | */$acl_libdirstem/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'` + if test "$name" = '$1'; then + LIB[]NAME[]_PREFIX="$basedir" + fi + additional_includedir="$basedir/include" + ;; + */$acl_libdirstem2 | */$acl_libdirstem2/) + basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem2/"'*$,,'` + if test "$name" = '$1'; then + LIB[]NAME[]_PREFIX="$basedir" + fi + additional_includedir="$basedir/include" + ;; + esac + if test "X$additional_includedir" != "X"; then + dnl Potentially add $additional_includedir to $INCNAME. + dnl But don't add it + dnl 1. if it's the standard /usr/include, + dnl 2. if it's /usr/local/include and we are using GCC on Linux, + dnl 3. if it's already present in $CPPFLAGS or the already + dnl constructed $INCNAME, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_includedir" != "X/usr/include"; then + haveit= + if test "X$additional_includedir" = "X/usr/local/include"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + for x in $CPPFLAGS $INC[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-I$additional_includedir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_includedir"; then + dnl Really add $additional_includedir to $INCNAME. + INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir" + fi + fi + fi + fi + fi + dnl Look for dependencies. + if test -n "$found_la"; then + dnl Read the .la file. It defines the variables + dnl dlname, library_names, old_library, dependency_libs, current, + dnl age, revision, installed, dlopen, dlpreopen, libdir. + save_libdir="$libdir" + case "$found_la" in + */* | *\\*) . "$found_la" ;; + *) . "./$found_la" ;; + esac + libdir="$save_libdir" + dnl We use only dependency_libs. + for dep in $dependency_libs; do + case "$dep" in + -L*) + additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'` + dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME. + dnl But don't add it + dnl 1. if it's the standard /usr/lib, + dnl 2. if it's /usr/local/lib and we are using GCC on Linux, + dnl 3. if it's already present in $LDFLAGS or the already + dnl constructed $LIBNAME, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_libdir" != "X/usr/$acl_libdirstem" \ + && test "X$additional_libdir" != "X/usr/$acl_libdirstem2"; then + haveit= + if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem" \ + || test "X$additional_libdir" = "X/usr/local/$acl_libdirstem2"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + haveit= + for x in $LDFLAGS $LIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + dnl Really add $additional_libdir to $LIBNAME. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir" + fi + fi + haveit= + for x in $LDFLAGS $LTLIB[]NAME; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + dnl Really add $additional_libdir to $LTLIBNAME. + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir" + fi + fi + fi + fi + ;; + -R*) + dir=`echo "X$dep" | sed -e 's/^X-R//'` + if test "$enable_rpath" != no; then + dnl Potentially add DIR to rpathdirs. + dnl The rpathdirs will be appended to $LIBNAME at the end. + haveit= + for x in $rpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + rpathdirs="$rpathdirs $dir" + fi + dnl Potentially add DIR to ltrpathdirs. + dnl The ltrpathdirs will be appended to $LTLIBNAME at the end. + haveit= + for x in $ltrpathdirs; do + if test "X$x" = "X$dir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + ltrpathdirs="$ltrpathdirs $dir" + fi + fi + ;; + -l*) + dnl Handle this in the next round. + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'` + ;; + *.la) + dnl Handle this in the next round. Throw away the .la's + dnl directory; it is already contained in a preceding -L + dnl option. + names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'` + ;; + *) + dnl Most likely an immediate library name. + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep" + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep" + ;; + esac + done + fi + else + dnl Didn't find the library; assume it is in the system directories + dnl known to the linker and runtime loader. (All the system + dnl directories known to the linker should also be known to the + dnl runtime loader, otherwise the system is severely misconfigured.) + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name" + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name" + fi + fi + fi + done + done + if test "X$rpathdirs" != "X"; then + if test -n "$acl_hardcode_libdir_separator"; then + dnl Weird platform: only the last -rpath option counts, the user must + dnl pass all path elements in one option. We can arrange that for a + dnl single library, but not when more than one $LIBNAMEs are used. + alldirs= + for found_dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir" + done + dnl Note: acl_hardcode_libdir_flag_spec uses $libdir and $wl. + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" + else + dnl The -rpath options are cumulative. + for found_dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$found_dir" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag" + done + fi + fi + if test "X$ltrpathdirs" != "X"; then + dnl When using libtool, the option that works for both libraries and + dnl executables is -R. The -R options are cumulative. + for found_dir in $ltrpathdirs; do + LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir" + done + fi + popdef([P_A_C_K]) + popdef([PACKLIBS]) + popdef([PACKUP]) + popdef([PACK]) + popdef([NAME]) +]) + +dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR, +dnl unless already present in VAR. +dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes +dnl contains two or three consecutive elements that belong together. +AC_DEFUN([AC_LIB_APPENDTOVAR], +[ + for element in [$2]; do + haveit= + for x in $[$1]; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X$element"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + [$1]="${[$1]}${[$1]:+ }$element" + fi + done +]) + +dnl For those cases where a variable contains several -L and -l options +dnl referring to unknown libraries and directories, this macro determines the +dnl necessary additional linker options for the runtime path. +dnl AC_LIB_LINKFLAGS_FROM_LIBS([LDADDVAR], [LIBSVALUE], [USE-LIBTOOL]) +dnl sets LDADDVAR to linker options needed together with LIBSVALUE. +dnl If USE-LIBTOOL evaluates to non-empty, linking with libtool is assumed, +dnl otherwise linking without libtool is assumed. +AC_DEFUN([AC_LIB_LINKFLAGS_FROM_LIBS], +[ + AC_REQUIRE([AC_LIB_RPATH]) + AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) + $1= + if test "$enable_rpath" != no; then + if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then + dnl Use an explicit option to hardcode directories into the resulting + dnl binary. + rpathdirs= + next= + for opt in $2; do + if test -n "$next"; then + dir="$next" + dnl No need to hardcode the standard /usr/lib. + if test "X$dir" != "X/usr/$acl_libdirstem" \ + && test "X$dir" != "X/usr/$acl_libdirstem2"; then + rpathdirs="$rpathdirs $dir" + fi + next= + else + case $opt in + -L) next=yes ;; + -L*) dir=`echo "X$opt" | sed -e 's,^X-L,,'` + dnl No need to hardcode the standard /usr/lib. + if test "X$dir" != "X/usr/$acl_libdirstem" \ + && test "X$dir" != "X/usr/$acl_libdirstem2"; then + rpathdirs="$rpathdirs $dir" + fi + next= ;; + *) next= ;; + esac + fi + done + if test "X$rpathdirs" != "X"; then + if test -n ""$3""; then + dnl libtool is used for linking. Use -R options. + for dir in $rpathdirs; do + $1="${$1}${$1:+ }-R$dir" + done + else + dnl The linker is used for linking directly. + if test -n "$acl_hardcode_libdir_separator"; then + dnl Weird platform: only the last -rpath option counts, the user + dnl must pass all path elements in one option. + alldirs= + for dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$dir" + done + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + $1="$flag" + else + dnl The -rpath options are cumulative. + for dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$dir" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + $1="${$1}${$1:+ }$flag" + done + fi + fi + fi + fi + fi + AC_SUBST([$1]) +]) diff --git a/config/lib-prefix.m4 b/config/lib-prefix.m4 new file mode 100644 index 0000000..16b26fb --- /dev/null +++ b/config/lib-prefix.m4 @@ -0,0 +1,255 @@ +# lib-prefix.m4 serial 11 +dnl Copyright (C) 2001-2005, 2008-2018 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 From Bruno Haible. + +dnl AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and +dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't +dnl require excessive bracketing. +ifdef([AC_HELP_STRING], +[AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])], +[AC_DEFUN([AC_][LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])]) + +dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed +dnl to access previously installed libraries. The basic assumption is that +dnl a user will want packages to use other packages he previously installed +dnl with the same --prefix option. +dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate +dnl libraries, but is otherwise very convenient. +AC_DEFUN([AC_LIB_PREFIX], +[ + AC_BEFORE([$0], [AC_LIB_LINKFLAGS]) + AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([AC_LIB_PREPARE_MULTILIB]) + AC_REQUIRE([AC_LIB_PREPARE_PREFIX]) + dnl By default, look in $includedir and $libdir. + use_additional=yes + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + AC_LIB_ARG_WITH([lib-prefix], +[ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib + --without-lib-prefix don't search for libraries in includedir and libdir], +[ + if test "X$withval" = "Xno"; then + use_additional=no + else + if test "X$withval" = "X"; then + AC_LIB_WITH_FINAL_PREFIX([ + eval additional_includedir=\"$includedir\" + eval additional_libdir=\"$libdir\" + ]) + else + additional_includedir="$withval/include" + additional_libdir="$withval/$acl_libdirstem" + fi + fi +]) + if test $use_additional = yes; then + dnl Potentially add $additional_includedir to $CPPFLAGS. + dnl But don't add it + dnl 1. if it's the standard /usr/include, + dnl 2. if it's already present in $CPPFLAGS, + dnl 3. if it's /usr/local/include and we are using GCC on Linux, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_includedir" != "X/usr/include"; then + haveit= + for x in $CPPFLAGS; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-I$additional_includedir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test "X$additional_includedir" = "X/usr/local/include"; then + if test -n "$GCC"; then + case $host_os in + linux* | gnu* | k*bsd*-gnu) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + if test -d "$additional_includedir"; then + dnl Really add $additional_includedir to $CPPFLAGS. + CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir" + fi + fi + fi + fi + dnl Potentially add $additional_libdir to $LDFLAGS. + dnl But don't add it + dnl 1. if it's the standard /usr/lib, + dnl 2. if it's already present in $LDFLAGS, + dnl 3. if it's /usr/local/lib and we are using GCC on Linux, + dnl 4. if it doesn't exist as a directory. + if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then + haveit= + for x in $LDFLAGS; do + AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"]) + if test "X$x" = "X-L$additional_libdir"; then + haveit=yes + break + fi + done + if test -z "$haveit"; then + if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; then + if test -n "$GCC"; then + case $host_os in + linux*) haveit=yes;; + esac + fi + fi + if test -z "$haveit"; then + if test -d "$additional_libdir"; then + dnl Really add $additional_libdir to $LDFLAGS. + LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir" + fi + fi + fi + fi + fi +]) + +dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix, +dnl acl_final_exec_prefix, containing the values to which $prefix and +dnl $exec_prefix will expand at the end of the configure script. +AC_DEFUN([AC_LIB_PREPARE_PREFIX], +[ + dnl Unfortunately, prefix and exec_prefix get only finally determined + dnl at the end of configure. + if test "X$prefix" = "XNONE"; then + acl_final_prefix="$ac_default_prefix" + else + acl_final_prefix="$prefix" + fi + if test "X$exec_prefix" = "XNONE"; then + acl_final_exec_prefix='${prefix}' + else + acl_final_exec_prefix="$exec_prefix" + fi + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + eval acl_final_exec_prefix=\"$acl_final_exec_prefix\" + prefix="$acl_save_prefix" +]) + +dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the +dnl variables prefix and exec_prefix bound to the values they will have +dnl at the end of the configure script. +AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX], +[ + acl_save_prefix="$prefix" + prefix="$acl_final_prefix" + acl_save_exec_prefix="$exec_prefix" + exec_prefix="$acl_final_exec_prefix" + $1 + exec_prefix="$acl_save_exec_prefix" + prefix="$acl_save_prefix" +]) + +dnl AC_LIB_PREPARE_MULTILIB creates +dnl - a variable acl_libdirstem, containing the basename of the libdir, either +dnl "lib" or "lib64" or "lib/64", +dnl - a variable acl_libdirstem2, as a secondary possible value for +dnl acl_libdirstem, either the same as acl_libdirstem or "lib/sparcv9" or +dnl "lib/amd64". +AC_DEFUN([AC_LIB_PREPARE_MULTILIB], +[ + dnl There is no formal standard regarding lib and lib64. + dnl On glibc systems, the current practice is that on a system supporting + dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under + dnl $prefix/lib64 and 32-bit libraries go under $prefix/lib. We determine + dnl the compiler's default mode by looking at the compiler's library search + dnl path. If at least one of its elements ends in /lib64 or points to a + dnl directory whose absolute pathname ends in /lib64, we assume a 64-bit ABI. + dnl Otherwise we use the default, namely "lib". + dnl On Solaris systems, the current practice is that on a system supporting + dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under + dnl $prefix/lib/64 (which is a symlink to either $prefix/lib/sparcv9 or + dnl $prefix/lib/amd64) and 32-bit libraries go under $prefix/lib. + AC_REQUIRE([AC_CANONICAL_HOST]) + AC_REQUIRE([gl_HOST_CPU_C_ABI]) + dnl Allow the user to override the result by setting acl_cv_libdirstems. + AC_CACHE_CHECK([for the common suffixes of directories in the library search path], + [acl_cv_libdirstems], + [acl_libdirstem=lib + acl_libdirstem2= + case "$host_os" in + solaris*) + dnl See Solaris 10 Software Developer Collection > Solaris 64-bit Developer's Guide > The Development Environment + dnl <https://docs.oracle.com/cd/E19253-01/816-5138/dev-env/index.html>. + dnl "Portable Makefiles should refer to any library directories using the 64 symbolic link." + dnl But we want to recognize the sparcv9 or amd64 subdirectory also if the + dnl symlink is missing, so we set acl_libdirstem2 too. + AC_CACHE_CHECK([for 64-bit host], [gl_cv_solaris_64bit], + [AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[#ifdef _LP64 + int ok; + #else + error fail + #endif + ]])], + [gl_cv_solaris_64bit=yes], + [gl_cv_solaris_64bit=no]) + ]) + if test $gl_cv_solaris_64bit = yes; then + acl_libdirstem=lib/64 + case "$host_cpu" in + sparc*) acl_libdirstem2=lib/sparcv9 ;; + i*86 | x86_64) acl_libdirstem2=lib/amd64 ;; + esac + fi + ;; + *) + dnl If $CC generates code for a 32-bit ABI, the libraries are + dnl surely under $prefix/lib, not $prefix/lib64. + case "$gl_cv_host_cpu_c_abi" in + i386 | arm | armhf | arm64-ilp32 | hppa | ia64-ilp32 | mips | mipsn32 | powerpc | s390 | sparc) + ;; + *) # x86_64 | arm64 | hppa64 | ia64 | mips64 | powerpc64* | s390x | sparc64 | ... + dnl The result is a property of the system. However, non-system + dnl compilers sometimes have odd library search paths. Therefore + dnl prefer asking /usr/bin/gcc, if available, rather than $CC. + searchpath=`(if test -f /usr/bin/gcc \ + && LC_ALL=C /usr/bin/gcc -print-search-dirs >/dev/null 2>/dev/null; then \ + LC_ALL=C /usr/bin/gcc -print-search-dirs; \ + else \ + LC_ALL=C $CC -print-search-dirs; \ + fi) 2>/dev/null \ + | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'` + if test -n "$searchpath"; then + acl_save_IFS="${IFS= }"; IFS=":" + for searchdir in $searchpath; do + if test -d "$searchdir"; then + case "$searchdir" in + */lib64/ | */lib64 ) acl_libdirstem=lib64 ;; + */../ | */.. ) + # Better ignore directories of this form. They are misleading. + ;; + *) searchdir=`cd "$searchdir" && pwd` + case "$searchdir" in + */lib64 ) acl_libdirstem=lib64 ;; + esac ;; + esac + fi + done + IFS="$acl_save_IFS" + fi + ;; + esac + ;; + esac + test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem" + acl_cv_libdirstems="$acl_libdirstem,$acl_libdirstem2" + ]) + # Decompose acl_cv_libdirstems into acl_libdirstem and acl_libdirstem2. + acl_libdirstem=`echo "$acl_cv_libdirstems" | sed -e 's/,.*//'` + acl_libdirstem2=`echo "$acl_cv_libdirstems" | sed -e '/,/s/.*,//'` +]) diff --git a/config/libopts.m4 b/config/libopts.m4 new file mode 100644 index 0000000..e2bf50e --- /dev/null +++ b/config/libopts.m4 @@ -0,0 +1,448 @@ + +dnl do always before generated macros: +dnl +AC_DEFUN([INVOKE_LIBOPTS_MACROS_FIRST],[ + AC_REQUIRE([AC_HEADER_STDC]) + AC_HEADER_DIRENT + + # ================= + # AC_CHECK_HEADERS + # ================= + AC_CHECK_HEADERS([ \ + sys/mman.h sys/param.h sys/poll.h sys/procset.h \ + sys/select.h sys/socket.h sys/stropts.h sys/time.h \ + sys/un.h sys/wait.h dlfcn.h errno.h \ + fcntl.h libgen.h libintl.h memory.h \ + netinet/in.h setjmp.h stdbool.h sysexits.h \ + unistd.h utime.h]) + + AC_CHECK_HEADERS([stdarg.h varargs.h], + [lo_have_arg_hdr=true;break], + [lo_have_arg_hdr=false]) + + AC_CHECK_HEADERS([string.h strings.h], + [lo_have_str_hdr=true;break], + [lo_have_str_hdr=false]) + + AC_CHECK_HEADERS([limits.h sys/limits.h values.h], + [lo_have_lim_hdr=true;break], + [lo_have_lim_hdr=false]) + + AC_CHECK_HEADERS([inttypes.h stdint.h], + [lo_have_typ_hdr=true;break], + [lo_have_typ_hdr=false]) + gl_STDNORETURN_H + + # ---------------------------------------------------------------------- + # check for various programs used during the build. + # On OS/X, "wchar.h" needs "runetype.h" to work properly. + # ---------------------------------------------------------------------- + AC_CHECK_HEADERS([runetype.h wchar.h], [], [],[ + AC_INCLUDES_DEFAULT + #if HAVE_RUNETYPE_H + # include <runetype.h> + #endif + ]) + + AC_ARG_ENABLE([nls], + AS_HELP_STRING([--disable-nls],[disable nls support in libopts])) + AS_IF([test "x$enable_nls" != "xno" && \ + test "X${ac_cv_header_libintl_h}" = Xyes], [ + AC_DEFINE([ENABLE_NLS],[1],[nls support in libopts])]) + + # -------------------------------------------- + # Verify certain entries from AC_CHECK_HEADERS + # -------------------------------------------- + [${lo_have_arg_hdr} || \ + ]AC_MSG_ERROR([you must have stdarg.h or varargs.h on your system])[ + + ${lo_have_str_hdr} || \ + ]AC_MSG_ERROR([you must have string.h or strings.h on your system])[ + + ${lo_have_lim_hdr} || \ + ]AC_MSG_ERROR( + [you must have one of limits.h, sys/limits.h or values.h])[ + + ${lo_have_typ_hdr} || \ + ]AC_MSG_ERROR([you must have inttypes.h or stdint.h on your system])[ + + for f in sys_types sys_param sys_stat string errno stdlib memory setjmp + do eval as_ac_var=\${ac_cv_header_${f}_h} + test "X${as_ac_var}" = Xyes || { + ]AC_MSG_ERROR([you must have ${f}.h on your system])[ + } + done + test "X${ac_cv_header_inttypes_h-no}" = Xyes || \ + echo '#include <stdint.h>' > inttypes.h] + + # ---------------------------------------------------------------------- + # Checks for typedefs + # ---------------------------------------------------------------------- + AC_CHECK_TYPES(wchar_t) + AC_CHECK_TYPES(wint_t, [], [], [ + AC_INCLUDES_DEFAULT + #if HAVE_RUNETYPE_H + # include <runetype.h> + #endif + #if HAVE_WCHAR_H + # include <wchar.h> + #endif + ]) + AC_CHECK_TYPES([int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, + intptr_t, uintptr_t, uint_t, pid_t, size_t, ptrdiff_t]) + AC_CHECK_SIZEOF(char *, 8) + AC_CHECK_SIZEOF(int, 4) + AC_CHECK_SIZEOF(long, 8) + AC_CHECK_SIZEOF(short, 2) + + # ------------ + # AC_CHECK_LIB + # ------------ + AC_CHECK_LIB(gen, pathfind) + AC_CHECK_LIB(intl,gettext) + AC_FUNC_VPRINTF + AC_FUNC_FORK + AC_CHECK_FUNCS([mmap canonicalize_file_name snprintf strdup strchr \ + strrchr strsignal fchmod fstat chmod]) + AC_PROG_SED + [while : + do + test -x "$POSIX_SHELL" && break + POSIX_SHELL=`which bash` + test -x "$POSIX_SHELL" && break + POSIX_SHELL=`which dash` + test -x "$POSIX_SHELL" && break + POSIX_SHELL=/usr/xpg4/bin/sh + test -x "$POSIX_SHELL" && break + POSIX_SHELL=`/bin/sh -c ' + exec 2>/dev/null + if ! true ; then exit 1 ; fi + echo /bin/sh'` + test -x "$POSIX_SHELL" && break + ]AC_MSG_ERROR([cannot locate a working POSIX shell])[ + done] + AC_DEFINE_UNQUOTED([POSIX_SHELL], ["${POSIX_SHELL}"], + [define to a working POSIX compliant shell]) + AC_SUBST([POSIX_SHELL]) +]) + +dnl +dnl @synopsis INVOKE_LIBOPTS_MACROS +dnl +dnl This macro will invoke the AutoConf macros specified in libopts.def +dnl that have not been disabled with "omit-invocation". +dnl +AC_DEFUN([LIBOPTS_WITH_REGEX_HEADER],[ + AC_ARG_WITH([regex-header], + AS_HELP_STRING([--with-regex-header], [a reg expr header is specified]), + [libopts_cv_with_regex_header=${with_regex_header}], + AC_CACHE_CHECK([whether a reg expr header is specified], libopts_cv_with_regex_header, + libopts_cv_with_regex_header=no) + ) # end of AC_ARG_WITH + if test "X${libopts_cv_with_regex_header}" != Xno + then + AC_DEFINE_UNQUOTED([REGEX_HEADER],[<${libopts_cv_with_regex_header}>]) + else + AC_DEFINE([REGEX_HEADER],[<regex.h>],[name of regex header file]) + fi + +]) # end of AC_DEFUN of LIBOPTS_WITH_REGEX_HEADER + + +AC_DEFUN([LIBOPTS_WITHLIB_REGEX],[ + AC_ARG_WITH([libregex], + AS_HELP_STRING([--with-libregex], [libregex installation prefix]), + [libopts_cv_with_libregex_root=${with_libregex}], + AC_CACHE_CHECK([whether with-libregex was specified], libopts_cv_with_libregex_root, + libopts_cv_with_libregex_root=no) + ) # end of AC_ARG_WITH libregex + + if test "${with_libregex+set}" = set && \ + test "X${withval}" = Xno + then ## disabled by request + libopts_cv_with_libregex_root=no + libopts_cv_with_libregex_cflags=no + libopts_cv_with_libregex_libs=no + else + + AC_ARG_WITH([libregex-cflags], + AS_HELP_STRING([--with-libregex-cflags], [libregex compile flags]), + [libopts_cv_with_libregex_cflags=${with_libregex_cflags}], + AC_CACHE_CHECK([whether with-libregex-cflags was specified], libopts_cv_with_libregex_cflags, + libopts_cv_with_libregex_cflags=no) + ) # end of AC_ARG_WITH libregex-cflags + + AC_ARG_WITH([libregex-libs], + AS_HELP_STRING([--with-libregex-libs], [libregex link command arguments]), + [libopts_cv_with_libregex_libs=${with_libregex_libs}], + AC_CACHE_CHECK([whether with-libregex-libs was specified], libopts_cv_with_libregex_libs, + libopts_cv_with_libregex_libs=no) + ) # end of AC_ARG_WITH libregex-libs + + case "X${libopts_cv_with_libregex_cflags}" in + Xyes|Xno|X ) + case "X${libopts_cv_with_libregex_root}" in + Xyes|Xno|X ) libopts_cv_with_libregex_cflags=no ;; + * ) libopts_cv_with_libregex_cflags=-I${libopts_cv_with_libregex_root}/include ;; + esac + esac + case "X${libopts_cv_with_libregex_libs}" in + Xyes|Xno|X ) + case "X${libopts_cv_with_libregex_root}" in + Xyes|Xno|X ) libopts_cv_with_libregex_libs=no ;; + * ) libopts_cv_with_libregex_libs="-L${libopts_cv_with_libregex_root}/lib -lregex" ;; + esac + esac + libopts_save_CPPFLAGS="${CPPFLAGS}" + libopts_save_LIBS="${LIBS}" + case "X${libopts_cv_with_libregex_cflags}" in + Xyes|Xno|X ) + libopts_cv_with_libregex_cflags="" ;; + * ) CPPFLAGS="${CPPFLAGS} ${libopts_cv_with_libregex_cflags}" ;; + esac + case "X${libopts_cv_with_libregex_libs}" in + Xyes|Xno|X ) + libopts_cv_with_libregex_libs="" ;; + * ) + LIBS="${LIBS} ${libopts_cv_with_libregex_libs}" ;; + esac + LIBREGEX_CFLAGS="" + LIBREGEX_LIBS="" + AC_MSG_CHECKING([whether libregex functions properly]) + AC_CACHE_VAL([libopts_cv_with_libregex],[ + AC_RUN_IFELSE([AC_LANG_SOURCE([@%:@include <stdio.h> +@%:@include <stdlib.h> +@%:@include <sys/types.h> +@%:@include REGEX_HEADER +static regex_t re; +void comp_re(char const * pzPat) { + int res = regcomp( &re, pzPat, REG_EXTENDED|REG_ICASE|REG_NEWLINE ); + if (res == 0) return; + exit( res ); } +int main() { + regmatch_t m@<:@2@:>@; + comp_re( "^.*\@S|@" ); + comp_re( "()|no.*" ); + comp_re( "." ); + if (regexec( &re, "X", 2, m, 0 ) != 0) return 1; + if ((m@<:@0@:>@.rm_so != 0) || (m@<:@0@:>@.rm_eo != 1)) { + fputs( "error: regex -->.<-- did not match\n", stderr ); + return 1; + } + return 0; }] )], + [libopts_cv_with_libregex=yes], [libopts_cv_with_libregex=no], + [libopts_cv_with_libregex=no]) # end of AC_RUN_IFELSE + ]) # end of AC_CACHE_VAL for libopts_cv_with_libregex + fi ## disabled by request + AC_MSG_RESULT([${libopts_cv_with_libregex}]) + if test "X${libopts_cv_with_libregex}" != Xno + then + AC_DEFINE([WITH_LIBREGEX],[1], + [Define this if a working libregex can be found]) + else + CPPFLAGS="${libopts_save_CPPFLAGS}" + LIBS="${libopts_save_LIBS}" + libopts_cv_with_libregex_root=no +libopts_cv_with_libregex_cflags=no +libopts_cv_with_libregex_libs=no +libopts_cv_with_libregex=no + fi + +]) # end of AC_DEFUN of LIBOPTS_WITHLIB_REGEX + + +AC_DEFUN([LIBOPTS_RUN_PATHFIND],[ + AC_MSG_CHECKING([whether pathfind(3) works]) + AC_CACHE_VAL([libopts_cv_run_pathfind],[ + AC_RUN_IFELSE([AC_LANG_SOURCE([@%:@include <string.h> +@%:@include <stdlib.h> +int main (int argc, char ** argv) { + char * pz = pathfind( getenv( "PATH" ), "sh", "x" ); + return (pz == 0) ? 1 : 0; +}] )], + [libopts_cv_run_pathfind=yes],[libopts_cv_run_pathfind=no],[libopts_cv_run_pathfind=no] + ) # end of RUN_IFELSE + ]) # end of AC_CACHE_VAL for libopts_cv_run_pathfind + AC_MSG_RESULT([${libopts_cv_run_pathfind}]) + if test "X${libopts_cv_run_pathfind}" != Xno + then + AC_DEFINE([HAVE_PATHFIND],[1], + [Define this if pathfind(3) works]) + fi + +]) # end of AC_DEFUN of LIBOPTS_RUN_PATHFIND + + +AC_DEFUN([LIBOPTS_TEST_DEV_ZERO],[ + AC_MSG_CHECKING([whether /dev/zero is readable device]) + AC_CACHE_VAL([libopts_cv_test_dev_zero],[ + libopts_cv_test_dev_zero=`exec 2> /dev/null +dzero=\`ls -lL /dev/zero | egrep ^c......r\` +test -z "${dzero}" && exit 1 +echo ${dzero}` + if test $? -ne 0 || test -z "$libopts_cv_test_dev_zero" + then libopts_cv_test_dev_zero=no + fi + ]) # end of CACHE_VAL of libopts_cv_test_dev_zero + AC_MSG_RESULT([${libopts_cv_test_dev_zero}]) + if test "X${libopts_cv_test_dev_zero}" != Xno + then + AC_DEFINE([HAVE_DEV_ZERO],[1], + [Define this if /dev/zero is readable device]) + fi + +]) # end of AC_DEFUN of LIBOPTS_TEST_DEV_ZERO + + +AC_DEFUN([LIBOPTS_RUN_REALPATH],[ + AC_MSG_CHECKING([whether we have a functional realpath(3C)]) + AC_CACHE_VAL([libopts_cv_run_realpath],[ + AC_RUN_IFELSE([AC_LANG_SOURCE([@%:@include <limits.h> +@%:@include <stdlib.h> +int main (int argc, char ** argv) { +@%:@ifndef PATH_MAX +choke me!! +@%:@else + char zPath@<:@PATH_MAX+1@:>@; +@%:@endif + char *pz = realpath(argv@<:@0@:>@, zPath); + return (pz == zPath) ? 0 : 1; +}] )], + [libopts_cv_run_realpath=yes],[libopts_cv_run_realpath=no],[libopts_cv_run_realpath=no] + ) # end of RUN_IFELSE + ]) # end of AC_CACHE_VAL for libopts_cv_run_realpath + AC_MSG_RESULT([${libopts_cv_run_realpath}]) + if test "X${libopts_cv_run_realpath}" != Xno + then + AC_DEFINE([HAVE_REALPATH],[1], + [Define this if we have a functional realpath(3C)]) + fi + +]) # end of AC_DEFUN of LIBOPTS_RUN_REALPATH + + +AC_DEFUN([LIBOPTS_RUN_STRFTIME],[ + AC_MSG_CHECKING([whether strftime() works]) + AC_CACHE_VAL([libopts_cv_run_strftime],[ + AC_RUN_IFELSE([AC_LANG_SOURCE([@%:@include <time.h> +@%:@include <string.h> +char t_buf@<:@ 64 @:>@; +int main() { + static char const z@<:@@:>@ = "Thursday Aug 28 240"; + struct tm tm; + tm.tm_sec = 36; /* seconds after the minute @<:@0, 61@:>@ */ + tm.tm_min = 44; /* minutes after the hour @<:@0, 59@:>@ */ + tm.tm_hour = 12; /* hour since midnight @<:@0, 23@:>@ */ + tm.tm_mday = 28; /* day of the month @<:@1, 31@:>@ */ + tm.tm_mon = 7; /* months since January @<:@0, 11@:>@ */ + tm.tm_year = 86; /* years since 1900 */ + tm.tm_wday = 4; /* days since Sunday @<:@0, 6@:>@ */ + tm.tm_yday = 239; /* days since January 1 @<:@0, 365@:>@ */ + tm.tm_isdst = 1; /* flag for daylight savings time */ + strftime( t_buf, sizeof( t_buf ), "%A %b %d %j", &tm ); + return (strcmp( t_buf, z ) != 0); }] )], + [libopts_cv_run_strftime=yes],[libopts_cv_run_strftime=no],[libopts_cv_run_strftime=no] + ) # end of RUN_IFELSE + ]) # end of AC_CACHE_VAL for libopts_cv_run_strftime + AC_MSG_RESULT([${libopts_cv_run_strftime}]) + if test "X${libopts_cv_run_strftime}" != Xno + then + AC_DEFINE([HAVE_STRFTIME],[1], + [Define this if strftime() works]) + fi + +]) # end of AC_DEFUN of LIBOPTS_RUN_STRFTIME + + +AC_DEFUN([LIBOPTS_RUN_FOPEN_BINARY],[ + AC_MSG_CHECKING([whether fopen accepts "b" mode]) + AC_CACHE_VAL([libopts_cv_run_fopen_binary],[ + AC_RUN_IFELSE([AC_LANG_SOURCE([@%:@include <stdio.h> +int main (int argc, char ** argv) { +FILE * fp = fopen("conftest.@S|@ac_ext", "rb"); +return (fp == NULL) ? 1 : fclose(fp); }] )], + [libopts_cv_run_fopen_binary=yes],[libopts_cv_run_fopen_binary=no],[libopts_cv_run_fopen_binary=no] + ) # end of RUN_IFELSE + ]) # end of AC_CACHE_VAL for libopts_cv_run_fopen_binary + AC_MSG_RESULT([${libopts_cv_run_fopen_binary}]) + if test "X${libopts_cv_run_fopen_binary}" != Xno + then + AC_DEFINE([FOPEN_BINARY_FLAG],"b", + [fopen(3) accepts a 'b' in the mode flag]) + else + AC_DEFINE([FOPEN_BINARY_FLAG],"", + [fopen(3) accepts a 'b' in the mode flag]) + fi + +]) # end of AC_DEFUN of LIBOPTS_RUN_FOPEN_BINARY + + +AC_DEFUN([LIBOPTS_RUN_FOPEN_TEXT],[ + AC_MSG_CHECKING([whether fopen accepts "t" mode]) + AC_CACHE_VAL([libopts_cv_run_fopen_text],[ + AC_RUN_IFELSE([AC_LANG_SOURCE([@%:@include <stdio.h> +int main (int argc, char ** argv) { +FILE * fp = fopen("conftest.@S|@ac_ext", "rt"); +return (fp == NULL) ? 1 : fclose(fp); }] )], + [libopts_cv_run_fopen_text=yes],[libopts_cv_run_fopen_text=no],[libopts_cv_run_fopen_text=no] + ) # end of RUN_IFELSE + ]) # end of AC_CACHE_VAL for libopts_cv_run_fopen_text + AC_MSG_RESULT([${libopts_cv_run_fopen_text}]) + if test "X${libopts_cv_run_fopen_text}" != Xno + then + AC_DEFINE([FOPEN_TEXT_FLAG],"t", + [fopen(3) accepts a 't' in the mode flag]) + else + AC_DEFINE([FOPEN_TEXT_FLAG],"", + [fopen(3) accepts a 't' in the mode flag]) + fi + +]) # end of AC_DEFUN of LIBOPTS_RUN_FOPEN_TEXT + + +AC_DEFUN([LIBOPTS_DISABLE_OPTIONAL_ARGS],[ + AC_ARG_ENABLE([optional-args], + AS_HELP_STRING([--disable-optional-args], [not wanting optional option args]), + [libopts_cv_enable_optional_args=${enable_optional_args}], + AC_CACHE_CHECK([whether not wanting optional option args], libopts_cv_enable_optional_args, + libopts_cv_enable_optional_args=yes) + ) # end of AC_ARG_ENABLE + if test "X${libopts_cv_enable_optional_args}" = Xno + then + AC_DEFINE([NO_OPTIONAL_OPT_ARGS], [1], + [Define this if optional arguments are disallowed]) + fi + +]) # end of AC_DEFUN of LIBOPTS_DISABLE_OPTIONAL_ARGS + + +AC_DEFUN([INVOKE_LIBOPTS_MACROS],[ + AC_REQUIRE([INVOKE_LIBOPTS_MACROS_FIRST]) + # Check to see if a reg expr header is specified. + LIBOPTS_WITH_REGEX_HEADER + + # Check to see if a working libregex can be found. + LIBOPTS_WITHLIB_REGEX + + # Check to see if pathfind(3) works. + LIBOPTS_RUN_PATHFIND + + # Check to see if /dev/zero is readable device. + LIBOPTS_TEST_DEV_ZERO + + # Check to see if we have a functional realpath(3C). + LIBOPTS_RUN_REALPATH + + # Check to see if strftime() works. + LIBOPTS_RUN_STRFTIME + + # Check to see if fopen accepts "b" mode. + LIBOPTS_RUN_FOPEN_BINARY + + # Check to see if fopen accepts "t" mode. + LIBOPTS_RUN_FOPEN_TEXT + + # Check to see if not wanting optional option args. + LIBOPTS_DISABLE_OPTIONAL_ARGS + +]) # end AC_DEFUN of INVOKE_LIBOPTS_MACROS diff --git a/config/liboptschk.m4 b/config/liboptschk.m4 new file mode 100644 index 0000000..9d107d6 --- /dev/null +++ b/config/liboptschk.m4 @@ -0,0 +1,27 @@ +# liboptschk.m4 serial 2 (autogen - 5.11.4) +dnl Copyright (C) 2005-2018 by Bruce Korb - all rights reserved +dnl +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 +AC_DEFUN([ag_FIND_LIBOPTS], + [if test "X${ac_cv_header_autoopts_options_h}" = Xno + then : + else + f=`autoopts-config cflags` 2>/dev/null + if test X"${f}" = X + then + : + else + AC_DEFINE([HAVE_LIBOPTS],[1],[define if we can find libopts]) + CFLAGS="${CFLAGS} ${f}" + ao_CFLAGS="${f}" + AC_SUBST(ao_CFLAGS) + + f=`autoopts-config ldflags` 2>/dev/null + LIBS="${LIBS} ${f}" + ao_LIBS="${f}" + AC_SUBST(ao_LIBS) + fi + fi]) diff --git a/config/libtool.m4 b/config/libtool.m4 new file mode 100644 index 0000000..a3bc337 --- /dev/null +++ b/config/libtool.m4 @@ -0,0 +1,8369 @@ +# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- +# +# Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc. +# Written by Gordon Matzigkeit, 1996 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +m4_define([_LT_COPYING], [dnl +# Copyright (C) 2014 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. + +# GNU Libtool 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 of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program or library that is built +# using GNU Libtool, you may include this file under the same +# distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +]) + +# serial 58 LT_INIT + + +# LT_PREREQ(VERSION) +# ------------------ +# Complain and exit if this libtool version is less that VERSION. +m4_defun([LT_PREREQ], +[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, + [m4_default([$3], + [m4_fatal([Libtool version $1 or higher is required], + 63)])], + [$2])]) + + +# _LT_CHECK_BUILDDIR +# ------------------ +# Complain if the absolute build directory name contains unusual characters +m4_defun([_LT_CHECK_BUILDDIR], +[case `pwd` in + *\ * | *\ *) + AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; +esac +]) + + +# LT_INIT([OPTIONS]) +# ------------------ +AC_DEFUN([LT_INIT], +[AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK +AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl +AC_BEFORE([$0], [LT_LANG])dnl +AC_BEFORE([$0], [LT_OUTPUT])dnl +AC_BEFORE([$0], [LTDL_INIT])dnl +m4_require([_LT_CHECK_BUILDDIR])dnl + +dnl Autoconf doesn't catch unexpanded LT_ macros by default: +m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl +m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl +dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 +dnl unless we require an AC_DEFUNed macro: +AC_REQUIRE([LTOPTIONS_VERSION])dnl +AC_REQUIRE([LTSUGAR_VERSION])dnl +AC_REQUIRE([LTVERSION_VERSION])dnl +AC_REQUIRE([LTOBSOLETE_VERSION])dnl +m4_require([_LT_PROG_LTMAIN])dnl + +_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) + +dnl Parse OPTIONS +_LT_SET_OPTIONS([$0], [$1]) + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS=$ltmain + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +_LT_SETUP + +# Only expand once: +m4_define([LT_INIT]) +])# LT_INIT + +# Old names: +AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) +AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PROG_LIBTOOL], []) +dnl AC_DEFUN([AM_PROG_LIBTOOL], []) + + +# _LT_PREPARE_CC_BASENAME +# ----------------------- +m4_defun([_LT_PREPARE_CC_BASENAME], [ +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +func_cc_basename () +{ + for cc_temp in @S|@*""; do + case $cc_temp in + compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; + distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; + \-*) ;; + *) break;; + esac + done + func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +} +])# _LT_PREPARE_CC_BASENAME + + +# _LT_CC_BASENAME(CC) +# ------------------- +# It would be clearer to call AC_REQUIREs from _LT_PREPARE_CC_BASENAME, +# but that macro is also expanded into generated libtool script, which +# arranges for $SED and $ECHO to be set by different means. +m4_defun([_LT_CC_BASENAME], +[m4_require([_LT_PREPARE_CC_BASENAME])dnl +AC_REQUIRE([_LT_DECL_SED])dnl +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl +func_cc_basename $1 +cc_basename=$func_cc_basename_result +]) + + +# _LT_FILEUTILS_DEFAULTS +# ---------------------- +# It is okay to use these file commands and assume they have been set +# sensibly after 'm4_require([_LT_FILEUTILS_DEFAULTS])'. +m4_defun([_LT_FILEUTILS_DEFAULTS], +[: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} +])# _LT_FILEUTILS_DEFAULTS + + +# _LT_SETUP +# --------- +m4_defun([_LT_SETUP], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl + +_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl +dnl +_LT_DECL([], [host_alias], [0], [The host system])dnl +_LT_DECL([], [host], [0])dnl +_LT_DECL([], [host_os], [0])dnl +dnl +_LT_DECL([], [build_alias], [0], [The build system])dnl +_LT_DECL([], [build], [0])dnl +_LT_DECL([], [build_os], [0])dnl +dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +dnl +AC_REQUIRE([AC_PROG_LN_S])dnl +test -z "$LN_S" && LN_S="ln -s" +_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl +dnl +AC_REQUIRE([LT_CMD_MAX_LEN])dnl +_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl +_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl +dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl +m4_require([_LT_CMD_RELOAD])dnl +m4_require([_LT_CHECK_MAGIC_METHOD])dnl +m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl +m4_require([_LT_CMD_OLD_ARCHIVE])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_WITH_SYSROOT])dnl +m4_require([_LT_CMD_TRUNCATE])dnl + +_LT_CONFIG_LIBTOOL_INIT([ +# See if we are running on zsh, and set the options that allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi +]) +if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi + +_LT_CHECK_OBJDIR + +m4_require([_LT_TAG_COMPILER])dnl + +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 set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a '.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld=$lt_cv_prog_gnu_ld + +old_CC=$CC +old_CFLAGS=$CFLAGS + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +_LT_CC_BASENAME([$compiler]) + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + _LT_PATH_MAGIC + fi + ;; +esac + +# Use C for the default configuration in the libtool script +LT_SUPPORTED_TAG([CC]) +_LT_LANG_C_CONFIG +_LT_LANG_DEFAULT_CONFIG +_LT_CONFIG_COMMANDS +])# _LT_SETUP + + +# _LT_PREPARE_SED_QUOTE_VARS +# -------------------------- +# Define a few sed substitution that help us do robust quoting. +m4_defun([_LT_PREPARE_SED_QUOTE_VARS], +[# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([["`\\]]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' +]) + +# _LT_PROG_LTMAIN +# --------------- +# Note that this code is called both from 'configure', and 'config.status' +# now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, +# 'config.status' has no value for ac_aux_dir unless we are using Automake, +# so we pass a copy along to make sure it has a sensible value anyway. +m4_defun([_LT_PROG_LTMAIN], +[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl +_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) +ltmain=$ac_aux_dir/ltmain.sh +])# _LT_PROG_LTMAIN + + +## ------------------------------------- ## +## Accumulate code for creating libtool. ## +## ------------------------------------- ## + +# So that we can recreate a full libtool script including additional +# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS +# in macros and then make a single call at the end using the 'libtool' +# label. + + +# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) +# ---------------------------------------- +# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL_INIT], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_INIT], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_INIT]) + + +# _LT_CONFIG_LIBTOOL([COMMANDS]) +# ------------------------------ +# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. +m4_define([_LT_CONFIG_LIBTOOL], +[m4_ifval([$1], + [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], + [$1 +])])]) + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) + + +# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) +# ----------------------------------------------------- +m4_defun([_LT_CONFIG_SAVE_COMMANDS], +[_LT_CONFIG_LIBTOOL([$1]) +_LT_CONFIG_LIBTOOL_INIT([$2]) +]) + + +# _LT_FORMAT_COMMENT([COMMENT]) +# ----------------------------- +# Add leading comment marks to the start of each line, and a trailing +# full-stop to the whole comment if one is not present already. +m4_define([_LT_FORMAT_COMMENT], +[m4_ifval([$1], [ +m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], + [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) +)]) + + + +## ------------------------ ## +## FIXME: Eliminate VARNAME ## +## ------------------------ ## + + +# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) +# ------------------------------------------------------------------- +# CONFIGNAME is the name given to the value in the libtool script. +# VARNAME is the (base) name used in the configure script. +# VALUE may be 0, 1 or 2 for a computed quote escaped value based on +# VARNAME. Any other value will be used directly. +m4_define([_LT_DECL], +[lt_if_append_uniq([lt_decl_varnames], [$2], [, ], + [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], + [m4_ifval([$1], [$1], [$2])]) + lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) + m4_ifval([$4], + [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) + lt_dict_add_subkey([lt_decl_dict], [$2], + [tagged?], [m4_ifval([$5], [yes], [no])])]) +]) + + +# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) +# -------------------------------------------------------- +m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) + + +# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_tag_varnames], +[_lt_decl_filter([tagged?], [yes], $@)]) + + +# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) +# --------------------------------------------------------- +m4_define([_lt_decl_filter], +[m4_case([$#], + [0], [m4_fatal([$0: too few arguments: $#])], + [1], [m4_fatal([$0: too few arguments: $#: $1])], + [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], + [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], + [lt_dict_filter([lt_decl_dict], $@)])[]dnl +]) + + +# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) +# -------------------------------------------------- +m4_define([lt_decl_quote_varnames], +[_lt_decl_filter([value], [1], $@)]) + + +# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_dquote_varnames], +[_lt_decl_filter([value], [2], $@)]) + + +# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) +# --------------------------------------------------- +m4_define([lt_decl_varnames_tagged], +[m4_assert([$# <= 2])dnl +_$0(m4_quote(m4_default([$1], [[, ]])), + m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), + m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) +m4_define([_lt_decl_varnames_tagged], +[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) + + +# lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) +# ------------------------------------------------ +m4_define([lt_decl_all_varnames], +[_$0(m4_quote(m4_default([$1], [[, ]])), + m4_if([$2], [], + m4_quote(lt_decl_varnames), + m4_quote(m4_shift($@))))[]dnl +]) +m4_define([_lt_decl_all_varnames], +[lt_join($@, lt_decl_varnames_tagged([$1], + lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl +]) + + +# _LT_CONFIG_STATUS_DECLARE([VARNAME]) +# ------------------------------------ +# Quote a variable value, and forward it to 'config.status' so that its +# declaration there will have the same value as in 'configure'. VARNAME +# must have a single quote delimited value for this to work. +m4_define([_LT_CONFIG_STATUS_DECLARE], +[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) + + +# _LT_CONFIG_STATUS_DECLARATIONS +# ------------------------------ +# We delimit libtool config variables with single quotes, so when +# we write them to config.status, we have to be sure to quote all +# embedded single quotes properly. In configure, this macro expands +# each variable declared with _LT_DECL (and _LT_TAGDECL) into: +# +# <var>='`$ECHO "$<var>" | $SED "$delay_single_quote_subst"`' +m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], +[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), + [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAGS +# ---------------- +# Output comment and list of tags supported by the script +m4_defun([_LT_LIBTOOL_TAGS], +[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl +available_tags='_LT_TAGS'dnl +]) + + +# _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) +# ----------------------------------- +# Extract the dictionary values for VARNAME (optionally with TAG) and +# expand to a commented shell variable setting: +# +# # Some comment about what VAR is for. +# visible_name=$lt_internal_name +m4_define([_LT_LIBTOOL_DECLARE], +[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], + [description])))[]dnl +m4_pushdef([_libtool_name], + m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl +m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), + [0], [_libtool_name=[$]$1], + [1], [_libtool_name=$lt_[]$1], + [2], [_libtool_name=$lt_[]$1], + [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl +m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl +]) + + +# _LT_LIBTOOL_CONFIG_VARS +# ----------------------- +# Produce commented declarations of non-tagged libtool config variables +# suitable for insertion in the LIBTOOL CONFIG section of the 'libtool' +# script. Tagged libtool config variables (even for the LIBTOOL CONFIG +# section) are produced by _LT_LIBTOOL_TAG_VARS. +m4_defun([_LT_LIBTOOL_CONFIG_VARS], +[m4_foreach([_lt_var], + m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) + + +# _LT_LIBTOOL_TAG_VARS(TAG) +# ------------------------- +m4_define([_LT_LIBTOOL_TAG_VARS], +[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), + [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) + + +# _LT_TAGVAR(VARNAME, [TAGNAME]) +# ------------------------------ +m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) + + +# _LT_CONFIG_COMMANDS +# ------------------- +# Send accumulated output to $CONFIG_STATUS. Thanks to the lists of +# variables for single and double quote escaping we saved from calls +# to _LT_DECL, we can put quote escaped variables declarations +# into 'config.status', and then the shell code to quote escape them in +# for loops in 'config.status'. Finally, any additional code accumulated +# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. +m4_defun([_LT_CONFIG_COMMANDS], +[AC_PROVIDE_IFELSE([LT_OUTPUT], + dnl If the libtool generation code has been placed in $CONFIG_LT, + dnl instead of duplicating it all over again into config.status, + dnl then we will have config.status run $CONFIG_LT later, so it + dnl needs to know what name is stored there: + [AC_CONFIG_COMMANDS([libtool], + [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], + dnl If the libtool generation code is destined for config.status, + dnl expand the accumulated commands and init code now: + [AC_CONFIG_COMMANDS([libtool], + [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) +])#_LT_CONFIG_COMMANDS + + +# Initialize. +m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], +[ + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +_LT_CONFIG_STATUS_DECLARATIONS +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$[]1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_quote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in lt_decl_all_varnames([[ \ +]], lt_decl_dquote_varnames); do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[[\\\\\\\`\\"\\\$]]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +_LT_OUTPUT_LIBTOOL_INIT +]) + +# _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) +# ------------------------------------ +# Generate a child script FILE with all initialization necessary to +# reuse the environment learned by the parent script, and make the +# file executable. If COMMENT is supplied, it is inserted after the +# '#!' sequence but before initialization text begins. After this +# macro, additional text can be appended to FILE to form the body of +# the child script. The macro ends with non-zero status if the +# file could not be fully written (such as if the disk is full). +m4_ifdef([AS_INIT_GENERATED], +[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], +[m4_defun([_LT_GENERATED_FILE_INIT], +[m4_require([AS_PREPARE])]dnl +[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl +[lt_write_fail=0 +cat >$1 <<_ASEOF || lt_write_fail=1 +#! $SHELL +# Generated by $as_me. +$2 +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$1 <<\_ASEOF || lt_write_fail=1 +AS_SHELL_SANITIZE +_AS_PREPARE +exec AS_MESSAGE_FD>&1 +_ASEOF +test 0 = "$lt_write_fail" && chmod +x $1[]dnl +m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT + +# LT_OUTPUT +# --------- +# This macro allows early generation of the libtool script (before +# AC_OUTPUT is called), incase it is used in configure for compilation +# tests. +AC_DEFUN([LT_OUTPUT], +[: ${CONFIG_LT=./config.lt} +AC_MSG_NOTICE([creating $CONFIG_LT]) +_LT_GENERATED_FILE_INIT(["$CONFIG_LT"], +[# Run this file to recreate a libtool stub with the current configuration.]) + +cat >>"$CONFIG_LT" <<\_LTEOF +lt_cl_silent=false +exec AS_MESSAGE_LOG_FD>>config.log +{ + echo + AS_BOX([Running $as_me.]) +} >&AS_MESSAGE_LOG_FD + +lt_cl_help="\ +'$as_me' creates a local libtool stub from the current configuration, +for use in further configure time tests before the real libtool is +generated. + +Usage: $[0] [[OPTIONS]] + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + +Report bugs to <bug-libtool@gnu.org>." + +lt_cl_version="\ +m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl +m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) +configured by $[0], generated by m4_PACKAGE_STRING. + +Copyright (C) 2011 Free Software Foundation, Inc. +This config.lt script is free software; the Free Software Foundation +gives unlimited permision to copy, distribute and modify it." + +while test 0 != $[#] +do + case $[1] in + --version | --v* | -V ) + echo "$lt_cl_version"; exit 0 ;; + --help | --h* | -h ) + echo "$lt_cl_help"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --quiet | --q* | --silent | --s* | -q ) + lt_cl_silent=: ;; + + -*) AC_MSG_ERROR([unrecognized option: $[1] +Try '$[0] --help' for more information.]) ;; + + *) AC_MSG_ERROR([unrecognized argument: $[1] +Try '$[0] --help' for more information.]) ;; + esac + shift +done + +if $lt_cl_silent; then + exec AS_MESSAGE_FD>/dev/null +fi +_LTEOF + +cat >>"$CONFIG_LT" <<_LTEOF +_LT_OUTPUT_LIBTOOL_COMMANDS_INIT +_LTEOF + +cat >>"$CONFIG_LT" <<\_LTEOF +AC_MSG_NOTICE([creating $ofile]) +_LT_OUTPUT_LIBTOOL_COMMANDS +AS_EXIT(0) +_LTEOF +chmod +x "$CONFIG_LT" + +# configure is writing to config.log, but config.lt does its own redirection, +# appending to config.log, which fails on DOS, as config.log is still kept +# open by configure. Here we exec the FD to /dev/null, effectively closing +# config.log, so it can be properly (re)opened and appended to by config.lt. +lt_cl_success=: +test yes = "$silent" && + lt_config_lt_args="$lt_config_lt_args --quiet" +exec AS_MESSAGE_LOG_FD>/dev/null +$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false +exec AS_MESSAGE_LOG_FD>>config.log +$lt_cl_success || AS_EXIT(1) +])# LT_OUTPUT + + +# _LT_CONFIG(TAG) +# --------------- +# If TAG is the built-in tag, create an initial libtool script with a +# default configuration from the untagged config vars. Otherwise add code +# to config.status for appending the configuration named by TAG from the +# matching tagged config vars. +m4_defun([_LT_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_CONFIG_SAVE_COMMANDS([ + m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl + m4_if(_LT_TAG, [C], [ + # See if we are running on zsh, and set the options that allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST + fi + + cfgfile=${ofile}T + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL +# Generated automatically by $as_me ($PACKAGE) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. + +# Provide generalized library-building support services. +# Written by Gordon Matzigkeit, 1996 + +_LT_COPYING +_LT_LIBTOOL_TAGS + +# Configured defaults for sys_lib_dlsearch_path munging. +: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} + +# ### BEGIN LIBTOOL CONFIG +_LT_LIBTOOL_CONFIG_VARS +_LT_LIBTOOL_TAG_VARS +# ### END LIBTOOL CONFIG + +_LT_EOF + + cat <<'_LT_EOF' >> "$cfgfile" + +# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE + +_LT_PREPARE_MUNGE_PATH_LIST +_LT_PREPARE_CC_BASENAME + +# ### END FUNCTIONS SHARED WITH CONFIGURE + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# 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 set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + _LT_PROG_LTMAIN + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" +], +[cat <<_LT_EOF >> "$ofile" + +dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded +dnl in a comment (ie after a #). +# ### BEGIN LIBTOOL TAG CONFIG: $1 +_LT_LIBTOOL_TAG_VARS(_LT_TAG) +# ### END LIBTOOL TAG CONFIG: $1 +_LT_EOF +])dnl /m4_if +], +[m4_if([$1], [], [ + PACKAGE='$PACKAGE' + VERSION='$VERSION' + RM='$RM' + ofile='$ofile'], []) +])dnl /_LT_CONFIG_SAVE_COMMANDS +])# _LT_CONFIG + + +# LT_SUPPORTED_TAG(TAG) +# --------------------- +# Trace this macro to discover what tags are supported by the libtool +# --tag option, using: +# autoconf --trace 'LT_SUPPORTED_TAG:$1' +AC_DEFUN([LT_SUPPORTED_TAG], []) + + +# C support is built-in for now +m4_define([_LT_LANG_C_enabled], []) +m4_define([_LT_TAGS], []) + + +# LT_LANG(LANG) +# ------------- +# Enable libtool support for the given language if not already enabled. +AC_DEFUN([LT_LANG], +[AC_BEFORE([$0], [LT_OUTPUT])dnl +m4_case([$1], + [C], [_LT_LANG(C)], + [C++], [_LT_LANG(CXX)], + [Go], [_LT_LANG(GO)], + [Java], [_LT_LANG(GCJ)], + [Fortran 77], [_LT_LANG(F77)], + [Fortran], [_LT_LANG(FC)], + [Windows Resource], [_LT_LANG(RC)], + [m4_ifdef([_LT_LANG_]$1[_CONFIG], + [_LT_LANG($1)], + [m4_fatal([$0: unsupported language: "$1"])])])dnl +])# LT_LANG + + +# _LT_LANG(LANGNAME) +# ------------------ +m4_defun([_LT_LANG], +[m4_ifdef([_LT_LANG_]$1[_enabled], [], + [LT_SUPPORTED_TAG([$1])dnl + m4_append([_LT_TAGS], [$1 ])dnl + m4_define([_LT_LANG_]$1[_enabled], [])dnl + _LT_LANG_$1_CONFIG($1)])dnl +])# _LT_LANG + + +m4_ifndef([AC_PROG_GO], [ +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_GO. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ +m4_defun([AC_PROG_GO], +[AC_LANG_PUSH(Go)dnl +AC_ARG_VAR([GOC], [Go compiler command])dnl +AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl +_AC_ARG_VAR_LDFLAGS()dnl +AC_CHECK_TOOL(GOC, gccgo) +if test -z "$GOC"; then + if test -n "$ac_tool_prefix"; then + AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) + fi +fi +if test -z "$GOC"; then + AC_CHECK_PROG(GOC, gccgo, gccgo, false) +fi +])#m4_defun +])#m4_ifndef + + +# _LT_LANG_DEFAULT_CONFIG +# ----------------------- +m4_defun([_LT_LANG_DEFAULT_CONFIG], +[AC_PROVIDE_IFELSE([AC_PROG_CXX], + [LT_LANG(CXX)], + [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) + +AC_PROVIDE_IFELSE([AC_PROG_F77], + [LT_LANG(F77)], + [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) + +AC_PROVIDE_IFELSE([AC_PROG_FC], + [LT_LANG(FC)], + [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) + +dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal +dnl pulling things in needlessly. +AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [LT_LANG(GCJ)], + [AC_PROVIDE_IFELSE([LT_PROG_GCJ], + [LT_LANG(GCJ)], + [m4_ifdef([AC_PROG_GCJ], + [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([A][M_PROG_GCJ], + [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) + m4_ifdef([LT_PROG_GCJ], + [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) + +AC_PROVIDE_IFELSE([AC_PROG_GO], + [LT_LANG(GO)], + [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) + +AC_PROVIDE_IFELSE([LT_PROG_RC], + [LT_LANG(RC)], + [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) +])# _LT_LANG_DEFAULT_CONFIG + +# Obsolete macros: +AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) +AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) +AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) +AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) +AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_CXX], []) +dnl AC_DEFUN([AC_LIBTOOL_F77], []) +dnl AC_DEFUN([AC_LIBTOOL_FC], []) +dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) +dnl AC_DEFUN([AC_LIBTOOL_RC], []) + + +# _LT_TAG_COMPILER +# ---------------- +m4_defun([_LT_TAG_COMPILER], +[AC_REQUIRE([AC_PROG_CC])dnl + +_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl +_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl +_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl +_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC +])# _LT_TAG_COMPILER + + +# _LT_COMPILER_BOILERPLATE +# ------------------------ +# Check for compiler boilerplate output or warnings with +# the simple compiler test code. +m4_defun([_LT_COMPILER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* +])# _LT_COMPILER_BOILERPLATE + + +# _LT_LINKER_BOILERPLATE +# ---------------------- +# Check for linker boilerplate output or warnings with +# the simple link test code. +m4_defun([_LT_LINKER_BOILERPLATE], +[m4_require([_LT_DECL_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* +])# _LT_LINKER_BOILERPLATE + +# _LT_REQUIRED_DARWIN_CHECKS +# ------------------------- +m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ + case $host_os in + rhapsody* | darwin*) + AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) + AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) + AC_CHECK_TOOL([LIPO], [lipo], [:]) + AC_CHECK_TOOL([OTOOL], [otool], [:]) + AC_CHECK_TOOL([OTOOL64], [otool64], [:]) + _LT_DECL([], [DSYMUTIL], [1], + [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) + _LT_DECL([], [NMEDIT], [1], + [Tool to change global to local symbols on Mac OS X]) + _LT_DECL([], [LIPO], [1], + [Tool to manipulate fat objects and archives on Mac OS X]) + _LT_DECL([], [OTOOL], [1], + [ldd/readelf like tool for Mach-O binaries on Mac OS X]) + _LT_DECL([], [OTOOL64], [1], + [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) + + AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], + [lt_cv_apple_cc_single_mod=no + if test -z "$LT_MULTI_MODULE"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test 0 = "$_lt_result"; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi]) + + AC_CACHE_CHECK([for -exported_symbols_list linker flag], + [lt_cv_ld_exported_symbols_list], + [lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [lt_cv_ld_exported_symbols_list=yes], + [lt_cv_ld_exported_symbols_list=no]) + LDFLAGS=$save_LDFLAGS + ]) + + AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], + [lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD + echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD + $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD + echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD + $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&AS_MESSAGE_LOG_FD + elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&AS_MESSAGE_LOG_FD + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + ]) + case $host_os in + rhapsody* | darwin1.[[012]]) + _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + 10.[[012]][[,.]]*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test yes = "$lt_cv_apple_cc_single_mod"; then + _lt_dar_single_mod='$single_module' + fi + if test yes = "$lt_cv_ld_exported_symbols_list"; then + _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' + fi + if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac +]) + + +# _LT_DARWIN_LINKER_FEATURES([TAG]) +# --------------------------------- +# Checks for linker and compiler features on darwin +m4_defun([_LT_DARWIN_LINKER_FEATURES], +[ + m4_require([_LT_REQUIRED_DARWIN_CHECKS]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_automatic, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + if test yes = "$lt_cv_ld_force_load"; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], + [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='' + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=$_lt_dar_allow_undefined + case $cc_basename in + ifort*|nagfor*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test yes = "$_lt_dar_can_shared"; then + output_verbose_link_cmd=func_echo_all + _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" + _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" + m4_if([$1], [CXX], +[ if test yes != "$lt_cv_apple_cc_single_mod"; then + _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" + _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" + fi +],[]) + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi +]) + +# _LT_SYS_MODULE_PATH_AIX([TAGNAME]) +# ---------------------------------- +# Links a minimal program and checks the executable +# for the system default hardcoded library path. In most cases, +# this is /usr/lib:/lib, but when the MPI compilers are used +# the location of the communication and MPI libs are included too. +# If we don't find anything, use the default library path according +# to the aix ld manual. +# Store the results from the different compilers for each TAGNAME. +# Allow to override them for all tags through lt_cv_aix_libpath. +m4_defun([_LT_SYS_MODULE_PATH_AIX], +[m4_require([_LT_DECL_SED])dnl +if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], + [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ + lt_aix_libpath_sed='[ + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }]' + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi],[]) + if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then + _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=/usr/lib:/lib + fi + ]) + aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) +fi +])# _LT_SYS_MODULE_PATH_AIX + + +# _LT_SHELL_INIT(ARG) +# ------------------- +m4_define([_LT_SHELL_INIT], +[m4_divert_text([M4SH-INIT], [$1 +])])# _LT_SHELL_INIT + + + +# _LT_PROG_ECHO_BACKSLASH +# ----------------------- +# Find how we can fake an echo command that does not interpret backslash. +# In particular, with Autoconf 2.60 or later we add some code to the start +# of the generated configure script that will find a shell with a builtin +# printf (that we can use as an echo command). +m4_defun([_LT_PROG_ECHO_BACKSLASH], +[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +AC_MSG_CHECKING([how to print strings]) +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$[]1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + +case $ECHO in + printf*) AC_MSG_RESULT([printf]) ;; + print*) AC_MSG_RESULT([print -r]) ;; + *) AC_MSG_RESULT([cat]) ;; +esac + +m4_ifdef([_AS_DETECT_SUGGESTED], +[_AS_DETECT_SUGGESTED([ + test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO + ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test "X`printf %s $ECHO`" = "X$ECHO" \ + || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) + +_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) +_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) +])# _LT_PROG_ECHO_BACKSLASH + + +# _LT_WITH_SYSROOT +# ---------------- +AC_DEFUN([_LT_WITH_SYSROOT], +[AC_MSG_CHECKING([for sysroot]) +AC_ARG_WITH([sysroot], +[AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@], + [Search for dependent libraries within DIR (or the compiler's sysroot + if not specified).])], +[], [with_sysroot=no]) + +dnl lt_sysroot will always be passed unquoted. We quote it here +dnl in case the user passed a directory name. +lt_sysroot= +case $with_sysroot in #( + yes) + if test yes = "$GCC"; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + AC_MSG_RESULT([$with_sysroot]) + AC_MSG_ERROR([The sysroot must be an absolute path.]) + ;; +esac + + AC_MSG_RESULT([${lt_sysroot:-no}]) +_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl +[dependent libraries, and where our libraries should be installed.])]) + +# _LT_ENABLE_LOCK +# --------------- +m4_defun([_LT_ENABLE_LOCK], +[AC_ARG_ENABLE([libtool-lock], + [AS_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test no = "$enable_libtool_lock" || enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out what ABI is being produced by ac_compile, and set mode + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE=32 + ;; + *ELF-64*) + HPUX_IA64_MODE=64 + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + if test yes = "$lt_cv_prog_gnu_ld"; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +mips64*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + emul=elf + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + emul="${emul}32" + ;; + *64-bit*) + emul="${emul}64" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *MSB*) + emul="${emul}btsmip" + ;; + *LSB*) + emul="${emul}ltsmip" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *N32*) + emul="${emul}n32" + ;; + esac + LD="${LD-ld} -m $emul" + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. Note that the listed cases only cover the + # situations where additional linker options are needed (such as when + # doing 32-bit compilation for a host where ld defaults to 64-bit, or + # vice versa); the common cases where no linker options are needed do + # not appear in the list. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + case `/usr/bin/file conftest.o` in + *x86-64*) + LD="${LD-ld} -m elf32_x86_64" + ;; + *) + LD="${LD-ld} -m elf_i386" + ;; + esac + ;; + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + 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_LANG_PUSH(C) + AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_POP]) + if test yes != "$lt_cv_cc_needs_belf"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS=$SAVE_CFLAGS + fi + ;; +*-*solaris*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) + case $host in + i?86-*-solaris*|x86_64-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD=${LD-ld}_sol2 + fi + ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks=$enable_libtool_lock +])# _LT_ENABLE_LOCK + + +# _LT_PROG_AR +# ----------- +m4_defun([_LT_PROG_AR], +[AC_CHECK_TOOLS(AR, [ar], false) +: ${AR=ar} +: ${AR_FLAGS=cru} +_LT_DECL([], [AR], [1], [The archiver]) +_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) + +AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], + [lt_cv_ar_at_file=no + AC_COMPILE_IFELSE([AC_LANG_PROGRAM], + [echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' + AC_TRY_EVAL([lt_ar_try]) + if test 0 -eq "$ac_status"; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + AC_TRY_EVAL([lt_ar_try]) + if test 0 -ne "$ac_status"; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + ]) + ]) + +if test no = "$lt_cv_ar_at_file"; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi +_LT_DECL([], [archiver_list_spec], [1], + [How to feed a file listing to the archiver]) +])# _LT_PROG_AR + + +# _LT_CMD_OLD_ARCHIVE +# ------------------- +m4_defun([_LT_CMD_OLD_ARCHIVE], +[_LT_PROG_AR + +AC_CHECK_TOOL(STRIP, strip, :) +test -z "$STRIP" && STRIP=: +_LT_DECL([], [STRIP], [1], [A symbol stripping program]) + +AC_CHECK_TOOL(RANLIB, ranlib, :) +test -z "$RANLIB" && RANLIB=: +_LT_DECL([], [RANLIB], [1], + [Commands used to install an old-style archive]) + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + bitrig* | openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac +_LT_DECL([], [old_postinstall_cmds], [2]) +_LT_DECL([], [old_postuninstall_cmds], [2]) +_LT_TAGDECL([], [old_archive_cmds], [2], + [Commands used to build an old-style archive]) +_LT_DECL([], [lock_old_archive_extraction], [0], + [Whether to use a lock for old archive extraction]) +])# _LT_CMD_OLD_ARCHIVE + + +# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------------------- +# Check whether the given compiler option works +AC_DEFUN([_LT_COMPILER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$3" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + fi + $RM conftest* +]) + +if test yes = "[$]$2"; then + m4_if([$5], , :, [$5]) +else + m4_if([$6], , :, [$6]) +fi +])# _LT_COMPILER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) + + +# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------- +# Check whether the given linker option works +AC_DEFUN([_LT_LINKER_OPTION], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_SED])dnl +AC_CACHE_CHECK([$1], [$2], + [$2=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS $3" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&AS_MESSAGE_LOG_FD + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + else + $2=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS +]) + +if test yes = "[$]$2"; then + m4_if([$4], , :, [$4]) +else + m4_if([$5], , :, [$5]) +fi +])# _LT_LINKER_OPTION + +# Old name: +AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) + + +# LT_CMD_MAX_LEN +#--------------- +AC_DEFUN([LT_CMD_MAX_LEN], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +# find the maximum length of command line arguments +AC_MSG_CHECKING([the maximum length of command line arguments]) +AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl + i=0 + teststring=ABCD + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len" && \ + test undefined != "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test X`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test 17 != "$i" # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac +]) +if test -n "$lt_cv_sys_max_cmd_len"; then + AC_MSG_RESULT($lt_cv_sys_max_cmd_len) +else + AC_MSG_RESULT(none) +fi +max_cmd_len=$lt_cv_sys_max_cmd_len +_LT_DECL([], [max_cmd_len], [0], + [What is the maximum length of a command?]) +])# LT_CMD_MAX_LEN + +# Old name: +AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) + + +# _LT_HEADER_DLFCN +# ---------------- +m4_defun([_LT_HEADER_DLFCN], +[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl +])# _LT_HEADER_DLFCN + + +# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# ---------------------------------------------------------------- +m4_defun([_LT_TRY_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test yes = "$cross_compiling"; then : + [$4] +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +[#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include <dlfcn.h> +#endif + +#include <stdio.h> + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisibility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +}] +_LT_EOF + if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then + (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_dlunknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_TRY_DLOPEN_SELF + + +# LT_SYS_DLOPEN_SELF +# ------------------ +AC_DEFUN([LT_SYS_DLOPEN_SELF], +[m4_require([_LT_HEADER_DLFCN])dnl +if test yes != "$enable_dlopen"; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen=load_add_on + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen=LoadLibrary + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl],[ + lt_cv_dlopen=dyld + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ]) + ;; + + tpf*) + # Don't try to run any link tests for TPF. We know it's impossible + # because TPF is a cross-compiler, and we know how we open DSOs. + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + lt_cv_dlopen_self=no + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen=shl_load], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen=dlopen], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test no = "$lt_cv_dlopen"; then + enable_dlopen=no + else + enable_dlopen=yes + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS=$CPPFLAGS + test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS=$LDFLAGS + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS=$LIBS + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test yes = "$lt_cv_dlopen_self"; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS=$save_CPPFLAGS + LDFLAGS=$save_LDFLAGS + LIBS=$save_LIBS + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +_LT_DECL([dlopen_support], [enable_dlopen], [0], + [Whether dlopen is supported]) +_LT_DECL([dlopen_self], [enable_dlopen_self], [0], + [Whether dlopen of programs is supported]) +_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], + [Whether dlopen of statically linked programs is supported]) +])# LT_SYS_DLOPEN_SELF + +# Old name: +AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) + + +# _LT_COMPILER_C_O([TAGNAME]) +# --------------------------- +# Check to see if options -c and -o are simultaneously supported by compiler. +# This macro does not hard code the compiler like AC_PROG_CC_C_O. +m4_defun([_LT_COMPILER_C_O], +[m4_require([_LT_DECL_SED])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + fi + fi + chmod u+w . 2>&AS_MESSAGE_LOG_FD + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* +]) +_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], + [Does compiler simultaneously support -c and -o options?]) +])# _LT_COMPILER_C_O + + +# _LT_COMPILER_FILE_LOCKS([TAGNAME]) +# ---------------------------------- +# Check to see if we can do hard links to lock some files if needed +m4_defun([_LT_COMPILER_FILE_LOCKS], +[m4_require([_LT_ENABLE_LOCK])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +_LT_COMPILER_C_O([$1]) + +hard_links=nottested +if test no = "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" && test no != "$need_locks"; then + # do not overwrite the value of need_locks provided by the user + AC_MSG_CHECKING([if we can lock with hard links]) + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + AC_MSG_RESULT([$hard_links]) + if test no = "$hard_links"; then + AC_MSG_WARN(['$CC' does not support '-c -o', so 'make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi +_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) +])# _LT_COMPILER_FILE_LOCKS + + +# _LT_CHECK_OBJDIR +# ---------------- +m4_defun([_LT_CHECK_OBJDIR], +[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], +[rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null]) +objdir=$lt_cv_objdir +_LT_DECL([], [objdir], [0], + [The name of the directory that contains temporary libtool files])dnl +m4_pattern_allow([LT_OBJDIR])dnl +AC_DEFINE_UNQUOTED([LT_OBJDIR], "$lt_cv_objdir/", + [Define to the sub-directory where libtool stores uninstalled libraries.]) +])# _LT_CHECK_OBJDIR + + +# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) +# -------------------------------------- +# Check hardcoding attributes. +m4_defun([_LT_LINKER_HARDCODE_LIBPATH], +[AC_MSG_CHECKING([how to hardcode library paths into programs]) +_LT_TAGVAR(hardcode_action, $1)= +if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || + test -n "$_LT_TAGVAR(runpath_var, $1)" || + test yes = "$_LT_TAGVAR(hardcode_automatic, $1)"; then + + # We can hardcode non-existent directories. + if test no != "$_LT_TAGVAR(hardcode_direct, $1)" && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" && + test no != "$_LT_TAGVAR(hardcode_minus_L, $1)"; then + # Linking always hardcodes the temporary library directory. + _LT_TAGVAR(hardcode_action, $1)=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + _LT_TAGVAR(hardcode_action, $1)=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + _LT_TAGVAR(hardcode_action, $1)=unsupported +fi +AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) + +if test relink = "$_LT_TAGVAR(hardcode_action, $1)" || + test yes = "$_LT_TAGVAR(inherit_rpath, $1)"; then + # Fast installation is not supported + enable_fast_install=no +elif test yes = "$shlibpath_overrides_runpath" || + test no = "$enable_shared"; then + # Fast installation is not necessary + enable_fast_install=needless +fi +_LT_TAGDECL([], [hardcode_action], [0], + [How to hardcode a shared library path into an executable]) +])# _LT_LINKER_HARDCODE_LIBPATH + + +# _LT_CMD_STRIPLIB +# ---------------- +m4_defun([_LT_CMD_STRIPLIB], +[m4_require([_LT_DECL_EGREP]) +striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP"; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac +fi +_LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) +_LT_DECL([], [striplib], [1]) +])# _LT_CMD_STRIPLIB + + +# _LT_PREPARE_MUNGE_PATH_LIST +# --------------------------- +# Make sure func_munge_path_list() is defined correctly. +m4_defun([_LT_PREPARE_MUNGE_PATH_LIST], +[[# func_munge_path_list VARIABLE PATH +# ----------------------------------- +# VARIABLE is name of variable containing _space_ separated list of +# directories to be munged by the contents of PATH, which is string +# having a format: +# "DIR[:DIR]:" +# string "DIR[ DIR]" will be prepended to VARIABLE +# ":DIR[:DIR]" +# string "DIR[ DIR]" will be appended to VARIABLE +# "DIRP[:DIRP]::[DIRA:]DIRA" +# string "DIRP[ DIRP]" will be prepended to VARIABLE and string +# "DIRA[ DIRA]" will be appended to VARIABLE +# "DIR[:DIR]" +# VARIABLE will be replaced by "DIR[ DIR]" +func_munge_path_list () +{ + case x@S|@2 in + x) + ;; + *:) + eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'` \@S|@@S|@1\" + ;; + x:*) + eval @S|@1=\"\@S|@@S|@1 `$ECHO @S|@2 | $SED 's/:/ /g'`\" + ;; + *::*) + eval @S|@1=\"\@S|@@S|@1\ `$ECHO @S|@2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" + eval @S|@1=\"`$ECHO @S|@2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \@S|@@S|@1\" + ;; + *) + eval @S|@1=\"`$ECHO @S|@2 | $SED 's/:/ /g'`\" + ;; + esac +} +]])# _LT_PREPARE_PATH_LIST + + +# _LT_SYS_DYNAMIC_LINKER([TAG]) +# ----------------------------- +# PORTME Fill in your ld.so characteristics +m4_defun([_LT_SYS_DYNAMIC_LINKER], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_OBJDUMP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CHECK_SHELL_FEATURES])dnl +m4_require([_LT_PREPARE_MUNGE_PATH_LIST])dnl +AC_MSG_CHECKING([dynamic linker characteristics]) +m4_if([$1], + [], [ +if test yes = "$GCC"; then + case $host_os in + darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; + *) lt_awk_arg='/^libraries:/' ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;; + *) lt_sed_strip_eq='s|=/|/|g' ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary... + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + # ...but if some path component already ends with the multilib dir we assume + # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). + case "$lt_multi_os_dir; $lt_search_path_spec " in + "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) + lt_multi_os_dir= + ;; + esac + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" + elif test -n "$lt_multi_os_dir"; then + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS = " "; FS = "/|\n";} { + lt_foo = ""; + lt_count = 0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo = "/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[[lt_foo]]++; } + if (lt_freq[[lt_foo]] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=.so +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +AC_ARG_VAR([LT_SYS_LIBRARY_PATH], +[User-defined run-time library search path.]) + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='$libname$release$shared_ext$major' + ;; + +aix[[4-9]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test ia64 = "$host_cpu"; then + # AIX 5 supports IA64 + library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line '#! .'. This would cause the generated library to + # depend on '.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[[01]] | aix4.[[01]].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # Using Import Files as archive members, it is possible to support + # filename-based versioning of shared library archives on AIX. While + # this would work for both with and without runtime linking, it will + # prevent static linking of such archives. So we do filename-based + # shared library versioning with .so extension only, which is used + # when both runtime linking and shared linking is enabled. + # Unfortunately, runtime linking may impact performance, so we do + # not want this to be the default eventually. Also, we use the + # versioned .so libs for executables only if there is the -brtl + # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. + # To allow for filename-based versioning support, we need to create + # libNAME.so.V as an archive file, containing: + # *) an Import File, referring to the versioned filename of the + # archive as well as the shared archive member, telling the + # bitwidth (32 or 64) of that shared object, and providing the + # list of exported symbols of that shared object, eventually + # decorated with the 'weak' keyword + # *) the shared object with the F_LOADONLY flag set, to really avoid + # it being seen by the linker. + # At run time we better use the real file rather than another symlink, + # but for link time we create the symlink libNAME.so -> libNAME.so.V + + case $with_aix_soname,$aix_use_runtimelinking in + # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + aix,yes) # traditional libtool + dynamic_linker='AIX unversionable lib.so' + # If using run time linking (on AIX 4.2 or later) use lib<name>.so + # instead of lib<name>.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + aix,no) # traditional AIX only + dynamic_linker='AIX lib.a[(]lib.so.V[)]' + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + ;; + svr4,*) # full svr4 only + dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)]" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,yes) # both, prefer svr4 + dynamic_linker="AIX lib.so.V[(]$shared_archive_member_spec.o[)], lib.a[(]lib.so.V[)]" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # unpreferred sharedlib libNAME.a needs extra handling + postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' + postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,no) # both, prefer aix + dynamic_linker="AIX lib.a[(]lib.so.V[)], lib.so.V[(]$shared_archive_member_spec.o[)]" + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling + postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' + postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' + ;; + esac + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + m68k) + 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=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; $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' + ;; + esac + ;; + +beos*) + library_names_spec='$libname$shared_ext' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[[45]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + library_names_spec='$libname.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec=$LIB + if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' + soname_spec='$libname$release$major$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' +m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[[23]].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[[01]]* | freebsdelf3.[[01]]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ + freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=no + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + if test 32 = "$HPUX_IA64_MODE"; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + sys_lib_dlsearch_path_spec=/usr/lib/hpux32 + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + sys_lib_dlsearch_path_spec=/usr/lib/hpux64 + fi + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[[3-9]]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test yes = "$lt_cv_prog_gnu_ld"; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" + sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +linux*android*) + version_type=none # Android doesn't support versioned libraries. + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + dynamic_linker='Android linker' + # Don't embed -rpath directories since the linker doesn't support them. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], + [lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ + LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], + [lt_cv_shlibpath_overrides_runpath=yes])]) + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + ]) + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Ideally, we could use ldconfig to report *all* directores which are + # searched for libraries, however this is still not possible. Aside from not + # being certain /sbin/ldconfig is available, command + # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, + # even though it is searched at run-time. Try to do the best guess by + # appending ld.so.conf contents (and includes) to the search path. + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd* | bitrig*) + version_type=sunos + sys_lib_dlsearch_path_spec=/usr/lib + need_lib_prefix=no + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + need_version=no + else + need_version=yes + fi + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +os2*) + libname_spec='$name' + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + # OS/2 can only load a DLL with a base name of 8 characters or less. + soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; + v=$($ECHO $release$versuffix | tr -d .-); + n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); + $ECHO $n$v`$shared_ext' + library_names_spec='${libname}_dll.$libext' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=BEGINLIBPATH + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test yes = "$with_gnu_ld"; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec; then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' + soname_spec='$libname$shared_ext.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=sco + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test yes = "$with_gnu_ld"; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test no = "$dynamic_linker" && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test yes = "$GCC"; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then + sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec +fi + +if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then + sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec +fi + +# remember unaugmented sys_lib_dlsearch_path content for libtool script decls... +configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec + +# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code +func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" + +# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool +configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH + +_LT_DECL([], [variables_saved_for_relink], [1], + [Variables whose values should be saved in libtool wrapper scripts and + restored at link time]) +_LT_DECL([], [need_lib_prefix], [0], + [Do we need the "lib" prefix for modules?]) +_LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) +_LT_DECL([], [version_type], [0], [Library versioning type]) +_LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) +_LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) +_LT_DECL([], [shlibpath_overrides_runpath], [0], + [Is shlibpath searched before the hard-coded library search path?]) +_LT_DECL([], [libname_spec], [1], [Format of library name prefix]) +_LT_DECL([], [library_names_spec], [1], + [[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]]) +_LT_DECL([], [soname_spec], [1], + [[The coded name of the library, if different from the real name]]) +_LT_DECL([], [install_override_mode], [1], + [Permission mode override for installation of shared libraries]) +_LT_DECL([], [postinstall_cmds], [2], + [Command to use after installation of a shared archive]) +_LT_DECL([], [postuninstall_cmds], [2], + [Command to use after uninstallation of a shared archive]) +_LT_DECL([], [finish_cmds], [2], + [Commands used to finish a libtool library installation in a directory]) +_LT_DECL([], [finish_eval], [1], + [[As "finish_cmds", except a single script fragment to be evaled but + not shown]]) +_LT_DECL([], [hardcode_into_libs], [0], + [Whether we should hardcode library paths into libraries]) +_LT_DECL([], [sys_lib_search_path_spec], [2], + [Compile-time system search path for libraries]) +_LT_DECL([sys_lib_dlsearch_path_spec], [configure_time_dlsearch_path], [2], + [Detected run-time system search path for libraries]) +_LT_DECL([], [configure_time_lt_sys_library_path], [2], + [Explicit LT_SYS_LIBRARY_PATH set during ./configure time]) +])# _LT_SYS_DYNAMIC_LINKER + + +# _LT_PATH_TOOL_PREFIX(TOOL) +# -------------------------- +# find a file program that can recognize shared library +AC_DEFUN([_LT_PATH_TOOL_PREFIX], +[m4_require([_LT_DECL_EGREP])dnl +AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in +[[\\/*] | ?:[\\/]*]) + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="m4_if([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$1"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD=$lt_cv_path_MAGIC_CMD + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD + ;; +esac]) +MAGIC_CMD=$lt_cv_path_MAGIC_CMD +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +_LT_DECL([], [MAGIC_CMD], [0], + [Used to examine libraries when file_magic_cmd begins with "file"])dnl +])# _LT_PATH_TOOL_PREFIX + +# Old name: +AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) + + +# _LT_PATH_MAGIC +# -------------- +# find a file program that can recognize a shared library +m4_defun([_LT_PATH_MAGIC], +[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) + else + MAGIC_CMD=: + fi +fi +])# _LT_PATH_MAGIC + + +# LT_PATH_LD +# ---------- +# find the pathname to the GNU or non-GNU linker +AC_DEFUN([LT_PATH_LD], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PROG_ECHO_BACKSLASH])dnl + +AC_ARG_WITH([gnu-ld], + [AS_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld @<:@default=no@:>@])], + [test no = "$withval" || with_gnu_ld=yes], + [with_gnu_ld=no])dnl + +ac_prog=ld +if test yes = "$GCC"; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by $CC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return, which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname 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 yes = "$with_gnu_ld"; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD=$ac_dir/$ac_prog + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in + *GNU* | *'with BFD'*) + test no != "$with_gnu_ld" && break + ;; + *) + test yes != "$with_gnu_ld" && break + ;; + esac + fi + done + IFS=$lt_save_ifs +else + lt_cv_path_LD=$LD # Let the user override the test with a path. +fi]) +LD=$lt_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]) +_LT_PATH_LD_GNU +AC_SUBST([LD]) + +_LT_TAGDECL([], [LD], [1], [The linker used to build libraries]) +])# LT_PATH_LD + +# Old names: +AU_ALIAS([AM_PROG_LD], [LT_PATH_LD]) +AU_ALIAS([AC_PROG_LD], [LT_PATH_LD]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_PROG_LD], []) +dnl AC_DEFUN([AC_PROG_LD], []) + + +# _LT_PATH_LD_GNU +#- -------------- +m4_defun([_LT_PATH_LD_GNU], +[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld, +[# I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 </dev/null` in +*GNU* | *'with BFD'*) + lt_cv_prog_gnu_ld=yes + ;; +*) + lt_cv_prog_gnu_ld=no + ;; +esac]) +with_gnu_ld=$lt_cv_prog_gnu_ld +])# _LT_PATH_LD_GNU + + +# _LT_CMD_RELOAD +# -------------- +# find reload flag for linker +# -- PORTME Some linkers may need a different reload flag. +m4_defun([_LT_CMD_RELOAD], +[AC_CACHE_CHECK([for $LD option to reload object files], + lt_cv_ld_reload_flag, + [lt_cv_ld_reload_flag='-r']) +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + if test yes != "$GCC"; then + reload_cmds=false + fi + ;; + darwin*) + if test yes = "$GCC"; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac +_LT_TAGDECL([], [reload_flag], [1], [How to create reloadable object files])dnl +_LT_TAGDECL([], [reload_cmds], [2])dnl +])# _LT_CMD_RELOAD + + +# _LT_PATH_DD +# ----------- +# find a working dd +m4_defun([_LT_PATH_DD], +[AC_CACHE_CHECK([for a working dd], [ac_cv_path_lt_DD], +[printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +: ${lt_DD:=$DD} +AC_PATH_PROGS_FEATURE_CHECK([lt_DD], [dd], +[if "$ac_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: +fi]) +rm -f conftest.i conftest2.i conftest.out]) +])# _LT_PATH_DD + + +# _LT_CMD_TRUNCATE +# ---------------- +# find command to truncate a binary pipe +m4_defun([_LT_CMD_TRUNCATE], +[m4_require([_LT_PATH_DD]) +AC_CACHE_CHECK([how to truncate binary pipes], [lt_cv_truncate_bin], +[printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +lt_cv_truncate_bin= +if "$ac_cv_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" +fi +rm -f conftest.i conftest2.i conftest.out +test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q"]) +_LT_DECL([lt_truncate_bin], [lt_cv_truncate_bin], [1], + [Command to truncate a binary pipe]) +])# _LT_CMD_TRUNCATE + + +# _LT_CHECK_MAGIC_METHOD +# ---------------------- +# how to check for library dependencies +# -- PORTME fill in with the dynamic library characteristics +m4_defun([_LT_CHECK_MAGIC_METHOD], +[m4_require([_LT_DECL_EGREP]) +m4_require([_LT_DECL_OBJDUMP]) +AC_CACHE_CHECK([how to recognize dependent libraries], +lt_cv_deplibs_check_method, +[lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# 'unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# that responds to the $file_magic_cmd with a given extended regex. +# If you have 'file' or equivalent on your system and you're not sure +# whether 'pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[[4-9]]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[[45]]*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + if ( file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[[3-9]]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd* | bitrig*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +os2*) + lt_cv_deplibs_check_method=pass_all + ;; +esac +]) + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + +_LT_DECL([], [deplibs_check_method], [1], + [Method to check whether dependent libraries are shared objects]) +_LT_DECL([], [file_magic_cmd], [1], + [Command to use when deplibs_check_method = "file_magic"]) +_LT_DECL([], [file_magic_glob], [1], + [How to find potential files when deplibs_check_method = "file_magic"]) +_LT_DECL([], [want_nocaseglob], [1], + [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) +])# _LT_CHECK_MAGIC_METHOD + + +# LT_PATH_NM +# ---------- +# find the pathname to a BSD- or MS-compatible name lister +AC_DEFUN([LT_PATH_NM], +[AC_REQUIRE([AC_PROG_CC])dnl +AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM=$NM +else + lt_nm_to_check=${ac_tool_prefix}nm + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + tmp_nm=$ac_dir/$lt_tmp_nm + if test -f "$tmp_nm" || test -f "$tmp_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 + # Tru64's nm complains that /dev/null is an invalid object file + # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty + case $build_os in + mingw*) lt_bad_file=conftest.nm/nofile ;; + *) lt_bad_file=/dev/null ;; + esac + case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in + *$lt_bad_file* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break 2 + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break 2 + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS=$lt_save_ifs + done + : ${lt_cv_path_NM=no} +fi]) +if test no != "$lt_cv_path_NM"; then + NM=$lt_cv_path_NM +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) + case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols -headers" + ;; + *) + DUMPBIN=: + ;; + esac + fi + AC_SUBST([DUMPBIN]) + if test : != "$DUMPBIN"; then + NM=$DUMPBIN + fi +fi +test -z "$NM" && NM=nm +AC_SUBST([NM]) +_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl + +AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], + [lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&AS_MESSAGE_LOG_FD + (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) + cat conftest.out >&AS_MESSAGE_LOG_FD + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest*]) +])# LT_PATH_NM + +# Old names: +AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) +AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_PROG_NM], []) +dnl AC_DEFUN([AC_PROG_NM], []) + +# _LT_CHECK_SHAREDLIB_FROM_LINKLIB +# -------------------------------- +# how to determine the name of the shared library +# associated with a specific link library. +# -- PORTME fill in with the dynamic library characteristics +m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], +[m4_require([_LT_DECL_EGREP]) +m4_require([_LT_DECL_OBJDUMP]) +m4_require([_LT_DECL_DLLTOOL]) +AC_CACHE_CHECK([how to associate runtime and link libraries], +lt_cv_sharedlib_from_linklib_cmd, +[lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh; + # decide which one to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd=$ECHO + ;; +esac +]) +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + +_LT_DECL([], [sharedlib_from_linklib_cmd], [1], + [Command to associate shared and link libraries]) +])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB + + +# _LT_PATH_MANIFEST_TOOL +# ---------------------- +# locate the manifest tool +m4_defun([_LT_PATH_MANIFEST_TOOL], +[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], + [lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&AS_MESSAGE_LOG_FD + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest*]) +if test yes != "$lt_cv_path_mainfest_tool"; then + MANIFEST_TOOL=: +fi +_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl +])# _LT_PATH_MANIFEST_TOOL + + +# _LT_DLL_DEF_P([FILE]) +# --------------------- +# True iff FILE is a Windows DLL '.def' file. +# Keep in sync with func_dll_def_p in the libtool script +AC_DEFUN([_LT_DLL_DEF_P], +[dnl + test DEF = "`$SED -n dnl + -e '\''s/^[[ ]]*//'\'' dnl Strip leading whitespace + -e '\''/^\(;.*\)*$/d'\'' dnl Delete empty lines and comments + -e '\''s/^\(EXPORTS\|LIBRARY\)\([[ ]].*\)*$/DEF/p'\'' dnl + -e q dnl Only consider the first "real" line + $1`" dnl +])# _LT_DLL_DEF_P + + +# LT_LIB_M +# -------- +# check for math library +AC_DEFUN([LT_LIB_M], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) + # These system don't have libm, or don't need it + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM=-lmw) + AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, cos, LIBM=-lm) + ;; +esac +AC_SUBST([LIBM]) +])# LT_LIB_M + +# Old name: +AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_CHECK_LIBM], []) + + +# _LT_COMPILER_NO_RTTI([TAGNAME]) +# ------------------------------- +m4_defun([_LT_COMPILER_NO_RTTI], +[m4_require([_LT_TAG_COMPILER])dnl + +_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + +if test yes = "$GCC"; then + case $cc_basename in + nvcc*) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; + *) + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; + esac + + _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], + lt_cv_prog_compiler_rtti_exceptions, + [-fno-rtti -fno-exceptions], [], + [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) +fi +_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], + [Compiler flag to turn off builtin functions]) +])# _LT_COMPILER_NO_RTTI + + +# _LT_CMD_GLOBAL_SYMBOLS +# ---------------------- +m4_defun([_LT_CMD_GLOBAL_SYMBOLS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([LT_PATH_NM])dnl +AC_REQUIRE([LT_PATH_LD])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_TAG_COMPILER])dnl + +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output from $compiler object]) +AC_CACHE_VAL([lt_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?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[[BCDEGRST]]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) + if test ia64 = "$host_cpu"; then + symcode='[[ABCDEGRST]]' + fi + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris*) + symcode='[[BDRT]]' + ;; +sco3.2v5*) + symcode='[[DT]]' + ;; +sysv4.2uw2*) + symcode='[[DT]]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[[ABDT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[[ABCDGIRSTW]]' ;; +esac + +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Gets list of data symbols to import. + lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" + # Adjust the below global symbol transforms to fixup imported variables. + lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" + lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" + lt_c_name_lib_hook="\ + -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ + -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" +else + # Disable hooks by default. + lt_cv_sys_global_symbol_to_import= + lt_cdecl_hook= + lt_c_name_hook= + lt_c_name_lib_hook= +fi + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n"\ +$lt_cdecl_hook\ +" -e 's/^T .* \(.*\)$/extern int \1();/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ +$lt_c_name_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" + +# Transform an extracted symbol line into symbol name with lib prefix and +# symbol address. +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ +$lt_c_name_lib_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function, + # D for any global variable and I for any imported variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK ['"\ +" {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ +" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ +" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ +" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ +" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx]" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if AC_TRY_EVAL(ac_compile); then + # Now try to grab the symbols. + nlist=conftest.nm + if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE +/* DATA imports from DLLs on WIN32 can't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT@&t@_DLSYM_CONST +#elif defined __osf__ +/* This system does not cope well with relocations in const data. */ +# define LT@&t@_DLSYM_CONST +#else +# define LT@&t@_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT@&t@_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[[]] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS=conftstm.$ac_objext + CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" + if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + else + echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD + fi + else + echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test yes = "$pipe_works"; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + +_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], + [Take the output of nm and produce a listing of raw symbols and C names]) +_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], + [Transform the output of nm in a proper C declaration]) +_LT_DECL([global_symbol_to_import], [lt_cv_sys_global_symbol_to_import], [1], + [Transform the output of nm into a list of symbols to manually relocate]) +_LT_DECL([global_symbol_to_c_name_address], + [lt_cv_sys_global_symbol_to_c_name_address], [1], + [Transform the output of nm in a C name address pair]) +_LT_DECL([global_symbol_to_c_name_address_lib_prefix], + [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], + [Transform the output of nm in a C name address pair when lib prefix is needed]) +_LT_DECL([nm_interface], [lt_cv_nm_interface], [1], + [The name lister interface]) +_LT_DECL([], [nm_file_list_spec], [1], + [Specify filename containing input files for $NM]) +]) # _LT_CMD_GLOBAL_SYMBOLS + + +# _LT_COMPILER_PIC([TAGNAME]) +# --------------------------- +m4_defun([_LT_COMPILER_PIC], +[m4_require([_LT_TAG_COMPILER])dnl +_LT_TAGVAR(lt_prog_compiler_wl, $1)= +_LT_TAGVAR(lt_prog_compiler_pic, $1)= +_LT_TAGVAR(lt_prog_compiler_static, $1)= + +m4_if([$1], [CXX], [ + # C++ specific cases for pic, static, wl, etc. + if test yes = "$GXX"; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + case $host_os in + os2*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' + ;; + esac + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + case $host_os in + aix[[4-9]]*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + mingw* | cygwin* | os2* | pw32* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + ;; + dgux*) + case $cc_basename in + ec++*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' + if test ia64 != "$host_cpu"; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + fi + ;; + aCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + KCC*) + # KAI C++ Compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + ecpc* ) + # old Intel C++ for x86_64, which still supported -KPIC. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + icpc* ) + # Intel C++, used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) + # IBM XL 8.0, 9.0 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + esac + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd*) + ;; + *qnx* | *nto*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + cxx*) + # Digital/Compaq C++ + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + lcc*) + # Lucid + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + *) + ;; + esac + ;; + vxworks*) + ;; + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +], +[ + if test yes = "$GCC"; then + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + case $host_os in + os2*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' + ;; + esac + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + _LT_TAGVAR(lt_prog_compiler_static, $1)= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' + if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + case $cc_basename in + nagfor*) + # NAG Fortran compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + m4_if([$1], [GCJ], [], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) + case $host_os in + os2*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-static' + ;; + esac + ;; + + hpux9* | hpux10* | hpux11*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + _LT_TAGVAR(lt_prog_compiler_static, $1)='$wl-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC (with -KPIC) is the default. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + # old Intel for x86_64, which still supported -KPIC. + ecc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' + _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' + ;; + nagfor*) + # NAG Fortran compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + ccc*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All Alpha code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='' + ;; + *Sun\ F* | *Sun*Fortran*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + *Intel*\ [[CF]]*Compiler*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + *Portland\ Group*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All OSF/1 code is PIC. + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + rdos*) + _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + solaris*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; + *) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; + esac + ;; + + sunos4*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + unicos*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + + uts4*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *) + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +]) +case $host_os in + # For platforms that do not support PIC, -DPIC is meaningless: + *djgpp*) + _LT_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + *) + _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" + ;; +esac + +AC_CACHE_CHECK([for $compiler option to produce PIC], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], + [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) +_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then + _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], + [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], + [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], + [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in + "" | " "*) ;; + *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; + esac], + [_LT_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) +fi +_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], + [Additional compiler flags for building library objects]) + +_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], + [How to pass a linker flag through the compiler]) +# +# Check to make sure the static flag actually works. +# +wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" +_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], + _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), + $lt_tmp_static_flag, + [], + [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) +_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], + [Compiler flag to prevent dynamic linking]) +])# _LT_COMPILER_PIC + + +# _LT_LINKER_SHLIBS([TAGNAME]) +# ---------------------------- +# See if the linker supports building shared libraries. +m4_defun([_LT_LINKER_SHLIBS], +[AC_REQUIRE([LT_PATH_LD])dnl +AC_REQUIRE([LT_PATH_NM])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_DECL_SED])dnl +m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl +m4_require([_LT_TAG_COMPILER])dnl +AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +m4_if([$1], [CXX], [ + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + case $host_os in + aix[[4-9]]*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds + ;; + cygwin* | mingw* | cegcc*) + case $cc_basename in + cl*) + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + ;; + esac + ;; + *) + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac +], [ + runpath_var= + _LT_TAGVAR(allow_undefined_flag, $1)= + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(archive_cmds, $1)= + _LT_TAGVAR(archive_expsym_cmds, $1)= + _LT_TAGVAR(compiler_needs_object, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(hardcode_automatic, $1)=no + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(hardcode_libdir_separator, $1)= + _LT_TAGVAR(hardcode_minus_L, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_TAGVAR(inherit_rpath, $1)=no + _LT_TAGVAR(link_all_deplibs, $1)=unknown + _LT_TAGVAR(module_cmds, $1)= + _LT_TAGVAR(module_expsym_cmds, $1)= + _LT_TAGVAR(old_archive_from_new_cmds, $1)= + _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= + _LT_TAGVAR(thread_safe_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + _LT_TAGVAR(include_expsyms, $1)= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ' (' and ')$', so one must not match beginning or + # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', + # as well as any symbol that contains 'd'. + _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. +dnl Note also adjust exclude_expsyms for C++ above. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test yes != "$GCC"; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd* | bitrig*) + with_gnu_ld=no + ;; + esac + + _LT_TAGVAR(ld_shlibs, $1)=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test yes = "$with_gnu_ld"; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; + *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test yes = "$lt_use_gnu_ld_interface"; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='$wl' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + supports_anon_versioning=no + case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[[3-9]]*) + # On AIX/PPC, the GNU linker is very broken + if test ia64 != "$host_cpu"; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach <jrb3@best.com> says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' + _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + shrext_cmds=.dll + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test linux-dietlibc = "$host_os"; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test no = "$tmp_diet" + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + _LT_TAGVAR(whole_archive_flag_spec, $1)= + tmp_sharedflag='--shared' ;; + nagfor*) # NAGFOR 5.3 + tmp_sharedflag='-Wl,-shared' ;; + xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + + if test yes = "$supports_anon_versioning"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + tcc*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic' + ;; + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test yes = "$supports_anon_versioning"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) + _LT_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + sunos4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + + if test no = "$_LT_TAGVAR(ld_shlibs, $1)"; then + runpath_var= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + _LT_TAGVAR(hardcode_direct, $1)=unsupported + fi + ;; + + aix[[4-9]]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' + else + _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then + aix_use_runtimelinking=yes + break + fi + done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # traditional, no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + ;; + esac + + if test yes = "$GCC"; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`$CC -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + ;; + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag="$shared_flag "'$wl-G' + fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared libraries. + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='' + ;; + m68k) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + ;; + + bsdi[[45]]*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + # FIXME: Should let the user specify the lib program. + _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + esac + ;; + + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + dgux*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # 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*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + hpux9*) + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + ;; + + hpux10*) + if test yes,no = "$GCC,$with_gnu_ld"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + fi + ;; + + hpux11*) + if test yes,no = "$GCC,$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + m4_if($1, [], [ + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + _LT_LINKER_OPTION([if $CC understands -b], + _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], + [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], + [_LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) + ;; + esac + fi + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], + [lt_cv_irix_exported_symbol], + [save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" + AC_LINK_IFELSE( + [AC_LANG_SOURCE( + [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], + [C++], [[int foo (void) { return 0; }]], + [Fortran 77], [[ + subroutine foo + end]], + [Fortran], [[ + subroutine foo + end]])])], + [lt_cv_irix_exported_symbol=yes], + [lt_cv_irix_exported_symbol=no]) + LDFLAGS=$save_LDFLAGS]) + if test yes = "$lt_cv_irix_exported_symbol"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' + fi + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + linux*) + case $cc_basename in + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + _LT_TAGVAR(ld_shlibs, $1)=yes + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + newsos6) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *nto* | *qnx*) + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + fi + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + shrext_cmds=.dll + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + osf3*) + if test yes = "$GCC"; then + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test yes = "$GCC"; then + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + else + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)='no' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + solaris*) + _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' + if test yes = "$GCC"; then + wlarc='$wl' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + _LT_TAGVAR(archive_cmds, $1)='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='$wl' + _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. GCC discards it without '$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test yes = "$GCC"; then + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + fi + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + sunos4*) + if test sequent = "$host_vendor"; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4) + case $host_vendor in + sni) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' + _LT_TAGVAR(hardcode_direct, $1)=no + ;; + motorola) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4.3*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + _LT_TAGVAR(ld_shlibs, $1)=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + if test sni = "$host_vendor"; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Blargedynsym' + ;; + esac + fi + fi +]) +AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) +test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no + +_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld + +_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl +_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl +_LT_DECL([], [extract_expsyms_cmds], [2], + [The commands to extract the exported symbol list from a shared archive]) + +# +# Do we need to explicitly link libc? +# +case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in +x|xyes) + # Assume -lc should be added + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + + if test yes,yes = "$GCC,$enable_shared"; then + case $_LT_TAGVAR(archive_cmds, $1) in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_CACHE_CHECK([whether -lc should be explicitly linked in], + [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), + [$RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile) 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) + pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) + _LT_TAGVAR(allow_undefined_flag, $1)= + if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) + then + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no + else + lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes + fi + _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + ]) + _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) + ;; + esac + fi + ;; +esac + +_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], + [Whether or not to add -lc for building shared libraries]) +_LT_TAGDECL([allow_libtool_libs_with_static_runtimes], + [enable_shared_with_static_runtimes], [0], + [Whether or not to disallow shared libs when runtime libs are static]) +_LT_TAGDECL([], [export_dynamic_flag_spec], [1], + [Compiler flag to allow reflexive dlopens]) +_LT_TAGDECL([], [whole_archive_flag_spec], [1], + [Compiler flag to generate shared objects directly from archives]) +_LT_TAGDECL([], [compiler_needs_object], [1], + [Whether the compiler copes with passing no objects directly]) +_LT_TAGDECL([], [old_archive_from_new_cmds], [2], + [Create an old-style archive from a shared archive]) +_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], + [Create a temporary old-style archive to link instead of a shared archive]) +_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) +_LT_TAGDECL([], [archive_expsym_cmds], [2]) +_LT_TAGDECL([], [module_cmds], [2], + [Commands used to build a loadable module if different from building + a shared archive.]) +_LT_TAGDECL([], [module_expsym_cmds], [2]) +_LT_TAGDECL([], [with_gnu_ld], [1], + [Whether we are building with GNU ld or not]) +_LT_TAGDECL([], [allow_undefined_flag], [1], + [Flag that allows shared libraries with undefined symbols to be built]) +_LT_TAGDECL([], [no_undefined_flag], [1], + [Flag that enforces no undefined symbols]) +_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], + [Flag to hardcode $libdir into a binary during linking. + This must work even if $libdir does not exist]) +_LT_TAGDECL([], [hardcode_libdir_separator], [1], + [Whether we need a single "-rpath" flag with a separated argument]) +_LT_TAGDECL([], [hardcode_direct], [0], + [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes + DIR into the resulting binary]) +_LT_TAGDECL([], [hardcode_direct_absolute], [0], + [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes + DIR into the resulting binary and the resulting library dependency is + "absolute", i.e impossible to change by setting $shlibpath_var if the + library is relocated]) +_LT_TAGDECL([], [hardcode_minus_L], [0], + [Set to "yes" if using the -LDIR flag during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_shlibpath_var], [0], + [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR + into the resulting binary]) +_LT_TAGDECL([], [hardcode_automatic], [0], + [Set to "yes" if building a shared library automatically hardcodes DIR + into the library and all subsequent libraries and executables linked + against it]) +_LT_TAGDECL([], [inherit_rpath], [0], + [Set to yes if linker adds runtime paths of dependent libraries + to runtime path list]) +_LT_TAGDECL([], [link_all_deplibs], [0], + [Whether libtool must link a program against all its dependency libraries]) +_LT_TAGDECL([], [always_export_symbols], [0], + [Set to "yes" if exported symbols are required]) +_LT_TAGDECL([], [export_symbols_cmds], [2], + [The commands to list exported symbols]) +_LT_TAGDECL([], [exclude_expsyms], [1], + [Symbols that should not be listed in the preloaded symbols]) +_LT_TAGDECL([], [include_expsyms], [1], + [Symbols that must always be exported]) +_LT_TAGDECL([], [prelink_cmds], [2], + [Commands necessary for linking programs (against libraries) with templates]) +_LT_TAGDECL([], [postlink_cmds], [2], + [Commands necessary for finishing linking programs]) +_LT_TAGDECL([], [file_list_spec], [1], + [Specify filename containing input files]) +dnl FIXME: Not yet implemented +dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], +dnl [Compiler flag to generate thread safe objects]) +])# _LT_LINKER_SHLIBS + + +# _LT_LANG_C_CONFIG([TAG]) +# ------------------------ +# Ensure that the configuration variables for a C compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_C_CONFIG], +[m4_require([_LT_DECL_EGREP])dnl +lt_save_CC=$CC +AC_LANG_PUSH(C) + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + +_LT_TAG_COMPILER +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + LT_SYS_DLOPEN_SELF + _LT_CMD_STRIPLIB + + # Report what library types will actually be built + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[[4-9]]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_CONFIG($1) +fi +AC_LANG_POP +CC=$lt_save_CC +])# _LT_LANG_C_CONFIG + + +# _LT_LANG_CXX_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a C++ compiler are suitably +# defined. These variables are subsequently used by _LT_CONFIG to write +# the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_CXX_CONFIG], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +m4_require([_LT_DECL_EGREP])dnl +m4_require([_LT_PATH_MANIFEST_TOOL])dnl +if test -n "$CXX" && ( test no != "$CXX" && + ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || + (test g++ != "$CXX"))); then + AC_PROG_CXXCPP +else + _lt_caught_CXX_error=yes +fi + +AC_LANG_PUSH(C++) +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(compiler_needs_object, $1)=no +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the CXX compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test yes != "$_lt_caught_CXX_error"; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="int some_variable = 0;" + + # Code to be used in simple link tests + lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_CFLAGS=$CFLAGS + lt_save_LD=$LD + lt_save_GCC=$GCC + GCC=$GXX + lt_save_with_gnu_ld=$with_gnu_ld + lt_save_path_LD=$lt_cv_path_LD + if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx + else + $as_unset lt_cv_prog_gnu_ld + fi + if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX + else + $as_unset lt_cv_path_LD + fi + test -z "${LDCXX+set}" || LD=$LDCXX + CC=${CXX-"c++"} + CFLAGS=$CXXFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + # We don't want -fno-exception when compiling C++ code, so set the + # no_builtin_flag separately + if test yes = "$GXX"; then + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' + else + _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + fi + + if test yes = "$GXX"; then + # Set up default GNU C++ configuration + + LT_PATH_LD + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test yes = "$with_gnu_ld"; then + _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='$wl' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | + $GREP 'no-whole-archive' > /dev/null; then + _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + _LT_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + GXX=no + with_gnu_ld=no + wlarc= + fi + + # PORTME: fill in a description of your system's C++ link characteristics + AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) + _LT_TAGVAR(ld_shlibs, $1)=yes + case $host_os in + aix3*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aix[[4-9]]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_TAGVAR(archive_cmds, $1)='' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=no + ;; + esac + + if test yes = "$GXX"; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`$CC -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + _LT_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)= + fi + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag=$shared_flag' $wl-G' + fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' + fi + fi + + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to + # export. + _LT_TAGVAR(always_export_symbols, $1)=yes + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + # The "-G" linker flag allows undefined symbols. + _LT_TAGVAR(no_undefined_flag, $1)='-bernotok' + # Determine the default libpath from the value encoded in an empty + # executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $libdir:/usr/lib:/lib' + _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + _LT_SYS_MODULE_PATH_AIX([$1]) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_TAGVAR(no_undefined_flag, $1)=' $wl-bernotok' + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + fi + _LT_TAGVAR(archive_cmds_need_lc, $1)=yes + _LT_TAGVAR(archive_expsym_cmds, $1)='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([[, ]]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared + # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + _LT_TAGVAR(archive_expsym_cmds, $1)="$_LT_TAGVAR(archive_expsym_cmds, $1)"'~$RM -r $output_objdir/$realname.d' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach <jrb3@best.com> says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + cygwin* | mingw* | pw32* | cegcc*) + case $GXX,$cc_basename in + ,cl* | no,cl*) + # Native MSVC + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + # Don't use ranlib + _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' + _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + func_to_tool_file "$lt_outputfile"~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # g++ + # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-all-symbols' + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_TAGVAR(always_export_symbols, $1)=no + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + darwin* | rhapsody*) + _LT_DARWIN_LINKER_FEATURES($1) + ;; + + os2*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_TAGVAR(hardcode_minus_L, $1)=yes + _LT_TAGVAR(allow_undefined_flag, $1)=unsupported + shrext_cmds=.dll + _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(archive_expsym_cmds, $1)='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + freebsd2.*) + # C++ shared libraries reported to be fairly broken before + # switch to ELF + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + freebsd-elf*) + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + haiku*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + + hpux9*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes = "$GXX"; then + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + hpux10*|hpux11*) + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + interix[[3-9]]*) + _LT_TAGVAR(hardcode_direct, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test yes = "$GXX"; then + if test no = "$with_gnu_ld"; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' + fi + fi + _LT_TAGVAR(link_all_deplibs, $1)=yes + ;; + esac + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_TAGVAR(inherit_rpath, $1)=yes + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc* | ecpc* ) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive$convenience $wl--no-whole-archive' + ;; + pgCC* | pgcpp*) + # Portland Group C++ compiler + case `$CC -V` in + *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) + _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ + compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' + _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ + $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ + $RANLIB $oldlib' + _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ + rm -rf $tpldir~ + $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ + $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 6 and above use weak symbols + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl--rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + ;; + cxx*) + # Compaq C++ + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' + ;; + xl* | mpixl* | bgxl*) + # IBM XL 8.0 on PPC, with GNU ld + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl--export-dynamic' + _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + if test yes = "$supports_anon_versioning"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + _LT_TAGVAR(compiler_needs_object, $1)=yes + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; + esac + ;; + + lynxos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + m88k*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + + *nto* | *qnx*) + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + _LT_TAGVAR(hardcode_direct, $1)=yes + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_direct_absolute, $1)=yes + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-E' + _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + fi + output_verbose_link_cmd=func_echo_all + else + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + case $host in + osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; + *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; + esac + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + cxx*) + case $host in + osf3*) + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + ;; + *) + _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_TAGVAR(archive_cmds, $1)='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ + $RM $lib.exp' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + ;; + *) + if test yes,no = "$GXX,$with_gnu_ld"; then + _LT_TAGVAR(allow_undefined_flag, $1)=' $wl-expect_unresolved $wl\*' + case $host in + osf3*) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + ;; + esac + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + psos*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + solaris*) + case $cc_basename in + CC* | sunCC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_TAGVAR(archive_cmds_need_lc,$1)=yes + _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_TAGVAR(archive_cmds, $1)='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. + # Supported since Solaris 2.6 (maybe 2.5.1?) + _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + ;; + esac + _LT_TAGVAR(link_all_deplibs, $1)=yes + + output_verbose_link_cmd='func_echo_all' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test yes,no = "$GXX,$with_gnu_ld"; then + _LT_TAGVAR(no_undefined_flag, $1)=' $wl-z ${wl}defs' + if $CC --version | $GREP -v '^2\.7' > /dev/null; then + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + else + # g++ 2.7 appears to require '-G' NOT '-shared' on this + # platform. + _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + fi + + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir' + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + ;; + esac + fi + ;; + esac + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_TAGVAR(no_undefined_flag, $1)='$wl-z,text' + _LT_TAGVAR(allow_undefined_flag, $1)='$wl-z,nodefs' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R,$libdir' + _LT_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(export_dynamic_flag_spec, $1)='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_TAGVAR(archive_cmds, $1)='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ + '"$_LT_TAGVAR(old_archive_cmds, $1)" + _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ + '"$_LT_TAGVAR(reload_cmds, $1)" + ;; + *) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + vxworks*) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + + *) + # FIXME: insert proper C++ library support + _LT_TAGVAR(ld_shlibs, $1)=no + ;; + esac + + AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) + test no = "$_LT_TAGVAR(ld_shlibs, $1)" && can_build_shared=no + + _LT_TAGVAR(GCC, $1)=$GXX + _LT_TAGVAR(LD, $1)=$LD + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS + LDCXX=$LD + LD=$lt_save_LD + GCC=$lt_save_GCC + with_gnu_ld=$lt_save_with_gnu_ld + lt_cv_path_LDCXX=$lt_cv_path_LD + lt_cv_path_LD=$lt_save_path_LD + lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld + lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +fi # test yes != "$_lt_caught_CXX_error" + +AC_LANG_POP +])# _LT_LANG_CXX_CONFIG + + +# _LT_FUNC_STRIPNAME_CNF +# ---------------------- +# func_stripname_cnf prefix suffix name +# strip PREFIX and SUFFIX off of NAME. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +# +# This function is identical to the (non-XSI) version of func_stripname, +# except this one can be used by m4 code that may be executed by configure, +# rather than the libtool script. +m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl +AC_REQUIRE([_LT_DECL_SED]) +AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) +func_stripname_cnf () +{ + case @S|@2 in + .*) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%\\\\@S|@2\$%%"`;; + *) func_stripname_result=`$ECHO "@S|@3" | $SED "s%^@S|@1%%; s%@S|@2\$%%"`;; + esac +} # func_stripname_cnf +])# _LT_FUNC_STRIPNAME_CNF + + +# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) +# --------------------------------- +# Figure out "hidden" library dependencies from verbose +# compiler output when linking a shared library. +# Parse the compiler output and extract the necessary +# objects, libraries and library flags. +m4_defun([_LT_SYS_HIDDEN_LIBDEPS], +[m4_require([_LT_FILEUTILS_DEFAULTS])dnl +AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl +# Dependencies to place before and after the object being linked: +_LT_TAGVAR(predep_objects, $1)= +_LT_TAGVAR(postdep_objects, $1)= +_LT_TAGVAR(predeps, $1)= +_LT_TAGVAR(postdeps, $1)= +_LT_TAGVAR(compiler_lib_search_path, $1)= + +dnl we can't use the lt_simple_compile_test_code here, +dnl because it contains code intended for an executable, +dnl not a library. It's possible we should let each +dnl tag define a new lt_????_link_test_code variable, +dnl but it's only used here... +m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF +int a; +void foo (void) { a = 0; } +_LT_EOF +], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +_LT_EOF +], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer*4 a + a=0 + return + end +_LT_EOF +], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF + subroutine foo + implicit none + integer a + a=0 + return + end +_LT_EOF +], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF +public class foo { + private int a; + public void bar (void) { + a = 0; + } +}; +_LT_EOF +], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF +package foo +func foo() { +} +_LT_EOF +]) + +_lt_libdeps_save_CFLAGS=$CFLAGS +case "$CC $CFLAGS " in #( +*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; +*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; +*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; +esac + +dnl Parse the compiler output and extract the necessary +dnl objects, libraries and library flags. +if AC_TRY_EVAL(ac_compile); then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + for p in `eval "$output_verbose_link_cmd"`; do + case $prev$p in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test x-L = "$p" || + test x-R = "$p"; then + prev=$p + continue + fi + + # Expand the sysroot to ease extracting the directories later. + if test -z "$prev"; then + case $p in + -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; + -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; + -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; + esac + fi + case $p in + =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; + esac + if test no = "$pre_test_object_deps_done"; then + case $prev in + -L | -R) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then + _LT_TAGVAR(compiler_lib_search_path, $1)=$prev$p + else + _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} $prev$p" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$_LT_TAGVAR(postdeps, $1)"; then + _LT_TAGVAR(postdeps, $1)=$prev$p + else + _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} $prev$p" + fi + fi + prev= + ;; + + *.lto.$objext) ;; # Ignore GCC LTO objects + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test no = "$pre_test_object_deps_done"; then + if test -z "$_LT_TAGVAR(predep_objects, $1)"; then + _LT_TAGVAR(predep_objects, $1)=$p + else + _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" + fi + else + if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then + _LT_TAGVAR(postdep_objects, $1)=$p + else + _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling $1 test program" +fi + +$RM -f confest.$objext +CFLAGS=$_lt_libdeps_save_CFLAGS + +# PORTME: override above test on systems where it is broken +m4_if([$1], [CXX], +[case $host_os in +interix[[3-9]]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + _LT_TAGVAR(predep_objects,$1)= + _LT_TAGVAR(postdep_objects,$1)= + _LT_TAGVAR(postdeps,$1)= + ;; +esac +]) + +case " $_LT_TAGVAR(postdeps, $1) " in +*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; +esac + _LT_TAGVAR(compiler_lib_search_dirs, $1)= +if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then + _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | $SED -e 's! -L! !g' -e 's!^ !!'` +fi +_LT_TAGDECL([], [compiler_lib_search_dirs], [1], + [The directories searched by this compiler when creating a shared library]) +_LT_TAGDECL([], [predep_objects], [1], + [Dependencies to place before and after the objects being linked to + create a shared library]) +_LT_TAGDECL([], [postdep_objects], [1]) +_LT_TAGDECL([], [predeps], [1]) +_LT_TAGDECL([], [postdeps], [1]) +_LT_TAGDECL([], [compiler_lib_search_path], [1], + [The library search path used internally by the compiler when linking + a shared library]) +])# _LT_SYS_HIDDEN_LIBDEPS + + +# _LT_LANG_F77_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for a Fortran 77 compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_F77_CONFIG], +[AC_LANG_PUSH(Fortran 77) +if test -z "$F77" || test no = "$F77"; then + _lt_disable_F77=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for f77 test sources. +ac_ext=f + +# Object file extension for compiled f77 test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the F77 compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test yes != "$_lt_disable_F77"; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${F77-"f77"} + CFLAGS=$FFLAGS + compiler=$CC + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + GCC=$G77 + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)=$G77 + _LT_TAGVAR(LD, $1)=$LD + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS +fi # test yes != "$_lt_disable_F77" + +AC_LANG_POP +])# _LT_LANG_F77_CONFIG + + +# _LT_LANG_FC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for a Fortran compiler are +# suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_FC_CONFIG], +[AC_LANG_PUSH(Fortran) + +if test -z "$FC" || test no = "$FC"; then + _lt_disable_FC=yes +fi + +_LT_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_TAGVAR(allow_undefined_flag, $1)= +_LT_TAGVAR(always_export_symbols, $1)=no +_LT_TAGVAR(archive_expsym_cmds, $1)= +_LT_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_TAGVAR(hardcode_direct, $1)=no +_LT_TAGVAR(hardcode_direct_absolute, $1)=no +_LT_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_TAGVAR(hardcode_libdir_separator, $1)= +_LT_TAGVAR(hardcode_minus_L, $1)=no +_LT_TAGVAR(hardcode_automatic, $1)=no +_LT_TAGVAR(inherit_rpath, $1)=no +_LT_TAGVAR(module_cmds, $1)= +_LT_TAGVAR(module_expsym_cmds, $1)= +_LT_TAGVAR(link_all_deplibs, $1)=unknown +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds +_LT_TAGVAR(no_undefined_flag, $1)= +_LT_TAGVAR(whole_archive_flag_spec, $1)= +_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for fc test sources. +ac_ext=${ac_fc_srcext-f} + +# Object file extension for compiled fc test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# No sense in running all these tests if we already determined that +# the FC compiler isn't working. Some variables (like enable_shared) +# are currently assumed to apply to all compilers on this platform, +# and will be corrupted by setting them based on a non-working compiler. +if test yes != "$_lt_disable_FC"; then + # Code to be used in simple compile tests + lt_simple_compile_test_code="\ + subroutine t + return + end +" + + # Code to be used in simple link tests + lt_simple_link_test_code="\ + program t + end +" + + # ltmain only uses $CC for tagged configurations so make sure $CC is set. + _LT_TAG_COMPILER + + # save warnings/boilerplate of simple test code + _LT_COMPILER_BOILERPLATE + _LT_LINKER_BOILERPLATE + + # Allow CC to be a program name with arguments. + lt_save_CC=$CC + lt_save_GCC=$GCC + lt_save_CFLAGS=$CFLAGS + CC=${FC-"f95"} + CFLAGS=$FCFLAGS + compiler=$CC + GCC=$ac_cv_fc_compiler_gnu + + _LT_TAGVAR(compiler, $1)=$CC + _LT_CC_BASENAME([$compiler]) + + if test -n "$compiler"; then + AC_MSG_CHECKING([if libtool supports shared libraries]) + AC_MSG_RESULT([$can_build_shared]) + + AC_MSG_CHECKING([whether to build shared libraries]) + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + aix[[4-9]]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + AC_MSG_RESULT([$enable_shared]) + + AC_MSG_CHECKING([whether to build static libraries]) + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + AC_MSG_RESULT([$enable_static]) + + _LT_TAGVAR(GCC, $1)=$ac_cv_fc_compiler_gnu + _LT_TAGVAR(LD, $1)=$LD + + ## CAVEAT EMPTOR: + ## There is no encapsulation within the following macros, do not change + ## the running order or otherwise move them around unless you know exactly + ## what you are doing... + _LT_SYS_HIDDEN_LIBDEPS($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_SYS_DYNAMIC_LINKER($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) + fi # test -n "$compiler" + + GCC=$lt_save_GCC + CC=$lt_save_CC + CFLAGS=$lt_save_CFLAGS +fi # test yes != "$_lt_disable_FC" + +AC_LANG_POP +])# _LT_LANG_FC_CONFIG + + +# _LT_LANG_GCJ_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Java Compiler compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_GCJ_CONFIG], +[AC_REQUIRE([LT_PROG_GCJ])dnl +AC_LANG_SAVE + +# Source file extension for Java test sources. +ac_ext=java + +# Object file extension for compiled Java test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="class foo {}" + +# Code to be used in simple link tests +lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GCJ-"gcj"} +CFLAGS=$GCJFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)=$LD +_LT_CC_BASENAME([$compiler]) + +# GCJ did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GCJ_CONFIG + + +# _LT_LANG_GO_CONFIG([TAG]) +# -------------------------- +# Ensure that the configuration variables for the GNU Go compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_GO_CONFIG], +[AC_REQUIRE([LT_PROG_GO])dnl +AC_LANG_SAVE + +# Source file extension for Go test sources. +ac_ext=go + +# Object file extension for compiled Go test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="package main; func main() { }" + +# Code to be used in simple link tests +lt_simple_link_test_code='package main; func main() { }' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC=yes +CC=${GOC-"gccgo"} +CFLAGS=$GOFLAGS +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_TAGVAR(LD, $1)=$LD +_LT_CC_BASENAME([$compiler]) + +# Go did not exist at the time GCC didn't implicitly link libc in. +_LT_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_TAGVAR(reload_flag, $1)=$reload_flag +_LT_TAGVAR(reload_cmds, $1)=$reload_cmds + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + _LT_COMPILER_NO_RTTI($1) + _LT_COMPILER_PIC($1) + _LT_COMPILER_C_O($1) + _LT_COMPILER_FILE_LOCKS($1) + _LT_LINKER_SHLIBS($1) + _LT_LINKER_HARDCODE_LIBPATH($1) + + _LT_CONFIG($1) +fi + +AC_LANG_RESTORE + +GCC=$lt_save_GCC +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_GO_CONFIG + + +# _LT_LANG_RC_CONFIG([TAG]) +# ------------------------- +# Ensure that the configuration variables for the Windows resource compiler +# are suitably defined. These variables are subsequently used by _LT_CONFIG +# to write the compiler configuration to 'libtool'. +m4_defun([_LT_LANG_RC_CONFIG], +[AC_REQUIRE([LT_PROG_RC])dnl +AC_LANG_SAVE + +# Source file extension for RC test sources. +ac_ext=rc + +# Object file extension for compiled RC test sources. +objext=o +_LT_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' + +# Code to be used in simple link tests +lt_simple_link_test_code=$lt_simple_compile_test_code + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_TAG_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_CFLAGS=$CFLAGS +lt_save_GCC=$GCC +GCC= +CC=${RC-"windres"} +CFLAGS= +compiler=$CC +_LT_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) +_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + +if test -n "$compiler"; then + : + _LT_CONFIG($1) +fi + +GCC=$lt_save_GCC +AC_LANG_RESTORE +CC=$lt_save_CC +CFLAGS=$lt_save_CFLAGS +])# _LT_LANG_RC_CONFIG + + +# LT_PROG_GCJ +# ----------- +AC_DEFUN([LT_PROG_GCJ], +[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], + [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], + [AC_CHECK_TOOL(GCJ, gcj,) + test set = "${GCJFLAGS+set}" || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS)])])[]dnl +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_GCJ], []) + + +# LT_PROG_GO +# ---------- +AC_DEFUN([LT_PROG_GO], +[AC_CHECK_TOOL(GOC, gccgo,) +]) + + +# LT_PROG_RC +# ---------- +AC_DEFUN([LT_PROG_RC], +[AC_CHECK_TOOL(RC, windres,) +]) + +# Old name: +AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_RC], []) + + +# _LT_DECL_EGREP +# -------------- +# If we don't have a new enough Autoconf to choose the best grep +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_EGREP], +[AC_REQUIRE([AC_PROG_EGREP])dnl +AC_REQUIRE([AC_PROG_FGREP])dnl +test -z "$GREP" && GREP=grep +_LT_DECL([], [GREP], [1], [A grep program that handles long lines]) +_LT_DECL([], [EGREP], [1], [An ERE matcher]) +_LT_DECL([], [FGREP], [1], [A literal string matcher]) +dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too +AC_SUBST([GREP]) +]) + + +# _LT_DECL_OBJDUMP +# -------------- +# If we don't have a new enough Autoconf to choose the best objdump +# available, choose the one first in the user's PATH. +m4_defun([_LT_DECL_OBJDUMP], +[AC_CHECK_TOOL(OBJDUMP, objdump, false) +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) +AC_SUBST([OBJDUMP]) +]) + +# _LT_DECL_DLLTOOL +# ---------------- +# Ensure DLLTOOL variable is set. +m4_defun([_LT_DECL_DLLTOOL], +[AC_CHECK_TOOL(DLLTOOL, dlltool, false) +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program]) +AC_SUBST([DLLTOOL]) +]) + +# _LT_DECL_SED +# ------------ +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +m4_defun([_LT_DECL_SED], +[AC_PROG_SED +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" +_LT_DECL([], [SED], [1], [A sed program that does not truncate output]) +_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], + [Sed that helps us avoid accidentally triggering echo(1) options like -n]) +])# _LT_DECL_SED + +m4_ifndef([AC_PROG_SED], [ +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_SED. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ + +m4_defun([AC_PROG_SED], +[AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +IFS=$as_save_IFS +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f "$lt_ac_sed" && continue + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test 10 -lt "$lt_ac_count" && break + lt_ac_count=`expr $lt_ac_count + 1` + if test "$lt_ac_count" -gt "$lt_ac_max"; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done +]) +SED=$lt_cv_path_SED +AC_SUBST([SED]) +AC_MSG_RESULT([$SED]) +])#AC_PROG_SED +])#m4_ifndef + +# Old name: +AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([LT_AC_PROG_SED], []) + + +# _LT_CHECK_SHELL_FEATURES +# ------------------------ +# Find out whether the shell is Bourne or XSI compatible, +# or has some other useful features. +m4_defun([_LT_CHECK_SHELL_FEATURES], +[if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi +_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac +_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl +_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl +])# _LT_CHECK_SHELL_FEATURES + + +# _LT_PATH_CONVERSION_FUNCTIONS +# ----------------------------- +# Determine what file name conversion functions should be used by +# func_to_host_file (and, implicitly, by func_to_host_path). These are needed +# for certain cross-compile configurations and native mingw. +m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_MSG_CHECKING([how to convert $build file names to $host format]) +AC_CACHE_VAL(lt_cv_to_host_file_cmd, +[case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac +]) +to_host_file_cmd=$lt_cv_to_host_file_cmd +AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) +_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], + [0], [convert $build file names to $host format])dnl + +AC_MSG_CHECKING([how to convert $build file names to toolchain format]) +AC_CACHE_VAL(lt_cv_to_tool_file_cmd, +[#assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac +]) +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) +_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], + [0], [convert $build files to toolchain format])dnl +])# _LT_PATH_CONVERSION_FUNCTIONS diff --git a/config/ltmain.sh b/config/ltmain.sh new file mode 100644 index 0000000..0f0a2da --- /dev/null +++ b/config/ltmain.sh @@ -0,0 +1,11147 @@ +#! /bin/sh +## DO NOT EDIT - This file generated from ./build-aux/ltmain.in +## by inline-source v2014-01-03.01 + +# libtool (GNU libtool) 2.4.6 +# Provide generalized library-building support services. +# Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996 + +# Copyright (C) 1996-2015 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. + +# GNU Libtool 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. +# +# As a special exception to the GNU General Public License, +# if you distribute this file as part of a program or library that +# is built using GNU Libtool, you may include this file under the +# same distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + + +PROGRAM=libtool +PACKAGE=libtool +VERSION=2.4.6 +package_revision=2.4.6 + + +## ------ ## +## Usage. ## +## ------ ## + +# Run './libtool --help' for help with using this script from the +# command line. + + +## ------------------------------- ## +## User overridable command paths. ## +## ------------------------------- ## + +# After configure completes, it has a better idea of some of the +# shell tools we need than the defaults used by the functions shared +# with bootstrap, so set those here where they can still be over- +# ridden by the user, but otherwise take precedence. + +: ${AUTOCONF="autoconf"} +: ${AUTOMAKE="automake"} + + +## -------------------------- ## +## Source external libraries. ## +## -------------------------- ## + +# Much of our low-level functionality needs to be sourced from external +# libraries, which are installed to $pkgauxdir. + +# Set a version string for this script. +scriptversion=2015-01-20.17; # UTC + +# General shell script boiler plate, and helper functions. +# Written by Gary V. Vaughan, 2004 + +# Copyright (C) 2004-2015 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. + +# As a special exception to the GNU General Public License, if you distribute +# this file as part of a program or library that is built using GNU Libtool, +# you may include this file under the same distribution terms that you use +# for the rest of that program. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# Please report bugs or propose patches to gary@gnu.org. + + +## ------ ## +## Usage. ## +## ------ ## + +# Evaluate this file near the top of your script to gain access to +# the functions and variables defined here: +# +# . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh +# +# If you need to override any of the default environment variable +# settings, do that before evaluating this file. + + +## -------------------- ## +## Shell normalisation. ## +## -------------------- ## + +# Some shells need a little help to be as Bourne compatible as possible. +# Before doing anything else, make sure all that help has been provided! + +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac +fi + +# NLS nuisances: We save the old values in case they are required later. +_G_user_locale= +_G_safe_locale= +for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES +do + eval "if test set = \"\${$_G_var+set}\"; then + save_$_G_var=\$$_G_var + $_G_var=C + export $_G_var + _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\" + _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\" + fi" +done + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Make sure IFS has a sensible default +sp=' ' +nl=' +' +IFS="$sp $nl" + +# There are apparently some retarded systems that use ';' as a PATH separator! +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + + +## ------------------------- ## +## Locate command utilities. ## +## ------------------------- ## + + +# func_executable_p FILE +# ---------------------- +# Check that FILE is an executable regular file. +func_executable_p () +{ + test -f "$1" && test -x "$1" +} + + +# func_path_progs PROGS_LIST CHECK_FUNC [PATH] +# -------------------------------------------- +# Search for either a program that responds to --version with output +# containing "GNU", or else returned by CHECK_FUNC otherwise, by +# trying all the directories in PATH with each of the elements of +# PROGS_LIST. +# +# CHECK_FUNC should accept the path to a candidate program, and +# set $func_check_prog_result if it truncates its output less than +# $_G_path_prog_max characters. +func_path_progs () +{ + _G_progs_list=$1 + _G_check_func=$2 + _G_PATH=${3-"$PATH"} + + _G_path_prog_max=0 + _G_path_prog_found=false + _G_save_IFS=$IFS; IFS=${PATH_SEPARATOR-:} + for _G_dir in $_G_PATH; do + IFS=$_G_save_IFS + test -z "$_G_dir" && _G_dir=. + for _G_prog_name in $_G_progs_list; do + for _exeext in '' .EXE; do + _G_path_prog=$_G_dir/$_G_prog_name$_exeext + func_executable_p "$_G_path_prog" || continue + case `"$_G_path_prog" --version 2>&1` in + *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;; + *) $_G_check_func $_G_path_prog + func_path_progs_result=$func_check_prog_result + ;; + esac + $_G_path_prog_found && break 3 + done + done + done + IFS=$_G_save_IFS + test -z "$func_path_progs_result" && { + echo "no acceptable sed could be found in \$PATH" >&2 + exit 1 + } +} + + +# We want to be able to use the functions in this file before configure +# has figured out where the best binaries are kept, which means we have +# to search for them ourselves - except when the results are already set +# where we skip the searches. + +# Unless the user overrides by setting SED, search the path for either GNU +# sed, or the sed that truncates its output the least. +test -z "$SED" && { + _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for _G_i in 1 2 3 4 5 6 7; do + _G_sed_script=$_G_sed_script$nl$_G_sed_script + done + echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed + _G_sed_script= + + func_check_prog_sed () + { + _G_path_prog=$1 + + _G_count=0 + printf 0123456789 >conftest.in + while : + do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo '' >> conftest.nl + "$_G_path_prog" -f conftest.sed <conftest.nl >conftest.out 2>/dev/null || break + diff conftest.out conftest.nl >/dev/null 2>&1 || break + _G_count=`expr $_G_count + 1` + if test "$_G_count" -gt "$_G_path_prog_max"; then + # Best one so far, save it but keep looking for a better one + func_check_prog_result=$_G_path_prog + _G_path_prog_max=$_G_count + fi + # 10*(2^10) chars as input seems more than enough + test 10 -lt "$_G_count" && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out + } + + func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin + rm -f conftest.sed + SED=$func_path_progs_result +} + + +# Unless the user overrides by setting GREP, search the path for either GNU +# grep, or the grep that truncates its output the least. +test -z "$GREP" && { + func_check_prog_grep () + { + _G_path_prog=$1 + + _G_count=0 + _G_path_prog_max=0 + printf 0123456789 >conftest.in + while : + do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo 'GREP' >> conftest.nl + "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' <conftest.nl >conftest.out 2>/dev/null || break + diff conftest.out conftest.nl >/dev/null 2>&1 || break + _G_count=`expr $_G_count + 1` + if test "$_G_count" -gt "$_G_path_prog_max"; then + # Best one so far, save it but keep looking for a better one + func_check_prog_result=$_G_path_prog + _G_path_prog_max=$_G_count + fi + # 10*(2^10) chars as input seems more than enough + test 10 -lt "$_G_count" && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out + } + + func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin + GREP=$func_path_progs_result +} + + +## ------------------------------- ## +## User overridable command paths. ## +## ------------------------------- ## + +# All uppercase variable names are used for environment variables. These +# variables can be overridden by the user before calling a script that +# uses them if a suitable command of that name is not already available +# in the command search PATH. + +: ${CP="cp -f"} +: ${ECHO="printf %s\n"} +: ${EGREP="$GREP -E"} +: ${FGREP="$GREP -F"} +: ${LN_S="ln -s"} +: ${MAKE="make"} +: ${MKDIR="mkdir"} +: ${MV="mv -f"} +: ${RM="rm -f"} +: ${SHELL="${CONFIG_SHELL-/bin/sh}"} + + +## -------------------- ## +## Useful sed snippets. ## +## -------------------- ## + +sed_dirname='s|/[^/]*$||' +sed_basename='s|^.*/||' + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='s|\([`"$\\]\)|\\\1|g' + +# Same as above, but do not quote variable references. +sed_double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution that turns a string into a regex matching for the +# string literally. +sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g' + +# Sed substitution that converts a w32 file name or path +# that contains forward slashes, into one that contains +# (escaped) backslashes. A very naive implementation. +sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' + +# Re-'\' parameter expansions in output of sed_double_quote_subst that +# were '\'-ed in input to the same. If an odd number of '\' preceded a +# '$' in input to sed_double_quote_subst, that '$' was protected from +# expansion. Since each input '\' is now two '\'s, look for any number +# of runs of four '\'s followed by two '\'s and then a '$'. '\' that '$'. +_G_bs='\\' +_G_bs2='\\\\' +_G_bs4='\\\\\\\\' +_G_dollar='\$' +sed_double_backslash="\ + s/$_G_bs4/&\\ +/g + s/^$_G_bs2$_G_dollar/$_G_bs&/ + s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g + s/\n//g" + + +## ----------------- ## +## Global variables. ## +## ----------------- ## + +# Except for the global variables explicitly listed below, the following +# functions in the '^func_' namespace, and the '^require_' namespace +# variables initialised in the 'Resource management' section, sourcing +# this file will not pollute your global namespace with anything +# else. There's no portable way to scope variables in Bourne shell +# though, so actually running these functions will sometimes place +# results into a variable named after the function, and often use +# temporary variables in the '^_G_' namespace. If you are careful to +# avoid using those namespaces casually in your sourcing script, things +# should continue to work as you expect. And, of course, you can freely +# overwrite any of the functions or variables defined here before +# calling anything to customize them. + +EXIT_SUCCESS=0 +EXIT_FAILURE=1 +EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. +EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. + +# Allow overriding, eg assuming that you follow the convention of +# putting '$debug_cmd' at the start of all your functions, you can get +# bash to show function call trace with: +# +# debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name +debug_cmd=${debug_cmd-":"} +exit_cmd=: + +# By convention, finish your script with: +# +# exit $exit_status +# +# so that you can set exit_status to non-zero if you want to indicate +# something went wrong during execution without actually bailing out at +# the point of failure. +exit_status=$EXIT_SUCCESS + +# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh +# is ksh but when the shell is invoked as "sh" and the current value of +# the _XPG environment variable is not equal to 1 (one), the special +# positional parameter $0, within a function call, is the name of the +# function. +progpath=$0 + +# The name of this program. +progname=`$ECHO "$progpath" |$SED "$sed_basename"` + +# Make sure we have an absolute progpath for reexecution: +case $progpath in + [\\/]*|[A-Za-z]:\\*) ;; + *[\\/]*) + progdir=`$ECHO "$progpath" |$SED "$sed_dirname"` + progdir=`cd "$progdir" && pwd` + progpath=$progdir/$progname + ;; + *) + _G_IFS=$IFS + IFS=${PATH_SEPARATOR-:} + for progdir in $PATH; do + IFS=$_G_IFS + test -x "$progdir/$progname" && break + done + IFS=$_G_IFS + test -n "$progdir" || progdir=`pwd` + progpath=$progdir/$progname + ;; +esac + + +## ----------------- ## +## Standard options. ## +## ----------------- ## + +# The following options affect the operation of the functions defined +# below, and should be set appropriately depending on run-time para- +# meters passed on the command line. + +opt_dry_run=false +opt_quiet=false +opt_verbose=false + +# Categories 'all' and 'none' are always available. Append any others +# you will pass as the first argument to func_warning from your own +# code. +warning_categories= + +# By default, display warnings according to 'opt_warning_types'. Set +# 'warning_func' to ':' to elide all warnings, or func_fatal_error to +# treat the next displayed warning as a fatal error. +warning_func=func_warn_and_continue + +# Set to 'all' to display all warnings, 'none' to suppress all +# warnings, or a space delimited list of some subset of +# 'warning_categories' to display only the listed warnings. +opt_warning_types=all + + +## -------------------- ## +## Resource management. ## +## -------------------- ## + +# This section contains definitions for functions that each ensure a +# particular resource (a file, or a non-empty configuration variable for +# example) is available, and if appropriate to extract default values +# from pertinent package files. Call them using their associated +# 'require_*' variable to ensure that they are executed, at most, once. +# +# It's entirely deliberate that calling these functions can set +# variables that don't obey the namespace limitations obeyed by the rest +# of this file, in order that that they be as useful as possible to +# callers. + + +# require_term_colors +# ------------------- +# Allow display of bold text on terminals that support it. +require_term_colors=func_require_term_colors +func_require_term_colors () +{ + $debug_cmd + + test -t 1 && { + # COLORTERM and USE_ANSI_COLORS environment variables take + # precedence, because most terminfo databases neglect to describe + # whether color sequences are supported. + test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"} + + if test 1 = "$USE_ANSI_COLORS"; then + # Standard ANSI escape sequences + tc_reset='' + tc_bold=''; tc_standout='' + tc_red=''; tc_green='' + tc_blue=''; tc_cyan='' + else + # Otherwise trust the terminfo database after all. + test -n "`tput sgr0 2>/dev/null`" && { + tc_reset=`tput sgr0` + test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold` + tc_standout=$tc_bold + test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso` + test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1` + test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2` + test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4` + test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5` + } + fi + } + + require_term_colors=: +} + + +## ----------------- ## +## Function library. ## +## ----------------- ## + +# This section contains a variety of useful functions to call in your +# scripts. Take note of the portable wrappers for features provided by +# some modern shells, which will fall back to slower equivalents on +# less featureful shells. + + +# func_append VAR VALUE +# --------------------- +# Append VALUE onto the existing contents of VAR. + + # We should try to minimise forks, especially on Windows where they are + # unreasonably slow, so skip the feature probes when bash or zsh are + # being used: + if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then + : ${_G_HAVE_ARITH_OP="yes"} + : ${_G_HAVE_XSI_OPS="yes"} + # The += operator was introduced in bash 3.1 + case $BASH_VERSION in + [12].* | 3.0 | 3.0*) ;; + *) + : ${_G_HAVE_PLUSEQ_OP="yes"} + ;; + esac + fi + + # _G_HAVE_PLUSEQ_OP + # Can be empty, in which case the shell is probed, "yes" if += is + # useable or anything else if it does not work. + test -z "$_G_HAVE_PLUSEQ_OP" \ + && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \ + && _G_HAVE_PLUSEQ_OP=yes + +if test yes = "$_G_HAVE_PLUSEQ_OP" +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_append () + { + $debug_cmd + + eval "$1+=\$2" + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_append () + { + $debug_cmd + + eval "$1=\$$1\$2" + } +fi + + +# func_append_quoted VAR VALUE +# ---------------------------- +# Quote VALUE and append to the end of shell variable VAR, separated +# by a space. +if test yes = "$_G_HAVE_PLUSEQ_OP"; then + eval 'func_append_quoted () + { + $debug_cmd + + func_quote_for_eval "$2" + eval "$1+=\\ \$func_quote_for_eval_result" + }' +else + func_append_quoted () + { + $debug_cmd + + func_quote_for_eval "$2" + eval "$1=\$$1\\ \$func_quote_for_eval_result" + } +fi + + +# func_append_uniq VAR VALUE +# -------------------------- +# Append unique VALUE onto the existing contents of VAR, assuming +# entries are delimited by the first character of VALUE. For example: +# +# func_append_uniq options " --another-option option-argument" +# +# will only append to $options if " --another-option option-argument " +# is not already present somewhere in $options already (note spaces at +# each end implied by leading space in second argument). +func_append_uniq () +{ + $debug_cmd + + eval _G_current_value='`$ECHO $'$1'`' + _G_delim=`expr "$2" : '\(.\)'` + + case $_G_delim$_G_current_value$_G_delim in + *"$2$_G_delim"*) ;; + *) func_append "$@" ;; + esac +} + + +# func_arith TERM... +# ------------------ +# Set func_arith_result to the result of evaluating TERMs. + test -z "$_G_HAVE_ARITH_OP" \ + && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \ + && _G_HAVE_ARITH_OP=yes + +if test yes = "$_G_HAVE_ARITH_OP"; then + eval 'func_arith () + { + $debug_cmd + + func_arith_result=$(( $* )) + }' +else + func_arith () + { + $debug_cmd + + func_arith_result=`expr "$@"` + } +fi + + +# func_basename FILE +# ------------------ +# Set func_basename_result to FILE with everything up to and including +# the last / stripped. +if test yes = "$_G_HAVE_XSI_OPS"; then + # If this shell supports suffix pattern removal, then use it to avoid + # forking. Hide the definitions single quotes in case the shell chokes + # on unsupported syntax... + _b='func_basename_result=${1##*/}' + _d='case $1 in + */*) func_dirname_result=${1%/*}$2 ;; + * ) func_dirname_result=$3 ;; + esac' + +else + # ...otherwise fall back to using sed. + _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`' + _d='func_dirname_result=`$ECHO "$1" |$SED "$sed_dirname"` + if test "X$func_dirname_result" = "X$1"; then + func_dirname_result=$3 + else + func_append func_dirname_result "$2" + fi' +fi + +eval 'func_basename () +{ + $debug_cmd + + '"$_b"' +}' + + +# func_dirname FILE APPEND NONDIR_REPLACEMENT +# ------------------------------------------- +# Compute the dirname of FILE. If nonempty, add APPEND to the result, +# otherwise set result to NONDIR_REPLACEMENT. +eval 'func_dirname () +{ + $debug_cmd + + '"$_d"' +}' + + +# func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT +# -------------------------------------------------------- +# Perform func_basename and func_dirname in a single function +# call: +# dirname: Compute the dirname of FILE. If nonempty, +# add APPEND to the result, otherwise set result +# to NONDIR_REPLACEMENT. +# value returned in "$func_dirname_result" +# basename: Compute filename of FILE. +# value retuned in "$func_basename_result" +# For efficiency, we do not delegate to the functions above but instead +# duplicate the functionality here. +eval 'func_dirname_and_basename () +{ + $debug_cmd + + '"$_b"' + '"$_d"' +}' + + +# func_echo ARG... +# ---------------- +# Echo program name prefixed message. +func_echo () +{ + $debug_cmd + + _G_message=$* + + func_echo_IFS=$IFS + IFS=$nl + for _G_line in $_G_message; do + IFS=$func_echo_IFS + $ECHO "$progname: $_G_line" + done + IFS=$func_echo_IFS +} + + +# func_echo_all ARG... +# -------------------- +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "$*" +} + + +# func_echo_infix_1 INFIX ARG... +# ------------------------------ +# Echo program name, followed by INFIX on the first line, with any +# additional lines not showing INFIX. +func_echo_infix_1 () +{ + $debug_cmd + + $require_term_colors + + _G_infix=$1; shift + _G_indent=$_G_infix + _G_prefix="$progname: $_G_infix: " + _G_message=$* + + # Strip color escape sequences before counting printable length + for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan" + do + test -n "$_G_tc" && { + _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"` + _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"` + } + done + _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`" " ## exclude from sc_prohibit_nested_quotes + + func_echo_infix_1_IFS=$IFS + IFS=$nl + for _G_line in $_G_message; do + IFS=$func_echo_infix_1_IFS + $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2 + _G_prefix=$_G_indent + done + IFS=$func_echo_infix_1_IFS +} + + +# func_error ARG... +# ----------------- +# Echo program name prefixed message to standard error. +func_error () +{ + $debug_cmd + + $require_term_colors + + func_echo_infix_1 " $tc_standout${tc_red}error$tc_reset" "$*" >&2 +} + + +# func_fatal_error ARG... +# ----------------------- +# Echo program name prefixed message to standard error, and exit. +func_fatal_error () +{ + $debug_cmd + + func_error "$*" + exit $EXIT_FAILURE +} + + +# func_grep EXPRESSION FILENAME +# ----------------------------- +# Check whether EXPRESSION matches any line of FILENAME, without output. +func_grep () +{ + $debug_cmd + + $GREP "$1" "$2" >/dev/null 2>&1 +} + + +# func_len STRING +# --------------- +# Set func_len_result to the length of STRING. STRING may not +# start with a hyphen. + test -z "$_G_HAVE_XSI_OPS" \ + && (eval 'x=a/b/c; + test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ + && _G_HAVE_XSI_OPS=yes + +if test yes = "$_G_HAVE_XSI_OPS"; then + eval 'func_len () + { + $debug_cmd + + func_len_result=${#1} + }' +else + func_len () + { + $debug_cmd + + func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` + } +fi + + +# func_mkdir_p DIRECTORY-PATH +# --------------------------- +# Make sure the entire path to DIRECTORY-PATH is available. +func_mkdir_p () +{ + $debug_cmd + + _G_directory_path=$1 + _G_dir_list= + + if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then + + # Protect directory names starting with '-' + case $_G_directory_path in + -*) _G_directory_path=./$_G_directory_path ;; + esac + + # While some portion of DIR does not yet exist... + while test ! -d "$_G_directory_path"; do + # ...make a list in topmost first order. Use a colon delimited + # list incase some portion of path contains whitespace. + _G_dir_list=$_G_directory_path:$_G_dir_list + + # If the last portion added has no slash in it, the list is done + case $_G_directory_path in */*) ;; *) break ;; esac + + # ...otherwise throw away the child directory and loop + _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"` + done + _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'` + + func_mkdir_p_IFS=$IFS; IFS=: + for _G_dir in $_G_dir_list; do + IFS=$func_mkdir_p_IFS + # mkdir can fail with a 'File exist' error if two processes + # try to create one of the directories concurrently. Don't + # stop in that case! + $MKDIR "$_G_dir" 2>/dev/null || : + done + IFS=$func_mkdir_p_IFS + + # Bail out if we (or some other process) failed to create a directory. + test -d "$_G_directory_path" || \ + func_fatal_error "Failed to create '$1'" + fi +} + + +# func_mktempdir [BASENAME] +# ------------------------- +# Make a temporary directory that won't clash with other running +# libtool processes, and avoids race conditions if possible. If +# given, BASENAME is the basename for that directory. +func_mktempdir () +{ + $debug_cmd + + _G_template=${TMPDIR-/tmp}/${1-$progname} + + if test : = "$opt_dry_run"; then + # Return a directory name, but don't create it in dry-run mode + _G_tmpdir=$_G_template-$$ + else + + # If mktemp works, use that first and foremost + _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null` + + if test ! -d "$_G_tmpdir"; then + # Failing that, at least try and use $RANDOM to avoid a race + _G_tmpdir=$_G_template-${RANDOM-0}$$ + + func_mktempdir_umask=`umask` + umask 0077 + $MKDIR "$_G_tmpdir" + umask $func_mktempdir_umask + fi + + # If we're not in dry-run mode, bomb out on failure + test -d "$_G_tmpdir" || \ + func_fatal_error "cannot create temporary directory '$_G_tmpdir'" + fi + + $ECHO "$_G_tmpdir" +} + + +# func_normal_abspath PATH +# ------------------------ +# Remove doubled-up and trailing slashes, "." path components, +# and cancel out any ".." path components in PATH after making +# it an absolute path. +func_normal_abspath () +{ + $debug_cmd + + # These SED scripts presuppose an absolute path with a trailing slash. + _G_pathcar='s|^/\([^/]*\).*$|\1|' + _G_pathcdr='s|^/[^/]*||' + _G_removedotparts=':dotsl + s|/\./|/|g + t dotsl + s|/\.$|/|' + _G_collapseslashes='s|/\{1,\}|/|g' + _G_finalslash='s|/*$|/|' + + # Start from root dir and reassemble the path. + func_normal_abspath_result= + func_normal_abspath_tpath=$1 + func_normal_abspath_altnamespace= + case $func_normal_abspath_tpath in + "") + # Empty path, that just means $cwd. + func_stripname '' '/' "`pwd`" + func_normal_abspath_result=$func_stripname_result + return + ;; + # The next three entries are used to spot a run of precisely + # two leading slashes without using negated character classes; + # we take advantage of case's first-match behaviour. + ///*) + # Unusual form of absolute path, do nothing. + ;; + //*) + # Not necessarily an ordinary path; POSIX reserves leading '//' + # and for example Cygwin uses it to access remote file shares + # over CIFS/SMB, so we conserve a leading double slash if found. + func_normal_abspath_altnamespace=/ + ;; + /*) + # Absolute path, do nothing. + ;; + *) + # Relative path, prepend $cwd. + func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath + ;; + esac + + # Cancel out all the simple stuff to save iterations. We also want + # the path to end with a slash for ease of parsing, so make sure + # there is one (and only one) here. + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"` + while :; do + # Processed it all yet? + if test / = "$func_normal_abspath_tpath"; then + # If we ascended to the root using ".." the result may be empty now. + if test -z "$func_normal_abspath_result"; then + func_normal_abspath_result=/ + fi + break + fi + func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$_G_pathcar"` + func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ + -e "$_G_pathcdr"` + # Figure out what to do with it + case $func_normal_abspath_tcomponent in + "") + # Trailing empty path component, ignore it. + ;; + ..) + # Parent dir; strip last assembled component from result. + func_dirname "$func_normal_abspath_result" + func_normal_abspath_result=$func_dirname_result + ;; + *) + # Actual path component, append it. + func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent" + ;; + esac + done + # Restore leading double-slash if one was found on entry. + func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result +} + + +# func_notquiet ARG... +# -------------------- +# Echo program name prefixed message only when not in quiet mode. +func_notquiet () +{ + $debug_cmd + + $opt_quiet || func_echo ${1+"$@"} + + # A bug in bash halts the script if the last line of a function + # fails when set -e is in force, so we need another command to + # work around that: + : +} + + +# func_relative_path SRCDIR DSTDIR +# -------------------------------- +# Set func_relative_path_result to the relative path from SRCDIR to DSTDIR. +func_relative_path () +{ + $debug_cmd + + func_relative_path_result= + func_normal_abspath "$1" + func_relative_path_tlibdir=$func_normal_abspath_result + func_normal_abspath "$2" + func_relative_path_tbindir=$func_normal_abspath_result + + # Ascend the tree starting from libdir + while :; do + # check if we have found a prefix of bindir + case $func_relative_path_tbindir in + $func_relative_path_tlibdir) + # found an exact match + func_relative_path_tcancelled= + break + ;; + $func_relative_path_tlibdir*) + # found a matching prefix + func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" + func_relative_path_tcancelled=$func_stripname_result + if test -z "$func_relative_path_result"; then + func_relative_path_result=. + fi + break + ;; + *) + func_dirname $func_relative_path_tlibdir + func_relative_path_tlibdir=$func_dirname_result + if test -z "$func_relative_path_tlibdir"; then + # Have to descend all the way to the root! + func_relative_path_result=../$func_relative_path_result + func_relative_path_tcancelled=$func_relative_path_tbindir + break + fi + func_relative_path_result=../$func_relative_path_result + ;; + esac + done + + # Now calculate path; take care to avoid doubling-up slashes. + func_stripname '' '/' "$func_relative_path_result" + func_relative_path_result=$func_stripname_result + func_stripname '/' '/' "$func_relative_path_tcancelled" + if test -n "$func_stripname_result"; then + func_append func_relative_path_result "/$func_stripname_result" + fi + + # Normalisation. If bindir is libdir, return '.' else relative path. + if test -n "$func_relative_path_result"; then + func_stripname './' '' "$func_relative_path_result" + func_relative_path_result=$func_stripname_result + fi + + test -n "$func_relative_path_result" || func_relative_path_result=. + + : +} + + +# func_quote_for_eval ARG... +# -------------------------- +# Aesthetically quote ARGs to be evaled later. +# This function returns two values: +# i) func_quote_for_eval_result +# double-quoted, suitable for a subsequent eval +# ii) func_quote_for_eval_unquoted_result +# has all characters that are still active within double +# quotes backslashified. +func_quote_for_eval () +{ + $debug_cmd + + func_quote_for_eval_unquoted_result= + func_quote_for_eval_result= + while test 0 -lt $#; do + case $1 in + *[\\\`\"\$]*) + _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;; + *) + _G_unquoted_arg=$1 ;; + esac + if test -n "$func_quote_for_eval_unquoted_result"; then + func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg" + else + func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg" + fi + + case $_G_unquoted_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting, command substitution and variable expansion + # for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + _G_quoted_arg=\"$_G_unquoted_arg\" + ;; + *) + _G_quoted_arg=$_G_unquoted_arg + ;; + esac + + if test -n "$func_quote_for_eval_result"; then + func_append func_quote_for_eval_result " $_G_quoted_arg" + else + func_append func_quote_for_eval_result "$_G_quoted_arg" + fi + shift + done +} + + +# func_quote_for_expand ARG +# ------------------------- +# Aesthetically quote ARG to be evaled later; same as above, +# but do not quote variable references. +func_quote_for_expand () +{ + $debug_cmd + + case $1 in + *[\\\`\"]*) + _G_arg=`$ECHO "$1" | $SED \ + -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;; + *) + _G_arg=$1 ;; + esac + + case $_G_arg in + # Double-quote args containing shell metacharacters to delay + # word splitting and command substitution for a subsequent eval. + # Many Bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + _G_arg=\"$_G_arg\" + ;; + esac + + func_quote_for_expand_result=$_G_arg +} + + +# func_stripname PREFIX SUFFIX NAME +# --------------------------------- +# strip PREFIX and SUFFIX from NAME, and store in func_stripname_result. +# PREFIX and SUFFIX must not contain globbing or regex special +# characters, hashes, percent signs, but SUFFIX may contain a leading +# dot (in which case that matches only a dot). +if test yes = "$_G_HAVE_XSI_OPS"; then + eval 'func_stripname () + { + $debug_cmd + + # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are + # positional parameters, so assign one to ordinary variable first. + func_stripname_result=$3 + func_stripname_result=${func_stripname_result#"$1"} + func_stripname_result=${func_stripname_result%"$2"} + }' +else + func_stripname () + { + $debug_cmd + + case $2 in + .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;; + *) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;; + esac + } +fi + + +# func_show_eval CMD [FAIL_EXP] +# ----------------------------- +# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. +func_show_eval () +{ + $debug_cmd + + _G_cmd=$1 + _G_fail_exp=${2-':'} + + func_quote_for_expand "$_G_cmd" + eval "func_notquiet $func_quote_for_expand_result" + + $opt_dry_run || { + eval "$_G_cmd" + _G_status=$? + if test 0 -ne "$_G_status"; then + eval "(exit $_G_status); $_G_fail_exp" + fi + } +} + + +# func_show_eval_locale CMD [FAIL_EXP] +# ------------------------------------ +# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is +# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP +# is given, then evaluate it. Use the saved locale for evaluation. +func_show_eval_locale () +{ + $debug_cmd + + _G_cmd=$1 + _G_fail_exp=${2-':'} + + $opt_quiet || { + func_quote_for_expand "$_G_cmd" + eval "func_echo $func_quote_for_expand_result" + } + + $opt_dry_run || { + eval "$_G_user_locale + $_G_cmd" + _G_status=$? + eval "$_G_safe_locale" + if test 0 -ne "$_G_status"; then + eval "(exit $_G_status); $_G_fail_exp" + fi + } +} + + +# func_tr_sh +# ---------- +# Turn $1 into a string suitable for a shell variable name. +# Result is stored in $func_tr_sh_result. All characters +# not in the set a-zA-Z0-9_ are replaced with '_'. Further, +# if $1 begins with a digit, a '_' is prepended as well. +func_tr_sh () +{ + $debug_cmd + + case $1 in + [0-9]* | *[!a-zA-Z0-9_]*) + func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'` + ;; + * ) + func_tr_sh_result=$1 + ;; + esac +} + + +# func_verbose ARG... +# ------------------- +# Echo program name prefixed message in verbose mode only. +func_verbose () +{ + $debug_cmd + + $opt_verbose && func_echo "$*" + + : +} + + +# func_warn_and_continue ARG... +# ----------------------------- +# Echo program name prefixed warning message to standard error. +func_warn_and_continue () +{ + $debug_cmd + + $require_term_colors + + func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2 +} + + +# func_warning CATEGORY ARG... +# ---------------------------- +# Echo program name prefixed warning message to standard error. Warning +# messages can be filtered according to CATEGORY, where this function +# elides messages where CATEGORY is not listed in the global variable +# 'opt_warning_types'. +func_warning () +{ + $debug_cmd + + # CATEGORY must be in the warning_categories list! + case " $warning_categories " in + *" $1 "*) ;; + *) func_internal_error "invalid warning category '$1'" ;; + esac + + _G_category=$1 + shift + + case " $opt_warning_types " in + *" $_G_category "*) $warning_func ${1+"$@"} ;; + esac +} + + +# func_sort_ver VER1 VER2 +# ----------------------- +# 'sort -V' is not generally available. +# Note this deviates from the version comparison in automake +# in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a +# but this should suffice as we won't be specifying old +# version formats or redundant trailing .0 in bootstrap.conf. +# If we did want full compatibility then we should probably +# use m4_version_compare from autoconf. +func_sort_ver () +{ + $debug_cmd + + printf '%s\n%s\n' "$1" "$2" \ + | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n +} + +# func_lt_ver PREV CURR +# --------------------- +# Return true if PREV and CURR are in the correct order according to +# func_sort_ver, otherwise false. Use it like this: +# +# func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..." +func_lt_ver () +{ + $debug_cmd + + test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q` +} + + +# Local variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" +# time-stamp-time-zone: "UTC" +# End: +#! /bin/sh + +# Set a version string for this script. +scriptversion=2014-01-07.03; # UTC + +# A portable, pluggable option parser for Bourne shell. +# Written by Gary V. Vaughan, 2010 + +# Copyright (C) 2010-2015 Free Software Foundation, Inc. +# This is free software; see the source for copying conditions. There is NO +# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# Please report bugs or propose patches to gary@gnu.org. + + +## ------ ## +## Usage. ## +## ------ ## + +# This file is a library for parsing options in your shell scripts along +# with assorted other useful supporting features that you can make use +# of too. +# +# For the simplest scripts you might need only: +# +# #!/bin/sh +# . relative/path/to/funclib.sh +# . relative/path/to/options-parser +# scriptversion=1.0 +# func_options ${1+"$@"} +# eval set dummy "$func_options_result"; shift +# ...rest of your script... +# +# In order for the '--version' option to work, you will need to have a +# suitably formatted comment like the one at the top of this file +# starting with '# Written by ' and ending with '# warranty; '. +# +# For '-h' and '--help' to work, you will also need a one line +# description of your script's purpose in a comment directly above the +# '# Written by ' line, like the one at the top of this file. +# +# The default options also support '--debug', which will turn on shell +# execution tracing (see the comment above debug_cmd below for another +# use), and '--verbose' and the func_verbose function to allow your script +# to display verbose messages only when your user has specified +# '--verbose'. +# +# After sourcing this file, you can plug processing for additional +# options by amending the variables from the 'Configuration' section +# below, and following the instructions in the 'Option parsing' +# section further down. + +## -------------- ## +## Configuration. ## +## -------------- ## + +# You should override these variables in your script after sourcing this +# file so that they reflect the customisations you have added to the +# option parser. + +# The usage line for option parsing errors and the start of '-h' and +# '--help' output messages. You can embed shell variables for delayed +# expansion at the time the message is displayed, but you will need to +# quote other shell meta-characters carefully to prevent them being +# expanded when the contents are evaled. +usage='$progpath [OPTION]...' + +# Short help message in response to '-h' and '--help'. Add to this or +# override it after sourcing this library to reflect the full set of +# options your script accepts. +usage_message="\ + --debug enable verbose shell tracing + -W, --warnings=CATEGORY + report the warnings falling in CATEGORY [all] + -v, --verbose verbosely report processing + --version print version information and exit + -h, --help print short or long help message and exit +" + +# Additional text appended to 'usage_message' in response to '--help'. +long_help_message=" +Warning categories include: + 'all' show all warnings + 'none' turn off all the warnings + 'error' warnings are treated as fatal errors" + +# Help message printed before fatal option parsing errors. +fatal_help="Try '\$progname --help' for more information." + + + +## ------------------------- ## +## Hook function management. ## +## ------------------------- ## + +# This section contains functions for adding, removing, and running hooks +# to the main code. A hook is just a named list of of function, that can +# be run in order later on. + +# func_hookable FUNC_NAME +# ----------------------- +# Declare that FUNC_NAME will run hooks added with +# 'func_add_hook FUNC_NAME ...'. +func_hookable () +{ + $debug_cmd + + func_append hookable_fns " $1" +} + + +# func_add_hook FUNC_NAME HOOK_FUNC +# --------------------------------- +# Request that FUNC_NAME call HOOK_FUNC before it returns. FUNC_NAME must +# first have been declared "hookable" by a call to 'func_hookable'. +func_add_hook () +{ + $debug_cmd + + case " $hookable_fns " in + *" $1 "*) ;; + *) func_fatal_error "'$1' does not accept hook functions." ;; + esac + + eval func_append ${1}_hooks '" $2"' +} + + +# func_remove_hook FUNC_NAME HOOK_FUNC +# ------------------------------------ +# Remove HOOK_FUNC from the list of functions called by FUNC_NAME. +func_remove_hook () +{ + $debug_cmd + + eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`' +} + + +# func_run_hooks FUNC_NAME [ARG]... +# --------------------------------- +# Run all hook functions registered to FUNC_NAME. +# It is assumed that the list of hook functions contains nothing more +# than a whitespace-delimited list of legal shell function names, and +# no effort is wasted trying to catch shell meta-characters or preserve +# whitespace. +func_run_hooks () +{ + $debug_cmd + + case " $hookable_fns " in + *" $1 "*) ;; + *) func_fatal_error "'$1' does not support hook funcions.n" ;; + esac + + eval _G_hook_fns=\$$1_hooks; shift + + for _G_hook in $_G_hook_fns; do + eval $_G_hook '"$@"' + + # store returned options list back into positional + # parameters for next 'cmd' execution. + eval _G_hook_result=\$${_G_hook}_result + eval set dummy "$_G_hook_result"; shift + done + + func_quote_for_eval ${1+"$@"} + func_run_hooks_result=$func_quote_for_eval_result +} + + + +## --------------- ## +## Option parsing. ## +## --------------- ## + +# In order to add your own option parsing hooks, you must accept the +# full positional parameter list in your hook function, remove any +# options that you action, and then pass back the remaining unprocessed +# options in '<hooked_function_name>_result', escaped suitably for +# 'eval'. Like this: +# +# my_options_prep () +# { +# $debug_cmd +# +# # Extend the existing usage message. +# usage_message=$usage_message' +# -s, --silent don'\''t print informational messages +# ' +# +# func_quote_for_eval ${1+"$@"} +# my_options_prep_result=$func_quote_for_eval_result +# } +# func_add_hook func_options_prep my_options_prep +# +# +# my_silent_option () +# { +# $debug_cmd +# +# # Note that for efficiency, we parse as many options as we can +# # recognise in a loop before passing the remainder back to the +# # caller on the first unrecognised argument we encounter. +# while test $# -gt 0; do +# opt=$1; shift +# case $opt in +# --silent|-s) opt_silent=: ;; +# # Separate non-argument short options: +# -s*) func_split_short_opt "$_G_opt" +# set dummy "$func_split_short_opt_name" \ +# "-$func_split_short_opt_arg" ${1+"$@"} +# shift +# ;; +# *) set dummy "$_G_opt" "$*"; shift; break ;; +# esac +# done +# +# func_quote_for_eval ${1+"$@"} +# my_silent_option_result=$func_quote_for_eval_result +# } +# func_add_hook func_parse_options my_silent_option +# +# +# my_option_validation () +# { +# $debug_cmd +# +# $opt_silent && $opt_verbose && func_fatal_help "\ +# '--silent' and '--verbose' options are mutually exclusive." +# +# func_quote_for_eval ${1+"$@"} +# my_option_validation_result=$func_quote_for_eval_result +# } +# func_add_hook func_validate_options my_option_validation +# +# You'll alse need to manually amend $usage_message to reflect the extra +# options you parse. It's preferable to append if you can, so that +# multiple option parsing hooks can be added safely. + + +# func_options [ARG]... +# --------------------- +# All the functions called inside func_options are hookable. See the +# individual implementations for details. +func_hookable func_options +func_options () +{ + $debug_cmd + + func_options_prep ${1+"$@"} + eval func_parse_options \ + ${func_options_prep_result+"$func_options_prep_result"} + eval func_validate_options \ + ${func_parse_options_result+"$func_parse_options_result"} + + eval func_run_hooks func_options \ + ${func_validate_options_result+"$func_validate_options_result"} + + # save modified positional parameters for caller + func_options_result=$func_run_hooks_result +} + + +# func_options_prep [ARG]... +# -------------------------- +# All initialisations required before starting the option parse loop. +# Note that when calling hook functions, we pass through the list of +# positional parameters. If a hook function modifies that list, and +# needs to propogate that back to rest of this script, then the complete +# modified list must be put in 'func_run_hooks_result' before +# returning. +func_hookable func_options_prep +func_options_prep () +{ + $debug_cmd + + # Option defaults: + opt_verbose=false + opt_warning_types= + + func_run_hooks func_options_prep ${1+"$@"} + + # save modified positional parameters for caller + func_options_prep_result=$func_run_hooks_result +} + + +# func_parse_options [ARG]... +# --------------------------- +# The main option parsing loop. +func_hookable func_parse_options +func_parse_options () +{ + $debug_cmd + + func_parse_options_result= + + # this just eases exit handling + while test $# -gt 0; do + # Defer to hook functions for initial option parsing, so they + # get priority in the event of reusing an option name. + func_run_hooks func_parse_options ${1+"$@"} + + # Adjust func_parse_options positional parameters to match + eval set dummy "$func_run_hooks_result"; shift + + # Break out of the loop if we already parsed every option. + test $# -gt 0 || break + + _G_opt=$1 + shift + case $_G_opt in + --debug|-x) debug_cmd='set -x' + func_echo "enabling shell trace mode" + $debug_cmd + ;; + + --no-warnings|--no-warning|--no-warn) + set dummy --warnings none ${1+"$@"} + shift + ;; + + --warnings|--warning|-W) + test $# = 0 && func_missing_arg $_G_opt && break + case " $warning_categories $1" in + *" $1 "*) + # trailing space prevents matching last $1 above + func_append_uniq opt_warning_types " $1" + ;; + *all) + opt_warning_types=$warning_categories + ;; + *none) + opt_warning_types=none + warning_func=: + ;; + *error) + opt_warning_types=$warning_categories + warning_func=func_fatal_error + ;; + *) + func_fatal_error \ + "unsupported warning category: '$1'" + ;; + esac + shift + ;; + + --verbose|-v) opt_verbose=: ;; + --version) func_version ;; + -\?|-h) func_usage ;; + --help) func_help ;; + + # Separate optargs to long options (plugins may need this): + --*=*) func_split_equals "$_G_opt" + set dummy "$func_split_equals_lhs" \ + "$func_split_equals_rhs" ${1+"$@"} + shift + ;; + + # Separate optargs to short options: + -W*) + func_split_short_opt "$_G_opt" + set dummy "$func_split_short_opt_name" \ + "$func_split_short_opt_arg" ${1+"$@"} + shift + ;; + + # Separate non-argument short options: + -\?*|-h*|-v*|-x*) + func_split_short_opt "$_G_opt" + set dummy "$func_split_short_opt_name" \ + "-$func_split_short_opt_arg" ${1+"$@"} + shift + ;; + + --) break ;; + -*) func_fatal_help "unrecognised option: '$_G_opt'" ;; + *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; + esac + done + + # save modified positional parameters for caller + func_quote_for_eval ${1+"$@"} + func_parse_options_result=$func_quote_for_eval_result +} + + +# func_validate_options [ARG]... +# ------------------------------ +# Perform any sanity checks on option settings and/or unconsumed +# arguments. +func_hookable func_validate_options +func_validate_options () +{ + $debug_cmd + + # Display all warnings if -W was not given. + test -n "$opt_warning_types" || opt_warning_types=" $warning_categories" + + func_run_hooks func_validate_options ${1+"$@"} + + # Bail if the options were screwed! + $exit_cmd $EXIT_FAILURE + + # save modified positional parameters for caller + func_validate_options_result=$func_run_hooks_result +} + + + +## ----------------- ## +## Helper functions. ## +## ----------------- ## + +# This section contains the helper functions used by the rest of the +# hookable option parser framework in ascii-betical order. + + +# func_fatal_help ARG... +# ---------------------- +# Echo program name prefixed message to standard error, followed by +# a help hint, and exit. +func_fatal_help () +{ + $debug_cmd + + eval \$ECHO \""Usage: $usage"\" + eval \$ECHO \""$fatal_help"\" + func_error ${1+"$@"} + exit $EXIT_FAILURE +} + + +# func_help +# --------- +# Echo long help message to standard output and exit. +func_help () +{ + $debug_cmd + + func_usage_message + $ECHO "$long_help_message" + exit 0 +} + + +# func_missing_arg ARGNAME +# ------------------------ +# Echo program name prefixed message to standard error and set global +# exit_cmd. +func_missing_arg () +{ + $debug_cmd + + func_error "Missing argument for '$1'." + exit_cmd=exit +} + + +# func_split_equals STRING +# ------------------------ +# Set func_split_equals_lhs and func_split_equals_rhs shell variables after +# splitting STRING at the '=' sign. +test -z "$_G_HAVE_XSI_OPS" \ + && (eval 'x=a/b/c; + test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ + && _G_HAVE_XSI_OPS=yes + +if test yes = "$_G_HAVE_XSI_OPS" +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_split_equals () + { + $debug_cmd + + func_split_equals_lhs=${1%%=*} + func_split_equals_rhs=${1#*=} + test "x$func_split_equals_lhs" = "x$1" \ + && func_split_equals_rhs= + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_split_equals () + { + $debug_cmd + + func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'` + func_split_equals_rhs= + test "x$func_split_equals_lhs" = "x$1" \ + || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'` + } +fi #func_split_equals + + +# func_split_short_opt SHORTOPT +# ----------------------------- +# Set func_split_short_opt_name and func_split_short_opt_arg shell +# variables after splitting SHORTOPT after the 2nd character. +if test yes = "$_G_HAVE_XSI_OPS" +then + # This is an XSI compatible shell, allowing a faster implementation... + eval 'func_split_short_opt () + { + $debug_cmd + + func_split_short_opt_arg=${1#??} + func_split_short_opt_name=${1%"$func_split_short_opt_arg"} + }' +else + # ...otherwise fall back to using expr, which is often a shell builtin. + func_split_short_opt () + { + $debug_cmd + + func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'` + func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'` + } +fi #func_split_short_opt + + +# func_usage +# ---------- +# Echo short help message to standard output and exit. +func_usage () +{ + $debug_cmd + + func_usage_message + $ECHO "Run '$progname --help |${PAGER-more}' for full usage" + exit 0 +} + + +# func_usage_message +# ------------------ +# Echo short help message to standard output. +func_usage_message () +{ + $debug_cmd + + eval \$ECHO \""Usage: $usage"\" + echo + $SED -n 's|^# || + /^Written by/{ + x;p;x + } + h + /^Written by/q' < "$progpath" + echo + eval \$ECHO \""$usage_message"\" +} + + +# func_version +# ------------ +# Echo version message to standard output and exit. +func_version () +{ + $debug_cmd + + printf '%s\n' "$progname $scriptversion" + $SED -n ' + /(C)/!b go + :more + /\./!{ + N + s|\n# | | + b more + } + :go + /^# Written by /,/# warranty; / { + s|^# || + s|^# *$|| + s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2| + p + } + /^# Written by / { + s|^# || + p + } + /^warranty; /q' < "$progpath" + + exit $? +} + + +# Local variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" +# time-stamp-time-zone: "UTC" +# End: + +# Set a version string. +scriptversion='(GNU libtool) 2.4.6' + + +# func_echo ARG... +# ---------------- +# Libtool also displays the current mode in messages, so override +# funclib.sh func_echo with this custom definition. +func_echo () +{ + $debug_cmd + + _G_message=$* + + func_echo_IFS=$IFS + IFS=$nl + for _G_line in $_G_message; do + IFS=$func_echo_IFS + $ECHO "$progname${opt_mode+: $opt_mode}: $_G_line" + done + IFS=$func_echo_IFS +} + + +# func_warning ARG... +# ------------------- +# Libtool warnings are not categorized, so override funclib.sh +# func_warning with this simpler definition. +func_warning () +{ + $debug_cmd + + $warning_func ${1+"$@"} +} + + +## ---------------- ## +## Options parsing. ## +## ---------------- ## + +# Hook in the functions to make sure our own options are parsed during +# the option parsing loop. + +usage='$progpath [OPTION]... [MODE-ARG]...' + +# Short help message in response to '-h'. +usage_message="Options: + --config show all configuration variables + --debug enable verbose shell tracing + -n, --dry-run display commands without modifying any files + --features display basic configuration information and exit + --mode=MODE use operation mode MODE + --no-warnings equivalent to '-Wnone' + --preserve-dup-deps don't remove duplicate dependency libraries + --quiet, --silent don't print informational messages + --tag=TAG use configuration variables from tag TAG + -v, --verbose print more informational messages than default + --version print version information + -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] + -h, --help, --help-all print short, long, or detailed help message +" + +# Additional text appended to 'usage_message' in response to '--help'. +func_help () +{ + $debug_cmd + + func_usage_message + $ECHO "$long_help_message + +MODE must be one of the following: + + clean remove files from the build directory + 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. When passed as first option, +'--mode=MODE' may be abbreviated as 'MODE' or a unique abbreviation of that. +Try '$progname --help --mode=MODE' for a more detailed description of MODE. + +When reporting a bug, please describe a test case to reproduce it and +include the following information: + + host-triplet: $host + shell: $SHELL + compiler: $LTCC + compiler flags: $LTCFLAGS + linker: $LD (gnu? $with_gnu_ld) + version: $progname (GNU libtool) 2.4.6 + automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q` + autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q` + +Report bugs to <bug-libtool@gnu.org>. +GNU libtool home page: <http://www.gnu.org/software/libtool/>. +General help using GNU software: <http://www.gnu.org/gethelp/>." + exit 0 +} + + +# func_lo2o OBJECT-NAME +# --------------------- +# Transform OBJECT-NAME from a '.lo' suffix to the platform specific +# object suffix. + +lo2o=s/\\.lo\$/.$objext/ +o2lo=s/\\.$objext\$/.lo/ + +if test yes = "$_G_HAVE_XSI_OPS"; then + eval 'func_lo2o () + { + case $1 in + *.lo) func_lo2o_result=${1%.lo}.$objext ;; + * ) func_lo2o_result=$1 ;; + esac + }' + + # func_xform LIBOBJ-OR-SOURCE + # --------------------------- + # Transform LIBOBJ-OR-SOURCE from a '.o' or '.c' (or otherwise) + # suffix to a '.lo' libtool-object suffix. + eval 'func_xform () + { + func_xform_result=${1%.*}.lo + }' +else + # ...otherwise fall back to using sed. + func_lo2o () + { + func_lo2o_result=`$ECHO "$1" | $SED "$lo2o"` + } + + func_xform () + { + func_xform_result=`$ECHO "$1" | $SED 's|\.[^.]*$|.lo|'` + } +fi + + +# func_fatal_configuration ARG... +# ------------------------------- +# Echo program name prefixed message to standard error, followed by +# a configuration failure hint, and exit. +func_fatal_configuration () +{ + func__fatal_error ${1+"$@"} \ + "See the $PACKAGE documentation for more information." \ + "Fatal configuration error." +} + + +# func_config +# ----------- +# Display the configuration for all the tags in this script. +func_config () +{ + re_begincf='^# ### BEGIN LIBTOOL' + re_endcf='^# ### END LIBTOOL' + + # Default configuration. + $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" + + # Now print the configurations for the tags. + for tagname in $taglist; do + $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" + done + + exit $? +} + + +# func_features +# ------------- +# Display the features supported by this script. +func_features () +{ + echo "host: $host" + if test yes = "$build_libtool_libs"; then + echo "enable shared libraries" + else + echo "disable shared libraries" + fi + if test yes = "$build_old_libs"; then + echo "enable static libraries" + else + echo "disable static libraries" + fi + + exit $? +} + + +# func_enable_tag TAGNAME +# ----------------------- +# Verify that TAGNAME is valid, and either flag an error and exit, or +# enable the TAGNAME tag. We also add TAGNAME to the global $taglist +# variable here. +func_enable_tag () +{ + # Global variable: + tagname=$1 + + re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" + re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" + sed_extractcf=/$re_begincf/,/$re_endcf/p + + # Validate tagname. + case $tagname in + *[!-_A-Za-z0-9,/]*) + func_fatal_error "invalid tag name: $tagname" + ;; + esac + + # Don't test for the "default" C tag, as we know it's + # there but not specially marked. + case $tagname in + CC) ;; + *) + if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then + taglist="$taglist $tagname" + + # Evaluate the configuration. Be careful to quote the path + # and the sed script, to avoid splitting on whitespace, but + # also don't use non-portable quotes within backquotes within + # quotes we have to do it in 2 steps: + extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` + eval "$extractedcf" + else + func_error "ignoring unknown tag $tagname" + fi + ;; + esac +} + + +# func_check_version_match +# ------------------------ +# Ensure that we are using m4 macros, and libtool script from the same +# release of libtool. +func_check_version_match () +{ + if test "$package_revision" != "$macro_revision"; then + if test "$VERSION" != "$macro_version"; then + if test -z "$macro_version"; then + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from an older release. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, but the +$progname: definition of this LT_INIT comes from $PACKAGE $macro_version. +$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION +$progname: and run autoconf again. +_LT_EOF + fi + else + cat >&2 <<_LT_EOF +$progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, +$progname: but the definition of this LT_INIT comes from revision $macro_revision. +$progname: You should recreate aclocal.m4 with macros from revision $package_revision +$progname: of $PACKAGE $VERSION and run autoconf again. +_LT_EOF + fi + + exit $EXIT_MISMATCH + fi +} + + +# libtool_options_prep [ARG]... +# ----------------------------- +# Preparation for options parsed by libtool. +libtool_options_prep () +{ + $debug_mode + + # Option defaults: + opt_config=false + opt_dlopen= + opt_dry_run=false + opt_help=false + opt_mode= + opt_preserve_dup_deps=false + opt_quiet=false + + nonopt= + preserve_args= + + # Shorthand for --mode=foo, only valid as the first argument + case $1 in + clean|clea|cle|cl) + shift; set dummy --mode clean ${1+"$@"}; shift + ;; + compile|compil|compi|comp|com|co|c) + shift; set dummy --mode compile ${1+"$@"}; shift + ;; + execute|execut|execu|exec|exe|ex|e) + shift; set dummy --mode execute ${1+"$@"}; shift + ;; + finish|finis|fini|fin|fi|f) + shift; set dummy --mode finish ${1+"$@"}; shift + ;; + install|instal|insta|inst|ins|in|i) + shift; set dummy --mode install ${1+"$@"}; shift + ;; + link|lin|li|l) + shift; set dummy --mode link ${1+"$@"}; shift + ;; + uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) + shift; set dummy --mode uninstall ${1+"$@"}; shift + ;; + esac + + # Pass back the list of options. + func_quote_for_eval ${1+"$@"} + libtool_options_prep_result=$func_quote_for_eval_result +} +func_add_hook func_options_prep libtool_options_prep + + +# libtool_parse_options [ARG]... +# --------------------------------- +# Provide handling for libtool specific options. +libtool_parse_options () +{ + $debug_cmd + + # Perform our own loop to consume as many options as possible in + # each iteration. + while test $# -gt 0; do + _G_opt=$1 + shift + case $_G_opt in + --dry-run|--dryrun|-n) + opt_dry_run=: + ;; + + --config) func_config ;; + + --dlopen|-dlopen) + opt_dlopen="${opt_dlopen+$opt_dlopen +}$1" + shift + ;; + + --preserve-dup-deps) + opt_preserve_dup_deps=: ;; + + --features) func_features ;; + + --finish) set dummy --mode finish ${1+"$@"}; shift ;; + + --help) opt_help=: ;; + + --help-all) opt_help=': help-all' ;; + + --mode) test $# = 0 && func_missing_arg $_G_opt && break + opt_mode=$1 + case $1 in + # Valid mode arguments: + clean|compile|execute|finish|install|link|relink|uninstall) ;; + + # Catch anything else as an error + *) func_error "invalid argument for $_G_opt" + exit_cmd=exit + break + ;; + esac + shift + ;; + + --no-silent|--no-quiet) + opt_quiet=false + func_append preserve_args " $_G_opt" + ;; + + --no-warnings|--no-warning|--no-warn) + opt_warning=false + func_append preserve_args " $_G_opt" + ;; + + --no-verbose) + opt_verbose=false + func_append preserve_args " $_G_opt" + ;; + + --silent|--quiet) + opt_quiet=: + opt_verbose=false + func_append preserve_args " $_G_opt" + ;; + + --tag) test $# = 0 && func_missing_arg $_G_opt && break + opt_tag=$1 + func_append preserve_args " $_G_opt $1" + func_enable_tag "$1" + shift + ;; + + --verbose|-v) opt_quiet=false + opt_verbose=: + func_append preserve_args " $_G_opt" + ;; + + # An option not handled by this hook function: + *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; + esac + done + + + # save modified positional parameters for caller + func_quote_for_eval ${1+"$@"} + libtool_parse_options_result=$func_quote_for_eval_result +} +func_add_hook func_parse_options libtool_parse_options + + + +# libtool_validate_options [ARG]... +# --------------------------------- +# Perform any sanity checks on option settings and/or unconsumed +# arguments. +libtool_validate_options () +{ + # save first non-option argument + if test 0 -lt $#; then + nonopt=$1 + shift + fi + + # preserve --debug + test : = "$debug_cmd" || func_append preserve_args " --debug" + + case $host in + # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452 + # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788 + *cygwin* | *mingw* | *pw32* | *cegcc* | *solaris2* | *os2*) + # don't eliminate duplications in $postdeps and $predeps + opt_duplicate_compiler_generated_deps=: + ;; + *) + opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps + ;; + esac + + $opt_help || { + # Sanity checks first: + func_check_version_match + + test yes != "$build_libtool_libs" \ + && test yes != "$build_old_libs" \ + && func_fatal_configuration "not configured to build any kind of library" + + # Darwin sucks + eval std_shrext=\"$shrext_cmds\" + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$opt_dlopen" && test execute != "$opt_mode"; then + func_error "unrecognized option '-dlopen'" + $ECHO "$help" 1>&2 + exit $EXIT_FAILURE + fi + + # Change the help message to a mode-specific one. + generic_help=$help + help="Try '$progname --help --mode=$opt_mode' for more information." + } + + # Pass back the unparsed argument list + func_quote_for_eval ${1+"$@"} + libtool_validate_options_result=$func_quote_for_eval_result +} +func_add_hook func_validate_options libtool_validate_options + + +# Process options as early as possible so that --help and --version +# can return quickly. +func_options ${1+"$@"} +eval set dummy "$func_options_result"; shift + + + +## ----------- ## +## Main. ## +## ----------- ## + +magic='%%%MAGIC variable%%%' +magic_exe='%%%MAGIC EXE variable%%%' + +# Global variables. +extracted_archives= +extracted_serial=0 + +# If this variable is set in any of the actions, the command in it +# will be execed at the end. This prevents here-documents from being +# left over by shells. +exec_cmd= + + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' +} + +# func_generated_by_libtool +# True iff stdin has been generated by Libtool. This function is only +# a basic sanity check; it will hardly flush out determined imposters. +func_generated_by_libtool_p () +{ + $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 +} + +# func_lalib_p file +# True iff FILE is a libtool '.la' library or '.lo' object file. +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_lalib_p () +{ + test -f "$1" && + $SED -e 4q "$1" 2>/dev/null | func_generated_by_libtool_p +} + +# func_lalib_unsafe_p file +# True iff FILE is a libtool '.la' library or '.lo' object file. +# This function implements the same check as func_lalib_p without +# resorting to external programs. To this end, it redirects stdin and +# closes it afterwards, without saving the original file descriptor. +# As a safety measure, use it only where a negative result would be +# fatal anyway. Works if 'file' does not exist. +func_lalib_unsafe_p () +{ + lalib_p=no + if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then + for lalib_p_l in 1 2 3 4 + do + read lalib_p_line + case $lalib_p_line in + \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; + esac + done + exec 0<&5 5<&- + fi + test yes = "$lalib_p" +} + +# func_ltwrapper_script_p file +# True iff FILE is a libtool wrapper script +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_script_p () +{ + test -f "$1" && + $lt_truncate_bin < "$1" 2>/dev/null | func_generated_by_libtool_p +} + +# func_ltwrapper_executable_p file +# True iff FILE is a libtool wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_executable_p () +{ + func_ltwrapper_exec_suffix= + case $1 in + *.exe) ;; + *) func_ltwrapper_exec_suffix=.exe ;; + esac + $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 +} + +# func_ltwrapper_scriptname file +# Assumes file is an ltwrapper_executable +# uses $file to determine the appropriate filename for a +# temporary ltwrapper_script. +func_ltwrapper_scriptname () +{ + func_dirname_and_basename "$1" "" "." + func_stripname '' '.exe' "$func_basename_result" + func_ltwrapper_scriptname_result=$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper +} + +# func_ltwrapper_p file +# True iff FILE is a libtool wrapper script or wrapper executable +# This function is only a basic sanity check; it will hardly flush out +# determined imposters. +func_ltwrapper_p () +{ + func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" +} + + +# func_execute_cmds commands fail_cmd +# Execute tilde-delimited COMMANDS. +# If FAIL_CMD is given, eval that upon failure. +# FAIL_CMD may read-access the current command in variable CMD! +func_execute_cmds () +{ + $debug_cmd + + save_ifs=$IFS; IFS='~' + for cmd in $1; do + IFS=$sp$nl + eval cmd=\"$cmd\" + IFS=$save_ifs + func_show_eval "$cmd" "${2-:}" + done + IFS=$save_ifs +} + + +# func_source file +# Source FILE, adding directory component if necessary. +# Note that it is not necessary on cygwin/mingw to append a dot to +# FILE even if both FILE and FILE.exe exist: automatic-append-.exe +# behavior happens only for exec(3), not for open(2)! Also, sourcing +# 'FILE.' does not work on cygwin managed mounts. +func_source () +{ + $debug_cmd + + case $1 in + */* | *\\*) . "$1" ;; + *) . "./$1" ;; + esac +} + + +# func_resolve_sysroot PATH +# Replace a leading = in PATH with a sysroot. Store the result into +# func_resolve_sysroot_result +func_resolve_sysroot () +{ + func_resolve_sysroot_result=$1 + case $func_resolve_sysroot_result in + =*) + func_stripname '=' '' "$func_resolve_sysroot_result" + func_resolve_sysroot_result=$lt_sysroot$func_stripname_result + ;; + esac +} + +# func_replace_sysroot PATH +# If PATH begins with the sysroot, replace it with = and +# store the result into func_replace_sysroot_result. +func_replace_sysroot () +{ + case $lt_sysroot:$1 in + ?*:"$lt_sysroot"*) + func_stripname "$lt_sysroot" '' "$1" + func_replace_sysroot_result='='$func_stripname_result + ;; + *) + # Including no sysroot. + func_replace_sysroot_result=$1 + ;; + esac +} + +# func_infer_tag arg +# Infer tagged configuration to use if any are available and +# if one wasn't chosen via the "--tag" command line option. +# Only attempt this if the compiler in the base compile +# command doesn't match the default compiler. +# arg is usually of the form 'gcc ...' +func_infer_tag () +{ + $debug_cmd + + if test -n "$available_tags" && test -z "$tagname"; then + CC_quoted= + for arg in $CC; do + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case $@ in + # Blanks in the command may have been stripped by the calling shell, + # but not from the CC environment variable when configure was run. + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; + # Blanks at the start of $base_compile will cause this to fail + # if we don't check for them as well. + *) + for z in $available_tags; do + if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then + # Evaluate the configuration. + eval "`$SED -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" + CC_quoted= + for arg in $CC; do + # Double-quote args containing other shell metacharacters. + func_append_quoted CC_quoted "$arg" + done + CC_expanded=`func_echo_all $CC` + CC_quoted_expanded=`func_echo_all $CC_quoted` + case "$@ " in + " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ + " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) + # The compiler in the base compile command matches + # the one in the tagged configuration. + # Assume this is the tagged configuration we want. + tagname=$z + break + ;; + esac + fi + done + # If $tagname still isn't set, then no tagged configuration + # was found and let the user know that the "--tag" command + # line option must be used. + if test -z "$tagname"; then + func_echo "unable to infer tagged configuration" + func_fatal_error "specify a tag with '--tag'" +# else +# func_verbose "using $tagname tagged configuration" + fi + ;; + esac + fi +} + + + +# func_write_libtool_object output_name pic_name nonpic_name +# Create a libtool object file (analogous to a ".la" file), +# but don't create it if we're doing a dry run. +func_write_libtool_object () +{ + write_libobj=$1 + if test yes = "$build_libtool_libs"; then + write_lobj=\'$2\' + else + write_lobj=none + fi + + if test yes = "$build_old_libs"; then + write_oldobj=\'$3\' + else + write_oldobj=none + fi + + $opt_dry_run || { + cat >${write_libobj}T <<EOF +# $write_libobj - a libtool object file +# Generated by $PROGRAM (GNU $PACKAGE) $VERSION +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# Name of the PIC object. +pic_object=$write_lobj + +# Name of the non-PIC object +non_pic_object=$write_oldobj + +EOF + $MV "${write_libobj}T" "$write_libobj" + } +} + + +################################################## +# FILE NAME AND PATH CONVERSION HELPER FUNCTIONS # +################################################## + +# func_convert_core_file_wine_to_w32 ARG +# Helper function used by file name conversion functions when $build is *nix, +# and $host is mingw, cygwin, or some other w32 environment. Relies on a +# correctly configured wine environment available, with the winepath program +# in $build's $PATH. +# +# ARG is the $build file name to be converted to w32 format. +# Result is available in $func_convert_core_file_wine_to_w32_result, and will +# be empty on error (or when ARG is empty) +func_convert_core_file_wine_to_w32 () +{ + $debug_cmd + + func_convert_core_file_wine_to_w32_result=$1 + if test -n "$1"; then + # Unfortunately, winepath does not exit with a non-zero error code, so we + # are forced to check the contents of stdout. On the other hand, if the + # command is not found, the shell will set an exit code of 127 and print + # *an error message* to stdout. So we must check for both error code of + # zero AND non-empty stdout, which explains the odd construction: + func_convert_core_file_wine_to_w32_tmp=`winepath -w "$1" 2>/dev/null` + if test "$?" -eq 0 && test -n "$func_convert_core_file_wine_to_w32_tmp"; then + func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | + $SED -e "$sed_naive_backslashify"` + else + func_convert_core_file_wine_to_w32_result= + fi + fi +} +# end: func_convert_core_file_wine_to_w32 + + +# func_convert_core_path_wine_to_w32 ARG +# Helper function used by path conversion functions when $build is *nix, and +# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly +# configured wine environment available, with the winepath program in $build's +# $PATH. Assumes ARG has no leading or trailing path separator characters. +# +# ARG is path to be converted from $build format to win32. +# Result is available in $func_convert_core_path_wine_to_w32_result. +# Unconvertible file (directory) names in ARG are skipped; if no directory names +# are convertible, then the result may be empty. +func_convert_core_path_wine_to_w32 () +{ + $debug_cmd + + # unfortunately, winepath doesn't convert paths, only file names + func_convert_core_path_wine_to_w32_result= + if test -n "$1"; then + oldIFS=$IFS + IFS=: + for func_convert_core_path_wine_to_w32_f in $1; do + IFS=$oldIFS + func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" + if test -n "$func_convert_core_file_wine_to_w32_result"; then + if test -z "$func_convert_core_path_wine_to_w32_result"; then + func_convert_core_path_wine_to_w32_result=$func_convert_core_file_wine_to_w32_result + else + func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" + fi + fi + done + IFS=$oldIFS + fi +} +# end: func_convert_core_path_wine_to_w32 + + +# func_cygpath ARGS... +# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when +# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) +# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or +# (2), returns the Cygwin file name or path in func_cygpath_result (input +# file name or path is assumed to be in w32 format, as previously converted +# from $build's *nix or MSYS format). In case (3), returns the w32 file name +# or path in func_cygpath_result (input file name or path is assumed to be in +# Cygwin format). Returns an empty string on error. +# +# ARGS are passed to cygpath, with the last one being the file name or path to +# be converted. +# +# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH +# environment variable; do not put it in $PATH. +func_cygpath () +{ + $debug_cmd + + if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then + func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` + if test "$?" -ne 0; then + # on failure, ensure result is empty + func_cygpath_result= + fi + else + func_cygpath_result= + func_error "LT_CYGPATH is empty or specifies non-existent file: '$LT_CYGPATH'" + fi +} +#end: func_cygpath + + +# func_convert_core_msys_to_w32 ARG +# Convert file name or path ARG from MSYS format to w32 format. Return +# result in func_convert_core_msys_to_w32_result. +func_convert_core_msys_to_w32 () +{ + $debug_cmd + + # awkward: cmd appends spaces to result + func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | + $SED -e 's/[ ]*$//' -e "$sed_naive_backslashify"` +} +#end: func_convert_core_msys_to_w32 + + +# func_convert_file_check ARG1 ARG2 +# Verify that ARG1 (a file name in $build format) was converted to $host +# format in ARG2. Otherwise, emit an error message, but continue (resetting +# func_to_host_file_result to ARG1). +func_convert_file_check () +{ + $debug_cmd + + if test -z "$2" && test -n "$1"; then + func_error "Could not determine host file name corresponding to" + func_error " '$1'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback: + func_to_host_file_result=$1 + fi +} +# end func_convert_file_check + + +# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH +# Verify that FROM_PATH (a path in $build format) was converted to $host +# format in TO_PATH. Otherwise, emit an error message, but continue, resetting +# func_to_host_file_result to a simplistic fallback value (see below). +func_convert_path_check () +{ + $debug_cmd + + if test -z "$4" && test -n "$3"; then + func_error "Could not determine the host path corresponding to" + func_error " '$3'" + func_error "Continuing, but uninstalled executables may not work." + # Fallback. This is a deliberately simplistic "conversion" and + # should not be "improved". See libtool.info. + if test "x$1" != "x$2"; then + lt_replace_pathsep_chars="s|$1|$2|g" + func_to_host_path_result=`echo "$3" | + $SED -e "$lt_replace_pathsep_chars"` + else + func_to_host_path_result=$3 + fi + fi +} +# end func_convert_path_check + + +# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG +# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT +# and appending REPL if ORIG matches BACKPAT. +func_convert_path_front_back_pathsep () +{ + $debug_cmd + + case $4 in + $1 ) func_to_host_path_result=$3$func_to_host_path_result + ;; + esac + case $4 in + $2 ) func_append func_to_host_path_result "$3" + ;; + esac +} +# end func_convert_path_front_back_pathsep + + +################################################## +# $build to $host FILE NAME CONVERSION FUNCTIONS # +################################################## +# invoked via '$to_host_file_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# Result will be available in $func_to_host_file_result. + + +# func_to_host_file ARG +# Converts the file name ARG from $build format to $host format. Return result +# in func_to_host_file_result. +func_to_host_file () +{ + $debug_cmd + + $to_host_file_cmd "$1" +} +# end func_to_host_file + + +# func_to_tool_file ARG LAZY +# converts the file name ARG from $build format to toolchain format. Return +# result in func_to_tool_file_result. If the conversion in use is listed +# in (the comma separated) LAZY, no conversion takes place. +func_to_tool_file () +{ + $debug_cmd + + case ,$2, in + *,"$to_tool_file_cmd",*) + func_to_tool_file_result=$1 + ;; + *) + $to_tool_file_cmd "$1" + func_to_tool_file_result=$func_to_host_file_result + ;; + esac +} +# end func_to_tool_file + + +# func_convert_file_noop ARG +# Copy ARG to func_to_host_file_result. +func_convert_file_noop () +{ + func_to_host_file_result=$1 +} +# end func_convert_file_noop + + +# func_convert_file_msys_to_w32 ARG +# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_file_result. +func_convert_file_msys_to_w32 () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_to_host_file_result=$func_convert_core_msys_to_w32_result + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_w32 + + +# func_convert_file_cygwin_to_w32 ARG +# Convert file name ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_file_cygwin_to_w32 () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + # because $build is cygwin, we call "the" cygpath in $PATH; no need to use + # LT_CYGPATH in this case. + func_to_host_file_result=`cygpath -m "$1"` + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_cygwin_to_w32 + + +# func_convert_file_nix_to_w32 ARG +# Convert file name ARG from *nix to w32 format. Requires a wine environment +# and a working winepath. Returns result in func_to_host_file_result. +func_convert_file_nix_to_w32 () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + func_convert_core_file_wine_to_w32 "$1" + func_to_host_file_result=$func_convert_core_file_wine_to_w32_result + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_w32 + + +# func_convert_file_msys_to_cygwin ARG +# Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_file_msys_to_cygwin () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + func_convert_core_msys_to_w32 "$1" + func_cygpath -u "$func_convert_core_msys_to_w32_result" + func_to_host_file_result=$func_cygpath_result + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_msys_to_cygwin + + +# func_convert_file_nix_to_cygwin ARG +# Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed +# in a wine environment, working winepath, and LT_CYGPATH set. Returns result +# in func_to_host_file_result. +func_convert_file_nix_to_cygwin () +{ + $debug_cmd + + func_to_host_file_result=$1 + if test -n "$1"; then + # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. + func_convert_core_file_wine_to_w32 "$1" + func_cygpath -u "$func_convert_core_file_wine_to_w32_result" + func_to_host_file_result=$func_cygpath_result + fi + func_convert_file_check "$1" "$func_to_host_file_result" +} +# end func_convert_file_nix_to_cygwin + + +############################################# +# $build to $host PATH CONVERSION FUNCTIONS # +############################################# +# invoked via '$to_host_path_cmd ARG' +# +# In each case, ARG is the path to be converted from $build to $host format. +# The result will be available in $func_to_host_path_result. +# +# Path separators are also converted from $build format to $host format. If +# ARG begins or ends with a path separator character, it is preserved (but +# converted to $host format) on output. +# +# All path conversion functions are named using the following convention: +# file name conversion function : func_convert_file_X_to_Y () +# path conversion function : func_convert_path_X_to_Y () +# where, for any given $build/$host combination the 'X_to_Y' value is the +# same. If conversion functions are added for new $build/$host combinations, +# the two new functions must follow this pattern, or func_init_to_host_path_cmd +# will break. + + +# func_init_to_host_path_cmd +# Ensures that function "pointer" variable $to_host_path_cmd is set to the +# appropriate value, based on the value of $to_host_file_cmd. +to_host_path_cmd= +func_init_to_host_path_cmd () +{ + $debug_cmd + + if test -z "$to_host_path_cmd"; then + func_stripname 'func_convert_file_' '' "$to_host_file_cmd" + to_host_path_cmd=func_convert_path_$func_stripname_result + fi +} + + +# func_to_host_path ARG +# Converts the path ARG from $build format to $host format. Return result +# in func_to_host_path_result. +func_to_host_path () +{ + $debug_cmd + + func_init_to_host_path_cmd + $to_host_path_cmd "$1" +} +# end func_to_host_path + + +# func_convert_path_noop ARG +# Copy ARG to func_to_host_path_result. +func_convert_path_noop () +{ + func_to_host_path_result=$1 +} +# end func_convert_path_noop + + +# func_convert_path_msys_to_w32 ARG +# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic +# conversion to w32 is not available inside the cwrapper. Returns result in +# func_to_host_path_result. +func_convert_path_msys_to_w32 () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # Remove leading and trailing path separator characters from ARG. MSYS + # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; + # and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result=$func_convert_core_msys_to_w32_result + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_msys_to_w32 + + +# func_convert_path_cygwin_to_w32 ARG +# Convert path ARG from Cygwin to w32 format. Returns result in +# func_to_host_file_result. +func_convert_path_cygwin_to_w32 () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_cygwin_to_w32 + + +# func_convert_path_nix_to_w32 ARG +# Convert path ARG from *nix to w32 format. Requires a wine environment and +# a working winepath. Returns result in func_to_host_file_result. +func_convert_path_nix_to_w32 () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_to_host_path_result=$func_convert_core_path_wine_to_w32_result + func_convert_path_check : ";" \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" + fi +} +# end func_convert_path_nix_to_w32 + + +# func_convert_path_msys_to_cygwin ARG +# Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. +# Returns result in func_to_host_file_result. +func_convert_path_msys_to_cygwin () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # See func_convert_path_msys_to_w32: + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_msys_to_w32_result" + func_to_host_path_result=$func_cygpath_result + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_msys_to_cygwin + + +# func_convert_path_nix_to_cygwin ARG +# Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a +# a wine environment, working winepath, and LT_CYGPATH set. Returns result in +# func_to_host_file_result. +func_convert_path_nix_to_cygwin () +{ + $debug_cmd + + func_to_host_path_result=$1 + if test -n "$1"; then + # Remove leading and trailing path separator characters from + # ARG. msys behavior is inconsistent here, cygpath turns them + # into '.;' and ';.', and winepath ignores them completely. + func_stripname : : "$1" + func_to_host_path_tmp1=$func_stripname_result + func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" + func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" + func_to_host_path_result=$func_cygpath_result + func_convert_path_check : : \ + "$func_to_host_path_tmp1" "$func_to_host_path_result" + func_convert_path_front_back_pathsep ":*" "*:" : "$1" + fi +} +# end func_convert_path_nix_to_cygwin + + +# func_dll_def_p FILE +# True iff FILE is a Windows DLL '.def' file. +# Keep in sync with _LT_DLL_DEF_P in libtool.m4 +func_dll_def_p () +{ + $debug_cmd + + func_dll_def_p_tmp=`$SED -n \ + -e 's/^[ ]*//' \ + -e '/^\(;.*\)*$/d' \ + -e 's/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p' \ + -e q \ + "$1"` + test DEF = "$func_dll_def_p_tmp" +} + + +# func_mode_compile arg... +func_mode_compile () +{ + $debug_cmd + + # Get the compilation command and the source file. + base_compile= + srcfile=$nonopt # always keep a non-empty value in "srcfile" + suppress_opt=yes + suppress_output= + arg_mode=normal + libobj= + later= + pie_flag= + + for arg + do + case $arg_mode in + arg ) + # do not "continue". Instead, add this to base_compile + lastarg=$arg + arg_mode=normal + ;; + + target ) + libobj=$arg + arg_mode=normal + continue + ;; + + normal ) + # Accept any command-line options. + case $arg in + -o) + test -n "$libobj" && \ + func_fatal_error "you cannot specify '-o' more than once" + arg_mode=target + continue + ;; + + -pie | -fpie | -fPIE) + func_append pie_flag " $arg" + continue + ;; + + -shared | -static | -prefer-pic | -prefer-non-pic) + func_append later " $arg" + continue + ;; + + -no-suppress) + suppress_opt=no + continue + ;; + + -Xcompiler) + arg_mode=arg # the next one goes into the "base_compile" arg list + continue # The current "srcfile" will either be retained or + ;; # replaced later. I would guess that would be a bug. + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + lastarg= + save_ifs=$IFS; IFS=, + for arg in $args; do + IFS=$save_ifs + func_append_quoted lastarg "$arg" + done + IFS=$save_ifs + func_stripname ' ' '' "$lastarg" + lastarg=$func_stripname_result + + # Add the arguments to base_compile. + func_append base_compile " $lastarg" + continue + ;; + + *) + # Accept the current argument as the source file. + # The previous "srcfile" becomes the current argument. + # + lastarg=$srcfile + srcfile=$arg + ;; + esac # case $arg + ;; + esac # case $arg_mode + + # Aesthetically quote the previous argument. + func_append_quoted base_compile "$lastarg" + done # for arg + + case $arg_mode in + arg) + func_fatal_error "you must specify an argument for -Xcompile" + ;; + target) + func_fatal_error "you must specify a target with '-o'" + ;; + *) + # Get the name of the library object. + test -z "$libobj" && { + func_basename "$srcfile" + libobj=$func_basename_result + } + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + case $libobj in + *.[cCFSifmso] | \ + *.ada | *.adb | *.ads | *.asm | \ + *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ + *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) + func_xform "$libobj" + libobj=$func_xform_result + ;; + esac + + case $libobj in + *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; + *) + func_fatal_error "cannot determine name of library object from '$libobj'" + ;; + esac + + func_infer_tag $base_compile + + for arg in $later; do + case $arg in + -shared) + test yes = "$build_libtool_libs" \ + || func_fatal_configuration "cannot build a shared library" + build_old_libs=no + continue + ;; + + -static) + build_libtool_libs=no + build_old_libs=yes + continue + ;; + + -prefer-pic) + pic_mode=yes + continue + ;; + + -prefer-non-pic) + pic_mode=no + continue + ;; + esac + done + + func_quote_for_eval "$libobj" + test "X$libobj" != "X$func_quote_for_eval_result" \ + && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ + && func_warning "libobj name '$libobj' may not contain shell special characters." + func_dirname_and_basename "$obj" "/" "" + objname=$func_basename_result + xdir=$func_dirname_result + lobj=$xdir$objdir/$objname + + test -z "$base_compile" && \ + func_fatal_help "you must specify a compilation command" + + # Delete any leftover library objects. + if test yes = "$build_old_libs"; then + removelist="$obj $lobj $libobj ${libobj}T" + else + removelist="$lobj $libobj ${libobj}T" + fi + + # On Cygwin there's no "real" PIC flag so we must build both object types + case $host_os in + cygwin* | mingw* | pw32* | os2* | cegcc*) + pic_mode=default + ;; + esac + if test no = "$pic_mode" && test pass_all != "$deplibs_check_method"; then + # non-PIC code in shared libraries is not supported + pic_mode=default + fi + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test no = "$compiler_c_o"; then + output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.$objext + lockfile=$output_obj.lock + else + output_obj= + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test yes = "$need_locks"; then + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + elif test warn = "$need_locks"; then + if test -f "$lockfile"; then + $ECHO "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support '-c' and '-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + func_append removelist " $output_obj" + $ECHO "$srcfile" > "$lockfile" + fi + + $opt_dry_run || $RM $removelist + func_append removelist " $lockfile" + trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 + + func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 + srcfile=$func_to_tool_file_result + func_quote_for_eval "$srcfile" + qsrcfile=$func_quote_for_eval_result + + # Only build a PIC object if we are building libtool libraries. + if test yes = "$build_libtool_libs"; then + # Without this assignment, base_compile gets emptied. + fbsd_hideous_sh_bug=$base_compile + + if test no != "$pic_mode"; then + command="$base_compile $qsrcfile $pic_flag" + else + # Don't build PIC code + command="$base_compile $qsrcfile" + fi + + func_mkdir_p "$xdir$objdir" + + if test -z "$output_obj"; then + # Place PIC objects in $objdir + func_append command " -o $lobj" + fi + + func_show_eval_locale "$command" \ + 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' + + if test warn = "$need_locks" && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support '-c' and '-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed, then go on to compile the next one + if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then + func_show_eval '$MV "$output_obj" "$lobj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + + # Allow error messages only from the first compilation. + if test yes = "$suppress_opt"; then + suppress_output=' >/dev/null 2>&1' + fi + fi + + # Only build a position-dependent object if we build old libraries. + if test yes = "$build_old_libs"; then + if test yes != "$pic_mode"; then + # Don't build PIC code + command="$base_compile $qsrcfile$pie_flag" + else + command="$base_compile $qsrcfile $pic_flag" + fi + if test yes = "$compiler_c_o"; then + func_append command " -o $obj" + fi + + # Suppress compiler output if we already did a PIC compilation. + func_append command "$suppress_output" + func_show_eval_locale "$command" \ + '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' + + if test warn = "$need_locks" && + test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then + $ECHO "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support '-c' and '-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $opt_dry_run || $RM $removelist + exit $EXIT_FAILURE + fi + + # Just move the object if needed + if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then + func_show_eval '$MV "$output_obj" "$obj"' \ + 'error=$?; $opt_dry_run || $RM $removelist; exit $error' + fi + fi + + $opt_dry_run || { + func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" + + # Unlock the critical section if it was locked + if test no != "$need_locks"; then + removelist=$lockfile + $RM "$lockfile" + fi + } + + exit $EXIT_SUCCESS +} + +$opt_help || { + test compile = "$opt_mode" && func_mode_compile ${1+"$@"} +} + +func_mode_help () +{ + # We need to display help for each of the modes. + case $opt_mode in + "") + # Generic help is extracted from the usage comments + # at the start of this file. + func_help + ;; + + clean) + $ECHO \ +"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... + +Remove files from the build 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, object or program, all the files associated +with it are deleted. Otherwise, only FILE itself is deleted using RM." + ;; + + compile) + $ECHO \ +"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -no-suppress do not suppress compiler output for multiple passes + -prefer-pic try to build PIC objects only + -prefer-non-pic try to build non-PIC objects only + -shared do not build a '.o' file suitable for static linking + -static only build a '.o' file suitable for static linking + -Wc,FLAG pass FLAG directly to the compiler + +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: $progname [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: $progname [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: $progname [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 following components of INSTALL-COMMAND are treated specially: + + -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + + link) + $ECHO \ +"Usage: $progname [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 + -avoid-version do not add a version suffix if possible + -bindir BINDIR specify path to binaries directory (for systems where + libraries must be found in the PATH setting at runtime) + -dlopen FILE '-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-fast-install disable the fast-install mode + -no-install link a not-installable executable + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -objectlist FILE use a list of object files found in FILE to specify objects + -os2dllname NAME force a short DLL name on OS/2 (no effect on other OSes) + -precious-files-regex REGEX + don't remove output files matching REGEX + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -shared only do dynamic linking of libtool libraries + -shrext SUFFIX override the standard shared library file extension + -static do not do any dynamic linking of uninstalled libtool libraries + -static-libtool-libs + do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + -weak LIBNAME declare that the target provides the LIBNAME interface + -Wc,FLAG + -Xcompiler FLAG pass linker-specific FLAG directly to the compiler + -Wl,FLAG + -Xlinker FLAG pass linker-specific FLAG directly to the linker + -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) + +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, except when creating a convenience library. + +If OUTPUT-FILE ends in '.a' or '.lib', then a standard library is created +using 'ar' and 'ranlib', or on Windows using 'lib'. + +If OUTPUT-FILE ends in '.lo' or '.$objext', then a reloadable object file +is created, otherwise an executable program is created." + ;; + + uninstall) + $ECHO \ +"Usage: $progname [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." + ;; + + *) + func_fatal_help "invalid operation mode '$opt_mode'" + ;; + esac + + echo + $ECHO "Try '$progname --help' for more information about other modes." +} + +# Now that we've collected a possible --mode arg, show help if necessary +if $opt_help; then + if test : = "$opt_help"; then + func_mode_help + else + { + func_help noexit + for opt_mode in compile link execute install finish uninstall clean; do + func_mode_help + done + } | $SED -n '1p; 2,$s/^Usage:/ or: /p' + { + func_help noexit + for opt_mode in compile link execute install finish uninstall clean; do + echo + func_mode_help + done + } | + $SED '1d + /^When reporting/,/^Report/{ + H + d + } + $x + /information about other modes/d + /more detailed .*MODE/d + s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' + fi + exit $? +fi + + +# func_mode_execute arg... +func_mode_execute () +{ + $debug_cmd + + # The first argument is the command name. + cmd=$nonopt + test -z "$cmd" && \ + func_fatal_help "you must specify a COMMAND" + + # Handle -dlopen flags immediately. + for file in $opt_dlopen; do + test -f "$file" \ + || func_fatal_help "'$file' is not a file" + + dir= + case $file in + *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "'$lib' is not a valid libtool archive" + + # Read the libtool library. + dlname= + library_names= + func_source "$file" + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && \ + func_warning "'$file' was not linked with '-export-dynamic'" + continue + fi + + func_dirname "$file" "" "." + dir=$func_dirname_result + + if test -f "$dir/$objdir/$dlname"; then + func_append dir "/$objdir" + else + if test ! -f "$dir/$dlname"; then + func_fatal_error "cannot find '$dlname' in '$dir' or '$dir/$objdir'" + fi + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + func_dirname "$file" "" "." + dir=$func_dirname_result + ;; + + *) + func_warning "'-dlopen' is ignored for non-libtool libraries and objects" + 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 + -* | *.la | *.lo ) ;; + *) + # Do a test to see if this is really a libtool program. + if func_ltwrapper_script_p "$file"; then + func_source "$file" + # Transform arg to wrapped name. + file=$progdir/$program + elif func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + func_source "$func_ltwrapper_scriptname_result" + # Transform arg to wrapped name. + file=$progdir/$program + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + func_append_quoted args "$file" + done + + if $opt_dry_run; then + # Display what would be done. + if test -n "$shlibpath_var"; then + eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" + echo "export $shlibpath_var" + fi + $ECHO "$cmd$args" + exit $EXIT_SUCCESS + else + if test -n "$shlibpath_var"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + fi + + # Restore saved environment variables + for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES + do + eval "if test \"\${save_$lt_var+set}\" = set; then + $lt_var=\$save_$lt_var; export $lt_var + else + $lt_unset $lt_var + fi" + done + + # Now prepare to actually exec the command. + exec_cmd=\$cmd$args + fi +} + +test execute = "$opt_mode" && func_mode_execute ${1+"$@"} + + +# func_mode_finish arg... +func_mode_finish () +{ + $debug_cmd + + libs= + libdirs= + admincmds= + + for opt in "$nonopt" ${1+"$@"} + do + if test -d "$opt"; then + func_append libdirs " $opt" + + elif test -f "$opt"; then + if func_lalib_unsafe_p "$opt"; then + func_append libs " $opt" + else + func_warning "'$opt' is not a valid libtool archive" + fi + + else + func_fatal_error "invalid argument '$opt'" + fi + done + + if test -n "$libs"; then + if test -n "$lt_sysroot"; then + sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` + sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" + else + sysroot_cmd= + fi + + # Remove sysroot references + if $opt_dry_run; then + for lib in $libs; do + echo "removing references to $lt_sysroot and '=' prefixes from $lib" + done + else + tmpdir=`func_mktempdir` + for lib in $libs; do + $SED -e "$sysroot_cmd s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ + > $tmpdir/tmp-la + mv -f $tmpdir/tmp-la $lib + done + ${RM}r "$tmpdir" + fi + fi + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + func_execute_cmds "$finish_cmds" 'admincmds="$admincmds +'"$cmd"'"' + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $opt_dry_run || eval "$cmds" || func_append admincmds " + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + $opt_quiet && exit $EXIT_SUCCESS + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + echo "----------------------------------------------------------------------" + echo "Libraries have been installed in:" + for libdir in $libdirs; do + $ECHO " $libdir" + done + echo + echo "If you ever happen to want to link against installed libraries" + echo "in a given directory, LIBDIR, you must either use libtool, and" + echo "specify the full pathname of the library, or use the '-LLIBDIR'" + echo "flag during linking and do at least 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 -n "$admincmds"; then + $ECHO " - have your system administrator run these commands:$admincmds" + 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" + case $host in + solaris2.[6789]|solaris2.1[0-9]) + echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" + echo "pages." + ;; + *) + echo "more information, such as the ld(1) and ld.so(8) manual pages." + ;; + esac + echo "----------------------------------------------------------------------" + fi + exit $EXIT_SUCCESS +} + +test finish = "$opt_mode" && func_mode_finish ${1+"$@"} + + +# func_mode_install arg... +func_mode_install () +{ + $debug_cmd + + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$SHELL" = "$nonopt" || test /bin/sh = "$nonopt" || + # Allow the use of GNU shtool's install command. + case $nonopt in *shtool*) :;; *) false;; esac + then + # Aesthetically quote it. + func_quote_for_eval "$nonopt" + install_prog="$func_quote_for_eval_result " + arg=$1 + shift + else + install_prog= + arg=$nonopt + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + func_quote_for_eval "$arg" + func_append install_prog "$func_quote_for_eval_result" + install_shared_prog=$install_prog + case " $install_prog " in + *[\\\ /]cp\ *) install_cp=: ;; + *) install_cp=false ;; + esac + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=false + stripme= + no_mode=: + for arg + do + arg2= + if test -n "$dest"; then + func_append files " $dest" + dest=$arg + continue + fi + + case $arg in + -d) isdir=: ;; + -f) + if $install_cp; then :; else + prev=$arg + fi + ;; + -g | -m | -o) + prev=$arg + ;; + -s) + stripme=" -s" + continue + ;; + -*) + ;; + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + if test X-m = "X$prev" && test -n "$install_override_mode"; then + arg2=$install_override_mode + no_mode=false + fi + prev= + else + dest=$arg + continue + fi + ;; + esac + + # Aesthetically quote the argument. + func_quote_for_eval "$arg" + func_append install_prog " $func_quote_for_eval_result" + if test -n "$arg2"; then + func_quote_for_eval "$arg2" + fi + func_append install_shared_prog " $func_quote_for_eval_result" + done + + test -z "$install_prog" && \ + func_fatal_help "you must specify an install program" + + test -n "$prev" && \ + func_fatal_help "the '$prev' option requires an argument" + + if test -n "$install_override_mode" && $no_mode; then + if $install_cp; then :; else + func_quote_for_eval "$install_override_mode" + func_append install_shared_prog " -m $func_quote_for_eval_result" + fi + fi + + if test -z "$files"; then + if test -z "$dest"; then + func_fatal_help "no file or destination specified" + else + func_fatal_help "you must specify a destination" + fi + fi + + # Strip any trailing slash from the destination. + func_stripname '' '/' "$dest" + dest=$func_stripname_result + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=: + if $isdir; then + destdir=$dest + destname= + else + func_dirname_and_basename "$dest" "" "." + destdir=$func_dirname_result + destname=$func_basename_result + + # Not a directory, so check to see that there is only one file specified. + set dummy $files; shift + test "$#" -gt 1 && \ + func_fatal_help "'$dest' is not a directory" + fi + case $destdir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case $file in + *.lo) ;; + *) + func_fatal_help "'$destdir' must be an absolute directory name" + ;; + 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 + *.$libext) + # Do the static libraries later. + func_append staticlibs " $file" + ;; + + *.la) + func_resolve_sysroot "$file" + file=$func_resolve_sysroot_result + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$file" \ + || func_fatal_help "'$file' is not a valid libtool archive" + + library_names= + old_library= + relink_command= + func_source "$file" + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) func_append current_libdirs " $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) func_append future_libdirs " $libdir" ;; + esac + fi + + func_dirname "$file" "/" "" + dir=$func_dirname_result + func_append dir "$objdir" + + if test -n "$relink_command"; then + # Determine the prefix the user has applied to our future dir. + inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` + + # Don't allow the user to place us outside of our expected + # location b/c this prevents finding dependent libraries that + # are installed to the same prefix. + # At present, this check doesn't affect windows .dll's that + # are installed into $libdir/../bin (currently, that works fine) + # but it's something to keep an eye on. + test "$inst_prefix_dir" = "$destdir" && \ + func_fatal_error "error: cannot install '$file' to a directory not ending in $libdir" + + if test -n "$inst_prefix_dir"; then + # Stick the inst_prefix_dir data into the link command. + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` + else + relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` + fi + + func_warning "relinking '$file'" + func_show_eval "$relink_command" \ + 'func_fatal_error "error: relink '\''$file'\'' with the above command before installing it"' + fi + + # See the names of the shared library. + set dummy $library_names; shift + if test -n "$1"; then + realname=$1 + shift + + srcname=$realname + test -n "$relink_command" && srcname=${realname}T + + # Install the shared library and build the symlinks. + func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ + 'exit $?' + tstripme=$stripme + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + case $realname in + *.dll.a) + tstripme= + ;; + esac + ;; + os2*) + case $realname in + *_dll.a) + tstripme= + ;; + esac + ;; + esac + if test -n "$tstripme" && test -n "$striplib"; then + func_show_eval "$striplib $destdir/$realname" 'exit $?' + fi + + if test "$#" -gt 0; then + # Delete the old symlinks, and create new ones. + # Try 'ln -sf' first, because the 'ln' binary might depend on + # the symlink we replace! Solaris /bin/ln does not understand -f, + # so we also need to try rm && ln -s. + for linkname + do + test "$linkname" != "$realname" \ + && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" + done + fi + + # Do each command in the postinstall commands. + lib=$destdir/$realname + func_execute_cmds "$postinstall_cmds" 'exit $?' + fi + + # Install the pseudo-library for information purposes. + func_basename "$file" + name=$func_basename_result + instname=$dir/${name}i + func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' + + # Maybe install the static library, too. + test -n "$old_library" && func_append 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 + func_basename "$file" + destfile=$func_basename_result + destfile=$destdir/$destfile + fi + + # Deduce the name of the destination old-style object file. + case $destfile in + *.lo) + func_lo2o "$destfile" + staticdest=$func_lo2o_result + ;; + *.$objext) + staticdest=$destfile + destfile= + ;; + *) + func_fatal_help "cannot copy a libtool object to '$destfile'" + ;; + esac + + # Install the libtool object if requested. + test -n "$destfile" && \ + func_show_eval "$install_prog $file $destfile" 'exit $?' + + # Install the old object if enabled. + if test yes = "$build_old_libs"; then + # Deduce the name of the old-style object file. + func_lo2o "$file" + staticobj=$func_lo2o_result + func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' + fi + exit $EXIT_SUCCESS + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile=$destdir/$destname + else + func_basename "$file" + destfile=$func_basename_result + destfile=$destdir/$destfile + fi + + # If the file is missing, and there is a .exe on the end, strip it + # because it is most likely a libtool script we actually want to + # install + stripped_ext= + case $file in + *.exe) + if test ! -f "$file"; then + func_stripname '' '.exe' "$file" + file=$func_stripname_result + stripped_ext=.exe + fi + ;; + esac + + # Do a test to see if this is really a libtool program. + case $host in + *cygwin* | *mingw*) + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + wrapper=$func_ltwrapper_scriptname_result + else + func_stripname '' '.exe' "$file" + wrapper=$func_stripname_result + fi + ;; + *) + wrapper=$file + ;; + esac + if func_ltwrapper_script_p "$wrapper"; then + notinst_deplibs= + relink_command= + + func_source "$wrapper" + + # Check the variables that should have been set. + test -z "$generated_by_libtool_version" && \ + func_fatal_error "invalid libtool wrapper script '$wrapper'" + + finalize=: + for lib in $notinst_deplibs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + func_source "$lib" + fi + libfile=$libdir/`$ECHO "$lib" | $SED 's%^.*/%%g'` + if test -n "$libdir" && test ! -f "$libfile"; then + func_warning "'$lib' has not been installed in '$libdir'" + finalize=false + fi + done + + relink_command= + func_source "$wrapper" + + outputname= + if test no = "$fast_install" && test -n "$relink_command"; then + $opt_dry_run || { + if $finalize; then + tmpdir=`func_mktempdir` + func_basename "$file$stripped_ext" + file=$func_basename_result + outputname=$tmpdir/$file + # Replace the output file specification. + relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` + + $opt_quiet || { + func_quote_for_expand "$relink_command" + eval "func_echo $func_quote_for_expand_result" + } + if eval "$relink_command"; then : + else + func_error "error: relink '$file' with the above command before installing it" + $opt_dry_run || ${RM}r "$tmpdir" + continue + fi + file=$outputname + else + func_warning "cannot relink '$file'" + fi + } + else + # Install the binary that we compiled earlier. + file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + # remove .exe since cygwin /usr/bin/install will append another + # one anyway + case $install_prog,$host in + */usr/bin/install*,*cygwin*) + case $file:$destfile in + *.exe:*.exe) + # this is ok + ;; + *.exe:*) + destfile=$destfile.exe + ;; + *:*.exe) + func_stripname '' '.exe' "$destfile" + destfile=$func_stripname_result + ;; + esac + ;; + esac + func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' + $opt_dry_run || if test -n "$outputname"; then + ${RM}r "$tmpdir" + fi + ;; + esac + done + + for file in $staticlibs; do + func_basename "$file" + name=$func_basename_result + + # Set up the ranlib parameters. + oldlib=$destdir/$name + func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 + tool_oldlib=$func_to_tool_file_result + + func_show_eval "$install_prog \$file \$oldlib" 'exit $?' + + if test -n "$stripme" && test -n "$old_striplib"; then + func_show_eval "$old_striplib $tool_oldlib" 'exit $?' + fi + + # Do each command in the postinstall commands. + func_execute_cmds "$old_postinstall_cmds" 'exit $?' + done + + test -n "$future_libdirs" && \ + func_warning "remember to run '$progname --finish$future_libdirs'" + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + $opt_dry_run && current_libdirs=" -n$current_libdirs" + exec_cmd='$SHELL "$progpath" $preserve_args --finish$current_libdirs' + else + exit $EXIT_SUCCESS + fi +} + +test install = "$opt_mode" && func_mode_install ${1+"$@"} + + +# func_generate_dlsyms outputname originator pic_p +# Extract symbols from dlprefiles and create ${outputname}S.o with +# a dlpreopen symbol table. +func_generate_dlsyms () +{ + $debug_cmd + + my_outputname=$1 + my_originator=$2 + my_pic_p=${3-false} + my_prefix=`$ECHO "$my_originator" | $SED 's%[^a-zA-Z0-9]%_%g'` + my_dlsyms= + + if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + my_dlsyms=${my_outputname}S.c + else + func_error "not configured to extract global symbols from dlpreopened files" + fi + fi + + if test -n "$my_dlsyms"; then + case $my_dlsyms in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist=$output_objdir/$my_outputname.nm + + func_show_eval "$RM $nlist ${nlist}S ${nlist}T" + + # Parse the name list into a source file. + func_verbose "creating $output_objdir/$my_dlsyms" + + $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ +/* $my_dlsyms - symbol resolution table for '$my_outputname' dlsym emulation. */ +/* Generated by $PROGRAM (GNU $PACKAGE) $VERSION */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +#if defined __GNUC__ && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) +#pragma GCC diagnostic ignored \"-Wstrict-prototypes\" +#endif + +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE +/* DATA imports from DLLs on WIN32 can't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined __osf__ +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) + +/* External symbol declarations for the compiler. */\ +" + + if test yes = "$dlself"; then + func_verbose "generating symbol list for '$output'" + + $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` + for progfile in $progfiles; do + func_to_tool_file "$progfile" func_convert_file_msys_to_w32 + func_verbose "extracting global C symbols from '$func_to_tool_file_result'" + $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $opt_dry_run || { + eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + if test -n "$export_symbols_regex"; then + $opt_dry_run || { + eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + } + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols=$output_objdir/$outputname.exp + $opt_dry_run || { + $RM $export_symbols + eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' + ;; + esac + } + else + $opt_dry_run || { + eval "$SED -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' + eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' + eval '$MV "$nlist"T "$nlist"' + case $host in + *cygwin* | *mingw* | *cegcc* ) + eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' + eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' + ;; + esac + } + fi + fi + + for dlprefile in $dlprefiles; do + func_verbose "extracting global C symbols from '$dlprefile'" + func_basename "$dlprefile" + name=$func_basename_result + case $host in + *cygwin* | *mingw* | *cegcc* ) + # if an import library, we need to obtain dlname + if func_win32_import_lib_p "$dlprefile"; then + func_tr_sh "$dlprefile" + eval "curr_lafile=\$libfile_$func_tr_sh_result" + dlprefile_dlbasename= + if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then + # Use subshell, to avoid clobbering current variable values + dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` + if test -n "$dlprefile_dlname"; then + func_basename "$dlprefile_dlname" + dlprefile_dlbasename=$func_basename_result + else + # no lafile. user explicitly requested -dlpreopen <import library>. + $sharedlib_from_linklib_cmd "$dlprefile" + dlprefile_dlbasename=$sharedlib_from_linklib_result + fi + fi + $opt_dry_run || { + if test -n "$dlprefile_dlbasename"; then + eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' + else + func_warning "Could not compute DLL name from $name" + eval '$ECHO ": $name " >> "$nlist"' + fi + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | + $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" + } + else # not an import lib + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + fi + ;; + *) + $opt_dry_run || { + eval '$ECHO ": $name " >> "$nlist"' + func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" + } + ;; + esac + done + + $opt_dry_run || { + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $MV "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if $GREP -v "^: " < "$nlist" | + if sort -k 3 </dev/null >/dev/null 2>&1; then + sort -k 3 + else + sort +2 + fi | + uniq > "$nlist"S; then + : + else + $GREP -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' + else + echo '/* NONE */' >> "$output_objdir/$my_dlsyms" + fi + + func_show_eval '$RM "${nlist}I"' + if test -n "$global_symbol_to_import"; then + eval "$global_symbol_to_import"' < "$nlist"S > "$nlist"I' + fi + + echo >> "$output_objdir/$my_dlsyms" "\ + +/* The mapping between symbol names and symbols. */ +typedef struct { + const char *name; + void *address; +} lt_dlsymlist; +extern LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[];\ +" + + if test -s "$nlist"I; then + echo >> "$output_objdir/$my_dlsyms" "\ +static void lt_syminit(void) +{ + LT_DLSYM_CONST lt_dlsymlist *symbol = lt_${my_prefix}_LTX_preloaded_symbols; + for (; symbol->name; ++symbol) + {" + $SED 's/.*/ if (STREQ (symbol->name, \"&\")) symbol->address = (void *) \&&;/' < "$nlist"I >> "$output_objdir/$my_dlsyms" + echo >> "$output_objdir/$my_dlsyms" "\ + } +}" + fi + echo >> "$output_objdir/$my_dlsyms" "\ +LT_DLSYM_CONST lt_dlsymlist +lt_${my_prefix}_LTX_preloaded_symbols[] = +{ {\"$my_originator\", (void *) 0}," + + if test -s "$nlist"I; then + echo >> "$output_objdir/$my_dlsyms" "\ + {\"@INIT@\", (void *) <_syminit}," + fi + + case $need_lib_prefix in + no) + eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + *) + eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" + ;; + esac + echo >> "$output_objdir/$my_dlsyms" "\ + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_${my_prefix}_LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + } # !$opt_dry_run + + pic_flag_for_symtable= + case "$compile_command " in + *" -static "*) ;; + *) + case $host in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) + pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; + *-*-hpux*) + pic_flag_for_symtable=" $pic_flag" ;; + *) + $my_pic_p && pic_flag_for_symtable=" $pic_flag" + ;; + esac + ;; + esac + symtab_cflags= + for arg in $LTCFLAGS; do + case $arg in + -pie | -fpie | -fPIE) ;; + *) func_append symtab_cflags " $arg" ;; + esac + done + + # Now compile the dynamic symbol file. + func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' + + # Clean up the generated files. + func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T" "${nlist}I"' + + # Transform the symbol file into the correct name. + symfileobj=$output_objdir/${my_outputname}S.$objext + case $host in + *cygwin* | *mingw* | *cegcc* ) + if test -f "$output_objdir/$my_outputname.def"; then + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` + else + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + fi + ;; + *) + compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` + ;; + esac + ;; + *) + func_fatal_error "unknown suffix for '$my_dlsyms'" + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` + finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` + fi +} + +# func_cygming_gnu_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is a GNU/binutils-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_gnu_implib_p () +{ + $debug_cmd + + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` + test -n "$func_cygming_gnu_implib_tmp" +} + +# func_cygming_ms_implib_p ARG +# This predicate returns with zero status (TRUE) if +# ARG is an MS-style import library. Returns +# with nonzero status (FALSE) otherwise. +func_cygming_ms_implib_p () +{ + $debug_cmd + + func_to_tool_file "$1" func_convert_file_msys_to_w32 + func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` + test -n "$func_cygming_ms_implib_tmp" +} + +# func_win32_libid arg +# return the library type of file 'arg' +# +# Need a lot of goo to handle *both* DLLs and import libs +# Has to be a shell function in order to 'eat' the argument +# that is supplied when $file_magic_command is called. +# Despite the name, also deal with 64 bit binaries. +func_win32_libid () +{ + $debug_cmd + + win32_libid_type=unknown + win32_fileres=`file -L $1 2>/dev/null` + case $win32_fileres in + *ar\ archive\ import\ library*) # definitely import + win32_libid_type="x86 archive import" + ;; + *ar\ archive*) # could be an import, or static + # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. + if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | + $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then + case $nm_interface in + "MS dumpbin") + if func_cygming_ms_implib_p "$1" || + func_cygming_gnu_implib_p "$1" + then + win32_nmres=import + else + win32_nmres= + fi + ;; + *) + func_to_tool_file "$1" func_convert_file_msys_to_w32 + win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | + $SED -n -e ' + 1,100{ + / I /{ + s|.*|import| + p + q + } + }'` + ;; + esac + case $win32_nmres in + import*) win32_libid_type="x86 archive import";; + *) win32_libid_type="x86 archive static";; + esac + fi + ;; + *DLL*) + win32_libid_type="x86 DLL" + ;; + *executable*) # but shell scripts are "executable" too... + case $win32_fileres in + *MS\ Windows\ PE\ Intel*) + win32_libid_type="x86 DLL" + ;; + esac + ;; + esac + $ECHO "$win32_libid_type" +} + +# func_cygming_dll_for_implib ARG +# +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib () +{ + $debug_cmd + + sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` +} + +# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs +# +# The is the core of a fallback implementation of a +# platform-specific function to extract the name of the +# DLL associated with the specified import library LIBNAME. +# +# SECTION_NAME is either .idata$6 or .idata$7, depending +# on the platform and compiler that created the implib. +# +# Echos the name of the DLL associated with the +# specified import library. +func_cygming_dll_for_implib_fallback_core () +{ + $debug_cmd + + match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` + $OBJDUMP -s --section "$1" "$2" 2>/dev/null | + $SED '/^Contents of section '"$match_literal"':/{ + # Place marker at beginning of archive member dllname section + s/.*/====MARK====/ + p + d + } + # These lines can sometimes be longer than 43 characters, but + # are always uninteresting + /:[ ]*file format pe[i]\{,1\}-/d + /^In archive [^:]*:/d + # Ensure marker is printed + /^====MARK====/p + # Remove all lines with less than 43 characters + /^.\{43\}/!d + # From remaining lines, remove first 43 characters + s/^.\{43\}//' | + $SED -n ' + # Join marker and all lines until next marker into a single line + /^====MARK====/ b para + H + $ b para + b + :para + x + s/\n//g + # Remove the marker + s/^====MARK====// + # Remove trailing dots and whitespace + s/[\. \t]*$// + # Print + /./p' | + # we now have a list, one entry per line, of the stringified + # contents of the appropriate section of all members of the + # archive that possess that section. Heuristic: eliminate + # all those that have a first or second character that is + # a '.' (that is, objdump's representation of an unprintable + # character.) This should work for all archives with less than + # 0x302f exports -- but will fail for DLLs whose name actually + # begins with a literal '.' or a single character followed by + # a '.'. + # + # Of those that remain, print the first one. + $SED -e '/^\./d;/^.\./d;q' +} + +# func_cygming_dll_for_implib_fallback ARG +# Platform-specific function to extract the +# name of the DLL associated with the specified +# import library ARG. +# +# This fallback implementation is for use when $DLLTOOL +# does not support the --identify-strict option. +# Invoked by eval'ing the libtool variable +# $sharedlib_from_linklib_cmd +# Result is available in the variable +# $sharedlib_from_linklib_result +func_cygming_dll_for_implib_fallback () +{ + $debug_cmd + + if func_cygming_gnu_implib_p "$1"; then + # binutils import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` + elif func_cygming_ms_implib_p "$1"; then + # ms-generated import library + sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` + else + # unknown + sharedlib_from_linklib_result= + fi +} + + +# func_extract_an_archive dir oldlib +func_extract_an_archive () +{ + $debug_cmd + + f_ex_an_ar_dir=$1; shift + f_ex_an_ar_oldlib=$1 + if test yes = "$lock_old_archive_extraction"; then + lockfile=$f_ex_an_ar_oldlib.lock + until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do + func_echo "Waiting for $lockfile to be removed" + sleep 2 + done + fi + func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ + 'stat=$?; rm -f "$lockfile"; exit $stat' + if test yes = "$lock_old_archive_extraction"; then + $opt_dry_run || rm -f "$lockfile" + fi + if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then + : + else + func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" + fi +} + + +# func_extract_archives gentop oldlib ... +func_extract_archives () +{ + $debug_cmd + + my_gentop=$1; shift + my_oldlibs=${1+"$@"} + my_oldobjs= + my_xlib= + my_xabs= + my_xdir= + + for my_xlib in $my_oldlibs; do + # Extract the objects. + case $my_xlib in + [\\/]* | [A-Za-z]:[\\/]*) my_xabs=$my_xlib ;; + *) my_xabs=`pwd`"/$my_xlib" ;; + esac + func_basename "$my_xlib" + my_xlib=$func_basename_result + my_xlib_u=$my_xlib + while :; do + case " $extracted_archives " in + *" $my_xlib_u "*) + func_arith $extracted_serial + 1 + extracted_serial=$func_arith_result + my_xlib_u=lt$extracted_serial-$my_xlib ;; + *) break ;; + esac + done + extracted_archives="$extracted_archives $my_xlib_u" + my_xdir=$my_gentop/$my_xlib_u + + func_mkdir_p "$my_xdir" + + case $host in + *-darwin*) + func_verbose "Extracting $my_xabs" + # Do not bother doing anything if just a dry run + $opt_dry_run || { + darwin_orig_dir=`pwd` + cd $my_xdir || exit $? + darwin_archive=$my_xabs + darwin_curdir=`pwd` + func_basename "$darwin_archive" + darwin_base_archive=$func_basename_result + darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` + if test -n "$darwin_arches"; then + darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` + darwin_arch= + func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" + for darwin_arch in $darwin_arches; do + func_mkdir_p "unfat-$$/$darwin_base_archive-$darwin_arch" + $LIPO -thin $darwin_arch -output "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" "$darwin_archive" + cd "unfat-$$/$darwin_base_archive-$darwin_arch" + func_extract_an_archive "`pwd`" "$darwin_base_archive" + cd "$darwin_curdir" + $RM "unfat-$$/$darwin_base_archive-$darwin_arch/$darwin_base_archive" + done # $darwin_arches + ## Okay now we've a bunch of thin objects, gotta fatten them up :) + darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$sed_basename" | sort -u` + darwin_file= + darwin_files= + for darwin_file in $darwin_filelist; do + darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` + $LIPO -create -output "$darwin_file" $darwin_files + done # $darwin_filelist + $RM -rf unfat-$$ + cd "$darwin_orig_dir" + else + cd $darwin_orig_dir + func_extract_an_archive "$my_xdir" "$my_xabs" + fi # $darwin_arches + } # !$opt_dry_run + ;; + *) + func_extract_an_archive "$my_xdir" "$my_xabs" + ;; + esac + my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` + done + + func_extract_archives_result=$my_oldobjs +} + + +# func_emit_wrapper [arg=no] +# +# Emit a libtool wrapper script on stdout. +# Don't directly open a file because we may want to +# incorporate the script contents within a cygwin/mingw +# wrapper executable. Must ONLY be called from within +# func_mode_link because it depends on a number of variables +# set therein. +# +# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR +# variable will take. If 'yes', then the emitted script +# will assume that the directory where it is stored is +# the $objdir directory. This is a cygwin/mingw-specific +# behavior. +func_emit_wrapper () +{ + func_emit_wrapper_arg1=${1-no} + + $ECHO "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM (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 the build directory. +# 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. +sed_quote_subst='$sed_quote_subst' + +# Be Bourne compatible +if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variables: + generated_by_libtool_version='$macro_version' + notinst_deplibs='$notinst_deplibs' +else + # When we are sourced in execute mode, \$file and \$ECHO are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + file=\"\$0\"" + + qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` + $ECHO "\ + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + ECHO=\"$qECHO\" + fi + +# Very basic option parsing. These options are (a) specific to +# the libtool wrapper, (b) are identical between the wrapper +# /script/ and the wrapper /executable/ that is used only on +# windows platforms, and (c) all begin with the string "--lt-" +# (application programs are unlikely to have options that match +# this pattern). +# +# There are only two supported options: --lt-debug and +# --lt-dump-script. There is, deliberately, no --lt-help. +# +# The first argument to this parsing function should be the +# script's $0 value, followed by "$@". +lt_option_debug= +func_parse_lt_options () +{ + lt_script_arg0=\$0 + shift + for lt_opt + do + case \"\$lt_opt\" in + --lt-debug) lt_option_debug=1 ;; + --lt-dump-script) + lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` + test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. + lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` + cat \"\$lt_dump_D/\$lt_dump_F\" + exit 0 + ;; + --lt-*) + \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 + exit 1 + ;; + esac + done + + # Print the debug banner immediately: + if test -n \"\$lt_option_debug\"; then + echo \"$outputname:$output:\$LINENO: libtool wrapper (GNU $PACKAGE) $VERSION\" 1>&2 + fi +} + +# Used when --lt-debug. Prints its arguments to stdout +# (redirection is the responsibility of the caller) +func_lt_dump_args () +{ + lt_dump_args_N=1; + for lt_arg + do + \$ECHO \"$outputname:$output:\$LINENO: newargv[\$lt_dump_args_N]: \$lt_arg\" + lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` + done +} + +# Core function for launching the target application +func_exec_program_core () +{ +" + case $host in + # Backslashes separate directories on plain windows + *-*-mingw | *-*-os2* | *-cegcc*) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} +" + ;; + + *) + $ECHO "\ + if test -n \"\$lt_option_debug\"; then + \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir/\$program\" 1>&2 + func_lt_dump_args \${1+\"\$@\"} 1>&2 + fi + exec \"\$progdir/\$program\" \${1+\"\$@\"} +" + ;; + esac + $ECHO "\ + \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 + exit 1 +} + +# A function to encapsulate launching the target application +# Strips options in the --lt-* namespace from \$@ and +# launches target application with the remaining arguments. +func_exec_program () +{ + case \" \$* \" in + *\\ --lt-*) + for lt_wr_arg + do + case \$lt_wr_arg in + --lt-*) ;; + *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; + esac + shift + done ;; + esac + func_exec_program_core \${1+\"\$@\"} +} + + # Parse options + func_parse_lt_options \"\$0\" \${1+\"\$@\"} + + # Find the directory that this script lives in. + thisdir=\`\$ECHO \"\$file\" | $SED '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 \"\$file\" | $SED '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 \"\$file\" | $SED 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` + done + + # Usually 'no', except on cygwin/mingw when embedded into + # the cwrapper. + WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 + if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then + # special case for '.' + if test \"\$thisdir\" = \".\"; then + thisdir=\`pwd\` + fi + # remove .libs from thisdir + case \"\$thisdir\" in + *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; + $objdir ) thisdir=. ;; + esac + fi + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test yes = "$fast_install"; then + $ECHO "\ + program=lt-'$outputname'$exeext + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | $SED 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $MKDIR \"\$progdir\" + else + $RM \"\$progdir/\$file\" + fi" + + $ECHO "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if relink_command_output=\`eval \$relink_command 2>&1\`; then : + else + \$ECHO \"\$relink_command_output\" >&2 + $RM \"\$progdir/\$file\" + exit 1 + fi + fi + + $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $RM \"\$progdir/\$program\"; + $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $RM \"\$progdir/\$file\" + fi" + else + $ECHO "\ + program='$outputname' + progdir=\"\$thisdir/$objdir\" +" + fi + + $ECHO "\ + + if test -f \"\$progdir/\$program\"; then" + + # fixup the dll searchpath if we need to. + # + # Fix the DLL searchpath if we need to. Do this before prepending + # to shlibpath, because on Windows, both are PATH and uninstalled + # libraries must come first. + if test -n "$dllsearchpath"; then + $ECHO "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + # Export our shlibpath_var if we have one. + if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $ECHO "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` + + export $shlibpath_var +" + fi + + $ECHO "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. + func_exec_program \${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\ +" +} + + +# func_emit_cwrapperexe_src +# emit the source code for a wrapper executable on stdout +# Must ONLY be called from within func_mode_link because +# it depends on a number of variable set therein. +func_emit_cwrapperexe_src () +{ + cat <<EOF + +/* $cwrappersource - temporary wrapper executable for $objdir/$outputname + Generated by $PROGRAM (GNU $PACKAGE) $VERSION + + The $output program cannot be directly executed until all the libtool + libraries that it depends on are installed. + + This wrapper executable should never be moved out of the build directory. + If it is, it will not operate correctly. +*/ +EOF + cat <<"EOF" +#ifdef _MSC_VER +# define _CRT_SECURE_NO_DEPRECATE 1 +#endif +#include <stdio.h> +#include <stdlib.h> +#ifdef _MSC_VER +# include <direct.h> +# include <process.h> +# include <io.h> +#else +# include <unistd.h> +# include <stdint.h> +# ifdef __CYGWIN__ +# include <io.h> +# endif +#endif +#include <malloc.h> +#include <stdarg.h> +#include <assert.h> +#include <string.h> +#include <ctype.h> +#include <errno.h> +#include <fcntl.h> +#include <sys/stat.h> + +#define STREQ(s1, s2) (strcmp ((s1), (s2)) == 0) + +/* declarations of non-ANSI functions */ +#if defined __MINGW32__ +# ifdef __STRICT_ANSI__ +int _putenv (const char *); +# endif +#elif defined __CYGWIN__ +# ifdef __STRICT_ANSI__ +char *realpath (const char *, char *); +int putenv (char *); +int setenv (const char *, const char *, int); +# endif +/* #elif defined other_platform || defined ... */ +#endif + +/* portability defines, excluding path handling macros */ +#if defined _MSC_VER +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +# define S_IXUSR _S_IEXEC +#elif defined __MINGW32__ +# define setmode _setmode +# define stat _stat +# define chmod _chmod +# define getcwd _getcwd +# define putenv _putenv +#elif defined __CYGWIN__ +# define HAVE_SETENV +# define FOPEN_WB "wb" +/* #elif defined other platforms ... */ +#endif + +#if defined PATH_MAX +# define LT_PATHMAX PATH_MAX +#elif defined MAXPATHLEN +# define LT_PATHMAX MAXPATHLEN +#else +# define LT_PATHMAX 1024 +#endif + +#ifndef S_IXOTH +# define S_IXOTH 0 +#endif +#ifndef S_IXGRP +# define S_IXGRP 0 +#endif + +/* path handling portability macros */ +#ifndef DIR_SEPARATOR +# define DIR_SEPARATOR '/' +# define PATH_SEPARATOR ':' +#endif + +#if defined _WIN32 || defined __MSDOS__ || defined __DJGPP__ || \ + defined __OS2__ +# define HAVE_DOS_BASED_FILE_SYSTEM +# define FOPEN_WB "wb" +# ifndef DIR_SEPARATOR_2 +# define DIR_SEPARATOR_2 '\\' +# endif +# ifndef PATH_SEPARATOR_2 +# define PATH_SEPARATOR_2 ';' +# endif +#endif + +#ifndef DIR_SEPARATOR_2 +# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) +#else /* DIR_SEPARATOR_2 */ +# define IS_DIR_SEPARATOR(ch) \ + (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) +#endif /* DIR_SEPARATOR_2 */ + +#ifndef PATH_SEPARATOR_2 +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) +#else /* PATH_SEPARATOR_2 */ +# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) +#endif /* PATH_SEPARATOR_2 */ + +#ifndef FOPEN_WB +# define FOPEN_WB "w" +#endif +#ifndef _O_BINARY +# define _O_BINARY 0 +#endif + +#define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) +#define XFREE(stale) do { \ + if (stale) { free (stale); stale = 0; } \ +} while (0) + +#if defined LT_DEBUGWRAPPER +static int lt_debug = 1; +#else +static int lt_debug = 0; +#endif + +const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ + +void *xmalloc (size_t num); +char *xstrdup (const char *string); +const char *base_name (const char *name); +char *find_executable (const char *wrapper); +char *chase_symlinks (const char *pathspec); +int make_executable (const char *path); +int check_executable (const char *path); +char *strendzap (char *str, const char *pat); +void lt_debugprintf (const char *file, int line, const char *fmt, ...); +void lt_fatal (const char *file, int line, const char *message, ...); +static const char *nonnull (const char *s); +static const char *nonempty (const char *s); +void lt_setenv (const char *name, const char *value); +char *lt_extend_str (const char *orig_value, const char *add, int to_end); +void lt_update_exe_path (const char *name, const char *value); +void lt_update_lib_path (const char *name, const char *value); +char **prepare_spawn (char **argv); +void lt_dump_script (FILE *f); +EOF + + cat <<EOF +#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5) +# define externally_visible volatile +#else +# define externally_visible __attribute__((externally_visible)) volatile +#endif +externally_visible const char * MAGIC_EXE = "$magic_exe"; +const char * LIB_PATH_VARNAME = "$shlibpath_var"; +EOF + + if test yes = "$shlibpath_overrides_runpath" && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + func_to_host_path "$temp_rpath" + cat <<EOF +const char * LIB_PATH_VALUE = "$func_to_host_path_result"; +EOF + else + cat <<"EOF" +const char * LIB_PATH_VALUE = ""; +EOF + fi + + if test -n "$dllsearchpath"; then + func_to_host_path "$dllsearchpath:" + cat <<EOF +const char * EXE_PATH_VARNAME = "PATH"; +const char * EXE_PATH_VALUE = "$func_to_host_path_result"; +EOF + else + cat <<"EOF" +const char * EXE_PATH_VARNAME = ""; +const char * EXE_PATH_VALUE = ""; +EOF + fi + + if test yes = "$fast_install"; then + cat <<EOF +const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */ +EOF + else + cat <<EOF +const char * TARGET_PROGRAM_NAME = "$outputname"; /* hopefully, no .exe */ +EOF + fi + + + cat <<"EOF" + +#define LTWRAPPER_OPTION_PREFIX "--lt-" + +static const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX; +static const char *dumpscript_opt = LTWRAPPER_OPTION_PREFIX "dump-script"; +static const char *debug_opt = LTWRAPPER_OPTION_PREFIX "debug"; + +int +main (int argc, char *argv[]) +{ + char **newargz; + int newargc; + char *tmp_pathspec; + char *actual_cwrapper_path; + char *actual_cwrapper_name; + char *target_name; + char *lt_argv_zero; + int rval = 127; + + int i; + + program_name = (char *) xstrdup (base_name (argv[0])); + newargz = XMALLOC (char *, (size_t) argc + 1); + + /* very simple arg parsing; don't want to rely on getopt + * also, copy all non cwrapper options to newargz, except + * argz[0], which is handled differently + */ + newargc=0; + for (i = 1; i < argc; i++) + { + if (STREQ (argv[i], dumpscript_opt)) + { +EOF + case $host in + *mingw* | *cygwin* ) + # make stdout use "unix" line endings + echo " setmode(1,_O_BINARY);" + ;; + esac + + cat <<"EOF" + lt_dump_script (stdout); + return 0; + } + if (STREQ (argv[i], debug_opt)) + { + lt_debug = 1; + continue; + } + if (STREQ (argv[i], ltwrapper_option_prefix)) + { + /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX + namespace, but it is not one of the ones we know about and + have already dealt with, above (inluding dump-script), then + report an error. Otherwise, targets might begin to believe + they are allowed to use options in the LTWRAPPER_OPTION_PREFIX + namespace. The first time any user complains about this, we'll + need to make LTWRAPPER_OPTION_PREFIX a configure-time option + or a configure.ac-settable value. + */ + lt_fatal (__FILE__, __LINE__, + "unrecognized %s option: '%s'", + ltwrapper_option_prefix, argv[i]); + } + /* otherwise ... */ + newargz[++newargc] = xstrdup (argv[i]); + } + newargz[++newargc] = NULL; + +EOF + cat <<EOF + /* The GNU banner must be the first non-error debug message */ + lt_debugprintf (__FILE__, __LINE__, "libtool wrapper (GNU $PACKAGE) $VERSION\n"); +EOF + cat <<"EOF" + lt_debugprintf (__FILE__, __LINE__, "(main) argv[0]: %s\n", argv[0]); + lt_debugprintf (__FILE__, __LINE__, "(main) program_name: %s\n", program_name); + + tmp_pathspec = find_executable (argv[0]); + if (tmp_pathspec == NULL) + lt_fatal (__FILE__, __LINE__, "couldn't find %s", argv[0]); + lt_debugprintf (__FILE__, __LINE__, + "(main) found exe (before symlink chase) at: %s\n", + tmp_pathspec); + + actual_cwrapper_path = chase_symlinks (tmp_pathspec); + lt_debugprintf (__FILE__, __LINE__, + "(main) found exe (after symlink chase) at: %s\n", + actual_cwrapper_path); + XFREE (tmp_pathspec); + + actual_cwrapper_name = xstrdup (base_name (actual_cwrapper_path)); + strendzap (actual_cwrapper_path, actual_cwrapper_name); + + /* wrapper name transforms */ + strendzap (actual_cwrapper_name, ".exe"); + tmp_pathspec = lt_extend_str (actual_cwrapper_name, ".exe", 1); + XFREE (actual_cwrapper_name); + actual_cwrapper_name = tmp_pathspec; + tmp_pathspec = 0; + + /* target_name transforms -- use actual target program name; might have lt- prefix */ + target_name = xstrdup (base_name (TARGET_PROGRAM_NAME)); + strendzap (target_name, ".exe"); + tmp_pathspec = lt_extend_str (target_name, ".exe", 1); + XFREE (target_name); + target_name = tmp_pathspec; + tmp_pathspec = 0; + + lt_debugprintf (__FILE__, __LINE__, + "(main) libtool target name: %s\n", + target_name); +EOF + + cat <<EOF + newargz[0] = + XMALLOC (char, (strlen (actual_cwrapper_path) + + strlen ("$objdir") + 1 + strlen (actual_cwrapper_name) + 1)); + strcpy (newargz[0], actual_cwrapper_path); + strcat (newargz[0], "$objdir"); + strcat (newargz[0], "/"); +EOF + + cat <<"EOF" + /* stop here, and copy so we don't have to do this twice */ + tmp_pathspec = xstrdup (newargz[0]); + + /* do NOT want the lt- prefix here, so use actual_cwrapper_name */ + strcat (newargz[0], actual_cwrapper_name); + + /* DO want the lt- prefix here if it exists, so use target_name */ + lt_argv_zero = lt_extend_str (tmp_pathspec, target_name, 1); + XFREE (tmp_pathspec); + tmp_pathspec = NULL; +EOF + + case $host_os in + mingw*) + cat <<"EOF" + { + char* p; + while ((p = strchr (newargz[0], '\\')) != NULL) + { + *p = '/'; + } + while ((p = strchr (lt_argv_zero, '\\')) != NULL) + { + *p = '/'; + } + } +EOF + ;; + esac + + cat <<"EOF" + XFREE (target_name); + XFREE (actual_cwrapper_path); + XFREE (actual_cwrapper_name); + + lt_setenv ("BIN_SH", "xpg4"); /* for Tru64 */ + lt_setenv ("DUALCASE", "1"); /* for MSK sh */ + /* Update the DLL searchpath. EXE_PATH_VALUE ($dllsearchpath) must + be prepended before (that is, appear after) LIB_PATH_VALUE ($temp_rpath) + because on Windows, both *_VARNAMEs are PATH but uninstalled + libraries must come first. */ + lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE); + lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE); + + lt_debugprintf (__FILE__, __LINE__, "(main) lt_argv_zero: %s\n", + nonnull (lt_argv_zero)); + for (i = 0; i < newargc; i++) + { + lt_debugprintf (__FILE__, __LINE__, "(main) newargz[%d]: %s\n", + i, nonnull (newargz[i])); + } + +EOF + + case $host_os in + mingw*) + cat <<"EOF" + /* execv doesn't actually work on mingw as expected on unix */ + newargz = prepare_spawn (newargz); + rval = (int) _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz); + if (rval == -1) + { + /* failed to start process */ + lt_debugprintf (__FILE__, __LINE__, + "(main) failed to launch target \"%s\": %s\n", + lt_argv_zero, nonnull (strerror (errno))); + return 127; + } + return rval; +EOF + ;; + *) + cat <<"EOF" + execv (lt_argv_zero, newargz); + return rval; /* =127, but avoids unused variable warning */ +EOF + ;; + esac + + cat <<"EOF" +} + +void * +xmalloc (size_t num) +{ + void *p = (void *) malloc (num); + if (!p) + lt_fatal (__FILE__, __LINE__, "memory exhausted"); + + return p; +} + +char * +xstrdup (const char *string) +{ + return string ? strcpy ((char *) xmalloc (strlen (string) + 1), + string) : NULL; +} + +const char * +base_name (const char *name) +{ + const char *base; + +#if defined HAVE_DOS_BASED_FILE_SYSTEM + /* Skip over the disk name in MSDOS pathnames. */ + if (isalpha ((unsigned char) name[0]) && name[1] == ':') + name += 2; +#endif + + for (base = name; *name; name++) + if (IS_DIR_SEPARATOR (*name)) + base = name + 1; + return base; +} + +int +check_executable (const char *path) +{ + struct stat st; + + lt_debugprintf (__FILE__, __LINE__, "(check_executable): %s\n", + nonempty (path)); + if ((!path) || (!*path)) + return 0; + + if ((stat (path, &st) >= 0) + && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) + return 1; + else + return 0; +} + +int +make_executable (const char *path) +{ + int rval = 0; + struct stat st; + + lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", + nonempty (path)); + if ((!path) || (!*path)) + return 0; + + if (stat (path, &st) >= 0) + { + rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); + } + return rval; +} + +/* Searches for the full path of the wrapper. Returns + newly allocated full path name if found, NULL otherwise + Does not chase symlinks, even on platforms that support them. +*/ +char * +find_executable (const char *wrapper) +{ + int has_slash = 0; + const char *p; + const char *p_next; + /* static buffer for getcwd */ + char tmp[LT_PATHMAX + 1]; + size_t tmp_len; + char *concat_name; + + lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", + nonempty (wrapper)); + + if ((wrapper == NULL) || (*wrapper == '\0')) + return NULL; + + /* Absolute path? */ +#if defined HAVE_DOS_BASED_FILE_SYSTEM + if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + else + { +#endif + if (IS_DIR_SEPARATOR (wrapper[0])) + { + concat_name = xstrdup (wrapper); + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } +#if defined HAVE_DOS_BASED_FILE_SYSTEM + } +#endif + + for (p = wrapper; *p; p++) + if (*p == '/') + { + has_slash = 1; + break; + } + if (!has_slash) + { + /* no slashes; search PATH */ + const char *path = getenv ("PATH"); + if (path != NULL) + { + for (p = path; *p; p = p_next) + { + const char *q; + size_t p_len; + for (q = p; *q; q++) + if (IS_PATH_SEPARATOR (*q)) + break; + p_len = (size_t) (q - p); + p_next = (*q == '\0' ? q : q + 1); + if (p_len == 0) + { + /* empty path: current directory */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = + XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + } + else + { + concat_name = + XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, p, p_len); + concat_name[p_len] = '/'; + strcpy (concat_name + p_len + 1, wrapper); + } + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + } + } + /* not found in PATH; assume curdir */ + } + /* Relative path | not found in path: prepend cwd */ + if (getcwd (tmp, LT_PATHMAX) == NULL) + lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", + nonnull (strerror (errno))); + tmp_len = strlen (tmp); + concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); + memcpy (concat_name, tmp, tmp_len); + concat_name[tmp_len] = '/'; + strcpy (concat_name + tmp_len + 1, wrapper); + + if (check_executable (concat_name)) + return concat_name; + XFREE (concat_name); + return NULL; +} + +char * +chase_symlinks (const char *pathspec) +{ +#ifndef S_ISLNK + return xstrdup (pathspec); +#else + char buf[LT_PATHMAX]; + struct stat s; + char *tmp_pathspec = xstrdup (pathspec); + char *p; + int has_symlinks = 0; + while (strlen (tmp_pathspec) && !has_symlinks) + { + lt_debugprintf (__FILE__, __LINE__, + "checking path component for symlinks: %s\n", + tmp_pathspec); + if (lstat (tmp_pathspec, &s) == 0) + { + if (S_ISLNK (s.st_mode) != 0) + { + has_symlinks = 1; + break; + } + + /* search backwards for last DIR_SEPARATOR */ + p = tmp_pathspec + strlen (tmp_pathspec) - 1; + while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + p--; + if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) + { + /* no more DIR_SEPARATORS left */ + break; + } + *p = '\0'; + } + else + { + lt_fatal (__FILE__, __LINE__, + "error accessing file \"%s\": %s", + tmp_pathspec, nonnull (strerror (errno))); + } + } + XFREE (tmp_pathspec); + + if (!has_symlinks) + { + return xstrdup (pathspec); + } + + tmp_pathspec = realpath (pathspec, buf); + if (tmp_pathspec == 0) + { + lt_fatal (__FILE__, __LINE__, + "could not follow symlinks for %s", pathspec); + } + return xstrdup (tmp_pathspec); +#endif +} + +char * +strendzap (char *str, const char *pat) +{ + size_t len, patlen; + + assert (str != NULL); + assert (pat != NULL); + + len = strlen (str); + patlen = strlen (pat); + + if (patlen <= len) + { + str += len - patlen; + if (STREQ (str, pat)) + *str = '\0'; + } + return str; +} + +void +lt_debugprintf (const char *file, int line, const char *fmt, ...) +{ + va_list args; + if (lt_debug) + { + (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); + va_start (args, fmt); + (void) vfprintf (stderr, fmt, args); + va_end (args); + } +} + +static void +lt_error_core (int exit_status, const char *file, + int line, const char *mode, + const char *message, va_list ap) +{ + fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); + vfprintf (stderr, message, ap); + fprintf (stderr, ".\n"); + + if (exit_status >= 0) + exit (exit_status); +} + +void +lt_fatal (const char *file, int line, const char *message, ...) +{ + va_list ap; + va_start (ap, message); + lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); + va_end (ap); +} + +static const char * +nonnull (const char *s) +{ + return s ? s : "(null)"; +} + +static const char * +nonempty (const char *s) +{ + return (s && !*s) ? "(empty)" : nonnull (s); +} + +void +lt_setenv (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_setenv) setting '%s' to '%s'\n", + nonnull (name), nonnull (value)); + { +#ifdef HAVE_SETENV + /* always make a copy, for consistency with !HAVE_SETENV */ + char *str = xstrdup (value); + setenv (name, str, 1); +#else + size_t len = strlen (name) + 1 + strlen (value) + 1; + char *str = XMALLOC (char, len); + sprintf (str, "%s=%s", name, value); + if (putenv (str) != EXIT_SUCCESS) + { + XFREE (str); + } +#endif + } +} + +char * +lt_extend_str (const char *orig_value, const char *add, int to_end) +{ + char *new_value; + if (orig_value && *orig_value) + { + size_t orig_value_len = strlen (orig_value); + size_t add_len = strlen (add); + new_value = XMALLOC (char, add_len + orig_value_len + 1); + if (to_end) + { + strcpy (new_value, orig_value); + strcpy (new_value + orig_value_len, add); + } + else + { + strcpy (new_value, add); + strcpy (new_value + add_len, orig_value); + } + } + else + { + new_value = xstrdup (add); + } + return new_value; +} + +void +lt_update_exe_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + /* some systems can't cope with a ':'-terminated path #' */ + size_t len = strlen (new_value); + while ((len > 0) && IS_PATH_SEPARATOR (new_value[len-1])) + { + new_value[--len] = '\0'; + } + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +void +lt_update_lib_path (const char *name, const char *value) +{ + lt_debugprintf (__FILE__, __LINE__, + "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", + nonnull (name), nonnull (value)); + + if (name && *name && value && *value) + { + char *new_value = lt_extend_str (getenv (name), value, 0); + lt_setenv (name, new_value); + XFREE (new_value); + } +} + +EOF + case $host_os in + mingw*) + cat <<"EOF" + +/* Prepares an argument vector before calling spawn(). + Note that spawn() does not by itself call the command interpreter + (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : + ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&v); + v.dwPlatformId == VER_PLATFORM_WIN32_NT; + }) ? "cmd.exe" : "command.com"). + Instead it simply concatenates the arguments, separated by ' ', and calls + CreateProcess(). We must quote the arguments since Win32 CreateProcess() + interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a + special way: + - Space and tab are interpreted as delimiters. They are not treated as + delimiters if they are surrounded by double quotes: "...". + - Unescaped double quotes are removed from the input. Their only effect is + that within double quotes, space and tab are treated like normal + characters. + - Backslashes not followed by double quotes are not special. + - But 2*n+1 backslashes followed by a double quote become + n backslashes followed by a double quote (n >= 0): + \" -> " + \\\" -> \" + \\\\\" -> \\" + */ +#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" +char ** +prepare_spawn (char **argv) +{ + size_t argc; + char **new_argv; + size_t i; + + /* Count number of arguments. */ + for (argc = 0; argv[argc] != NULL; argc++) + ; + + /* Allocate new argument vector. */ + new_argv = XMALLOC (char *, argc + 1); + + /* Put quoted arguments into the new argument vector. */ + for (i = 0; i < argc; i++) + { + const char *string = argv[i]; + + if (string[0] == '\0') + new_argv[i] = xstrdup ("\"\""); + else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) + { + int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); + size_t length; + unsigned int backslashes; + const char *s; + char *quoted_string; + char *p; + + length = 0; + backslashes = 0; + if (quote_around) + length++; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + length += backslashes + 1; + length++; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + length += backslashes + 1; + + quoted_string = XMALLOC (char, length + 1); + + p = quoted_string; + backslashes = 0; + if (quote_around) + *p++ = '"'; + for (s = string; *s != '\0'; s++) + { + char c = *s; + if (c == '"') + { + unsigned int j; + for (j = backslashes + 1; j > 0; j--) + *p++ = '\\'; + } + *p++ = c; + if (c == '\\') + backslashes++; + else + backslashes = 0; + } + if (quote_around) + { + unsigned int j; + for (j = backslashes; j > 0; j--) + *p++ = '\\'; + *p++ = '"'; + } + *p = '\0'; + + new_argv[i] = quoted_string; + } + else + new_argv[i] = (char *) string; + } + new_argv[argc] = NULL; + + return new_argv; +} +EOF + ;; + esac + + cat <<"EOF" +void lt_dump_script (FILE* f) +{ +EOF + func_emit_wrapper yes | + $SED -n -e ' +s/^\(.\{79\}\)\(..*\)/\1\ +\2/ +h +s/\([\\"]\)/\\\1/g +s/$/\\n/ +s/\([^\n]*\).*/ fputs ("\1", f);/p +g +D' + cat <<"EOF" +} +EOF +} +# end: func_emit_cwrapperexe_src + +# func_win32_import_lib_p ARG +# True if ARG is an import lib, as indicated by $file_magic_cmd +func_win32_import_lib_p () +{ + $debug_cmd + + case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in + *import*) : ;; + *) false ;; + esac +} + +# func_suncc_cstd_abi +# !!ONLY CALL THIS FOR SUN CC AFTER $compile_command IS FULLY EXPANDED!! +# Several compiler flags select an ABI that is incompatible with the +# Cstd library. Avoid specifying it if any are in CXXFLAGS. +func_suncc_cstd_abi () +{ + $debug_cmd + + case " $compile_command " in + *" -compat=g "*|*\ -std=c++[0-9][0-9]\ *|*" -library=stdcxx4 "*|*" -library=stlport4 "*) + suncc_use_cstd_abi=no + ;; + *) + suncc_use_cstd_abi=yes + ;; + esac +} + +# func_mode_link arg... +func_mode_link () +{ + $debug_cmd + + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + # It is impossible to link a dll without this setting, and + # we shouldn't force the makefile maintainer to figure out + # what system we are compiling for in order to pass an extra + # flag for every libtool invocation. + # allow_undefined=no + + # FIXME: Unfortunately, there are problems with the above when trying + # to make a dll that has undefined symbols, in which case not + # even a static library is built. For now, we need to specify + # -no-undefined on the libtool link line when we can be certain + # that all symbols are satisfied, otherwise we get a static library. + allow_undefined=yes + ;; + *) + allow_undefined=yes + ;; + esac + libtool_args=$nonopt + base_compile="$nonopt $@" + compile_command=$nonopt + finalize_command=$nonopt + + compile_rpath= + finalize_rpath= + compile_shlibpath= + finalize_shlibpath= + convenience= + old_convenience= + deplibs= + old_deplibs= + compiler_flags= + linker_flags= + dllsearchpath= + lib_search_path=`pwd` + inst_prefix_dir= + new_inherited_linker_flags= + + avoid_version=no + bindir= + dlfiles= + dlprefiles= + dlself=no + export_dynamic=no + export_symbols= + export_symbols_regex= + generated= + libobjs= + ltlibs= + module=no + no_install=no + objs= + os2dllname= + non_pic_objects= + precious_files_regex= + prefer_static_libs=no + preload=false + prev= + prevarg= + release= + rpath= + xrpath= + perm_rpath= + temp_rpath= + thread_safe=no + vinfo= + vinfo_number=no + weak_libs= + single_module=$wl-single_module + func_infer_tag $base_compile + + # We need to know -static, to get the right output filenames. + for arg + do + case $arg in + -shared) + test yes != "$build_libtool_libs" \ + && func_fatal_configuration "cannot build a shared library" + build_old_libs=no + break + ;; + -all-static | -static | -static-libtool-libs) + case $arg in + -all-static) + if test yes = "$build_libtool_libs" && test -z "$link_static_flag"; then + func_warning "complete static linking is impossible in this configuration" + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + -static) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=built + ;; + -static-libtool-libs) + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + prefer_static_libs=yes + ;; + esac + 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. + while test "$#" -gt 0; do + arg=$1 + shift + func_quote_for_eval "$arg" + qarg=$func_quote_for_eval_unquoted_result + func_append libtool_args " $func_quote_for_eval_result" + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case $prev in + output) + func_append compile_command " @OUTPUT@" + func_append finalize_command " @OUTPUT@" + ;; + esac + + case $prev in + bindir) + bindir=$arg + prev= + continue + ;; + dlfiles|dlprefiles) + $preload || { + # Add the symbol object into the linking commands. + func_append compile_command " @SYMFILE@" + func_append finalize_command " @SYMFILE@" + preload=: + } + case $arg in + *.la | *.lo) ;; # We handle these cases below. + force) + if test no = "$dlself"; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test dlprefiles = "$prev"; then + dlself=yes + elif test dlfiles = "$prev" && test yes != "$dlopen_self"; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test dlfiles = "$prev"; then + func_append dlfiles " $arg" + else + func_append dlprefiles " $arg" + fi + prev= + continue + ;; + esac + ;; + expsyms) + export_symbols=$arg + test -f "$arg" \ + || func_fatal_error "symbol file '$arg' does not exist" + prev= + continue + ;; + expsyms_regex) + export_symbols_regex=$arg + prev= + continue + ;; + framework) + case $host in + *-*-darwin*) + case "$deplibs " in + *" $qarg.ltframework "*) ;; + *) func_append deplibs " $qarg.ltframework" # this is fixed later + ;; + esac + ;; + esac + prev= + continue + ;; + inst_prefix) + inst_prefix_dir=$arg + prev= + continue + ;; + mllvm) + # Clang does not use LLVM to link, so we can simply discard any + # '-mllvm $arg' options when doing the link step. + prev= + continue + ;; + objectlist) + if test -f "$arg"; then + save_arg=$arg + moreargs= + for fil in `cat "$save_arg"` + do +# func_append moreargs " $fil" + arg=$fil + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test none = "$pic_object" && + test none = "$non_pic_object"; then + func_fatal_error "cannot find name of object for '$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir=$func_dirname_result + + if test none != "$pic_object"; then + # Prepend the subdirectory the object is found in. + pic_object=$xdir$pic_object + + if test dlfiles = "$prev"; then + if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test dlprefiles = "$prev"; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg=$pic_object + fi + + # Non-PIC object. + if test none != "$non_pic_object"; then + # Prepend the subdirectory the object is found in. + non_pic_object=$xdir$non_pic_object + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test none = "$pic_object"; then + arg=$non_pic_object + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object=$pic_object + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir=$func_dirname_result + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "'$arg' is not a valid libtool object" + fi + fi + done + else + func_fatal_error "link input file '$arg' does not exist" + fi + arg=$save_arg + prev= + continue + ;; + os2dllname) + os2dllname=$arg + prev= + continue + ;; + precious_regex) + precious_files_regex=$arg + prev= + continue + ;; + release) + release=-$arg + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case $arg in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + if test rpath = "$prev"; then + case "$rpath " in + *" $arg "*) ;; + *) func_append rpath " $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) func_append xrpath " $arg" ;; + esac + fi + prev= + continue + ;; + shrext) + shrext_cmds=$arg + prev= + continue + ;; + weak) + func_append weak_libs " $arg" + prev= + continue + ;; + xcclinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xcompiler) + func_append compiler_flags " $qarg" + prev= + func_append compile_command " $qarg" + func_append finalize_command " $qarg" + continue + ;; + xlinker) + func_append linker_flags " $qarg" + func_append compiler_flags " $wl$qarg" + prev= + func_append compile_command " $wl$qarg" + func_append finalize_command " $wl$qarg" + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi # test -n "$prev" + + prevarg=$arg + + case $arg in + -all-static) + if test -n "$link_static_flag"; then + # See comment for -static flag below, for more details. + func_append compile_command " $link_static_flag" + func_append finalize_command " $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + func_fatal_error "'-allow-undefined' must not be used because it is the default" + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -bindir) + prev=bindir + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + func_fatal_error "more than one -exported-symbols argument is not allowed" + fi + if test X-export-symbols = "X$arg"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -framework) + prev=framework + continue + ;; + + -inst-prefix-dir) + prev=inst_prefix + continue + ;; + + # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* + # so, if we see these flags be careful not to treat them like -L + -L[A-Z][A-Z]*:*) + case $with_gcc/$host in + no/*-*-irix* | /*-*-irix*) + func_append compile_command " $arg" + func_append finalize_command " $arg" + ;; + esac + continue + ;; + + -L*) + func_stripname "-L" '' "$arg" + if test -z "$func_stripname_result"; then + if test "$#" -gt 0; then + func_fatal_error "require no space between '-L' and '$1'" + else + func_fatal_error "need path for '-L' option" + fi + fi + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + test -z "$absdir" && \ + func_fatal_error "cannot determine absolute directory name of '$dir'" + dir=$absdir + ;; + esac + case "$deplibs " in + *" -L$dir "* | *" $arg "*) + # Will only happen for absolute or sysroot arguments + ;; + *) + # Preserve sysroot, but never include relative directories + case $dir in + [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; + *) func_append deplibs " -L$dir" ;; + esac + func_append lib_search_path " $dir" + ;; + esac + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$dir:"*) ;; + ::) dllsearchpath=$dir;; + *) func_append dllsearchpath ":$dir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + continue + ;; + + -l*) + if test X-lc = "X$arg" || test X-lm = "X$arg"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) + # These systems don't actually have a C or math library (as such) + continue + ;; + *-*-os2*) + # These systems don't actually have a C library (as such) + test X-lc = "X$arg" && continue + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) + # Do not include libc due to us having libc/libc_r. + test X-lc = "X$arg" && continue + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C and math libraries are in the System framework + func_append deplibs " System.ltframework" + continue + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + test X-lc = "X$arg" && continue + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + test X-lc = "X$arg" && continue + ;; + esac + elif test X-lc_r = "X$arg"; then + case $host in + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) + # Do not include libc_r directly, use -pthread flag. + continue + ;; + esac + fi + func_append deplibs " $arg" + continue + ;; + + -mllvm) + prev=mllvm + continue + ;; + + -module) + module=yes + continue + ;; + + # Tru64 UNIX uses -model [arg] to determine the layout of C++ + # classes, name mangling, and exception handling. + # Darwin uses the -arch flag to determine output architecture. + -model|-arch|-isysroot|--sysroot) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + prev=xcompiler + continue + ;; + + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) + func_append compiler_flags " $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + case "$new_inherited_linker_flags " in + *" $arg "*) ;; + * ) func_append new_inherited_linker_flags " $arg" ;; + esac + continue + ;; + + -multi_module) + single_module=$wl-multi_module + continue + ;; + + -no-fast-install) + fast_install=no + continue + ;; + + -no-install) + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) + # The PATH hackery in wrapper scripts is required on Windows + # and Darwin in order for the loader to find any dlls it needs. + func_warning "'-no-install' is ignored for $host" + func_warning "assuming '-no-fast-install' instead" + fast_install=no + ;; + *) no_install=yes ;; + esac + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -objectlist) + prev=objectlist + continue + ;; + + -os2dllname) + prev=os2dllname + continue + ;; + + -o) prev=output ;; + + -precious-files-regex) + prev=precious_regex + continue + ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + func_stripname '-R' '' "$arg" + dir=$func_stripname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) ;; + =*) + func_stripname '=' '' "$dir" + dir=$lt_sysroot$func_stripname_result + ;; + *) + func_fatal_error "only absolute run-paths are allowed" + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + continue + ;; + + -shared) + # The effects of -shared are defined in a previous loop. + continue + ;; + + -shrext) + prev=shrext + continue + ;; + + -static | -static-libtool-libs) + # The effects of -static are defined in a previous loop. + # We used to do the same as -all-static on platforms that + # didn't have a PIC flag, but the assumption that the effects + # would be equivalent was wrong. It would break on at least + # Digital Unix and AIX. + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + + -version-number) + prev=vinfo + vinfo_number=yes + continue + ;; + + -weak) + prev=weak + continue + ;; + + -Wc,*) + func_stripname '-Wc,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs=$IFS; IFS=, + for flag in $args; do + IFS=$save_ifs + func_quote_for_eval "$flag" + func_append arg " $func_quote_for_eval_result" + func_append compiler_flags " $func_quote_for_eval_result" + done + IFS=$save_ifs + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Wl,*) + func_stripname '-Wl,' '' "$arg" + args=$func_stripname_result + arg= + save_ifs=$IFS; IFS=, + for flag in $args; do + IFS=$save_ifs + func_quote_for_eval "$flag" + func_append arg " $wl$func_quote_for_eval_result" + func_append compiler_flags " $wl$func_quote_for_eval_result" + func_append linker_flags " $func_quote_for_eval_result" + done + IFS=$save_ifs + func_stripname ' ' '' "$arg" + arg=$func_stripname_result + ;; + + -Xcompiler) + prev=xcompiler + continue + ;; + + -Xlinker) + prev=xlinker + continue + ;; + + -XCClinker) + prev=xcclinker + continue + ;; + + # -msg_* for osf cc + -msg_*) + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + ;; + + # Flags to be passed through unchanged, with rationale: + # -64, -mips[0-9] enable 64-bit mode for the SGI compiler + # -r[0-9][0-9]* specify processor for the SGI compiler + # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler + # +DA*, +DD* enable 64-bit mode for the HP compiler + # -q* compiler args for the IBM compiler + # -m*, -t[45]*, -txscale* architecture-specific flags for GCC + # -F/path path to uninstalled frameworks, gcc on darwin + # -p, -pg, --coverage, -fprofile-* profiling flags for GCC + # -fstack-protector* stack protector flags for GCC + # @file GCC response files + # -tp=* Portland pgcc target processor selection + # --sysroot=* for sysroot support + # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization + # -stdlib=* select c++ std lib with clang + -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ + -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ + -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*) + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + func_append compile_command " $arg" + func_append finalize_command " $arg" + func_append compiler_flags " $arg" + continue + ;; + + -Z*) + if test os2 = "`expr $host : '.*\(os2\)'`"; then + # OS/2 uses -Zxxx to specify OS/2-specific options + compiler_flags="$compiler_flags $arg" + func_append compile_command " $arg" + func_append finalize_command " $arg" + case $arg in + -Zlinker | -Zstack) + prev=xcompiler + ;; + esac + continue + else + # Otherwise treat like 'Some other compiler flag' below + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + fi + ;; + + # Some other compiler flag. + -* | +*) + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + ;; + + *.$objext) + # A standard object. + func_append objs " $arg" + ;; + + *.lo) + # A libtool-controlled object. + + # Check to see that this really is a libtool object. + if func_lalib_unsafe_p "$arg"; then + pic_object= + non_pic_object= + + # Read the .lo file + func_source "$arg" + + if test -z "$pic_object" || + test -z "$non_pic_object" || + test none = "$pic_object" && + test none = "$non_pic_object"; then + func_fatal_error "cannot find name of object for '$arg'" + fi + + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir=$func_dirname_result + + test none = "$pic_object" || { + # Prepend the subdirectory the object is found in. + pic_object=$xdir$pic_object + + if test dlfiles = "$prev"; then + if test yes = "$build_libtool_libs" && test yes = "$dlopen_support"; then + func_append dlfiles " $pic_object" + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + # CHECK ME: I think I busted this. -Ossama + if test dlprefiles = "$prev"; then + # Preload the old-style object. + func_append dlprefiles " $pic_object" + prev= + fi + + # A PIC object. + func_append libobjs " $pic_object" + arg=$pic_object + } + + # Non-PIC object. + if test none != "$non_pic_object"; then + # Prepend the subdirectory the object is found in. + non_pic_object=$xdir$non_pic_object + + # A standard non-PIC object + func_append non_pic_objects " $non_pic_object" + if test -z "$pic_object" || test none = "$pic_object"; then + arg=$non_pic_object + fi + else + # If the PIC object exists, use it instead. + # $xdir was prepended to $pic_object above. + non_pic_object=$pic_object + func_append non_pic_objects " $non_pic_object" + fi + else + # Only an error if not doing a dry-run. + if $opt_dry_run; then + # Extract subdirectory from the argument. + func_dirname "$arg" "/" "" + xdir=$func_dirname_result + + func_lo2o "$arg" + pic_object=$xdir$objdir/$func_lo2o_result + non_pic_object=$xdir$func_lo2o_result + func_append libobjs " $pic_object" + func_append non_pic_objects " $non_pic_object" + else + func_fatal_error "'$arg' is not a valid libtool object" + fi + fi + ;; + + *.$libext) + # An archive. + func_append deplibs " $arg" + func_append old_deplibs " $arg" + continue + ;; + + *.la) + # A libtool-controlled library. + + func_resolve_sysroot "$arg" + if test dlfiles = "$prev"; then + # This library was specified with -dlopen. + func_append dlfiles " $func_resolve_sysroot_result" + prev= + elif test dlprefiles = "$prev"; then + # The library was specified with -dlpreopen. + func_append dlprefiles " $func_resolve_sysroot_result" + prev= + else + func_append deplibs " $func_resolve_sysroot_result" + fi + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + func_quote_for_eval "$arg" + arg=$func_quote_for_eval_result + ;; + esac # arg + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + done # argument parsing loop + + test -n "$prev" && \ + func_fatal_help "the '$prevarg' option requires an argument" + + if test yes = "$export_dynamic" && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + func_append compile_command " $arg" + func_append finalize_command " $arg" + fi + + oldlibs= + # calculate the name of the file, without its directory + func_basename "$output" + outputname=$func_basename_result + libobjs_save=$libobjs + + if test -n "$shlibpath_var"; then + # get the directories listed in $shlibpath_var + eval shlib_search_path=\`\$ECHO \"\$$shlibpath_var\" \| \$SED \'s/:/ /g\'\` + else + shlib_search_path= + fi + eval sys_lib_search_path=\"$sys_lib_search_path_spec\" + eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" + + # Definition is injected by LT_CONFIG during libtool generation. + func_munge_path_list sys_lib_dlsearch_path "$LT_SYS_LIBRARY_PATH" + + func_dirname "$output" "/" "" + output_objdir=$func_dirname_result$objdir + func_to_tool_file "$output_objdir/" + tool_output_objdir=$func_to_tool_file_result + # Create the object directory. + func_mkdir_p "$output_objdir" + + # Determine the type of output + case $output in + "") + func_fatal_help "you must specify an output file" + ;; + *.$libext) linkmode=oldlib ;; + *.lo | *.$objext) linkmode=obj ;; + *.la) linkmode=lib ;; + *) linkmode=prog ;; # Anything else should be a program. + esac + + specialdeplibs= + + libs= + # Find all interdependent deplibs by searching for libraries + # that are linked more than once (e.g. -la -lb -la) + for deplib in $deplibs; do + if $opt_preserve_dup_deps; then + case "$libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append libs " $deplib" + done + + if test lib = "$linkmode"; then + libs="$predeps $libs $compiler_lib_search_path $postdeps" + + # Compute libraries that are listed more than once in $predeps + # $postdeps and mark them as special (i.e., whose duplicates are + # not to be eliminated). + pre_post_deps= + if $opt_duplicate_compiler_generated_deps; then + for pre_post_dep in $predeps $postdeps; do + case "$pre_post_deps " in + *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; + esac + func_append pre_post_deps " $pre_post_dep" + done + fi + pre_post_deps= + fi + + deplibs= + newdependency_libs= + newlib_search_path= + need_relink=no # whether we're linking any uninstalled libtool libraries + notinst_deplibs= # not-installed libtool libraries + notinst_path= # paths that contain not-installed libtool libraries + + case $linkmode in + lib) + passes="conv dlpreopen link" + for file in $dlfiles $dlprefiles; do + case $file in + *.la) ;; + *) + func_fatal_help "libraries can '-dlopen' only libtool libraries: $file" + ;; + esac + done + ;; + prog) + compile_deplibs= + finalize_deplibs= + alldeplibs=false + newdlfiles= + newdlprefiles= + passes="conv scan dlopen dlpreopen link" + ;; + *) passes="conv" + ;; + esac + + for pass in $passes; do + # The preopen pass in lib mode reverses $deplibs; put it back here + # so that -L comes before libs that need it for instance... + if test lib,link = "$linkmode,$pass"; then + ## FIXME: Find the place where the list is rebuilt in the wrong + ## order, and fix it there properly + tmp_deplibs= + for deplib in $deplibs; do + tmp_deplibs="$deplib $tmp_deplibs" + done + deplibs=$tmp_deplibs + fi + + if test lib,link = "$linkmode,$pass" || + test prog,scan = "$linkmode,$pass"; then + libs=$deplibs + deplibs= + fi + if test prog = "$linkmode"; then + case $pass in + dlopen) libs=$dlfiles ;; + dlpreopen) libs=$dlprefiles ;; + link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; + esac + fi + if test lib,dlpreopen = "$linkmode,$pass"; then + # Collect and forward deplibs of preopened libtool libs + for lib in $dlprefiles; do + # Ignore non-libtool-libs + dependency_libs= + func_resolve_sysroot "$lib" + case $lib in + *.la) func_source "$func_resolve_sysroot_result" ;; + esac + + # Collect preopened libtool deplibs, except any this library + # has declared as weak libs + for deplib in $dependency_libs; do + func_basename "$deplib" + deplib_base=$func_basename_result + case " $weak_libs " in + *" $deplib_base "*) ;; + *) func_append deplibs " $deplib" ;; + esac + done + done + libs=$dlprefiles + fi + if test dlopen = "$pass"; then + # Collect dlpreopened libraries + save_deplibs=$deplibs + deplibs= + fi + + for deplib in $libs; do + lib= + found=false + case $deplib in + -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ + |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append compiler_flags " $deplib" + if test lib = "$linkmode"; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -l*) + if test lib != "$linkmode" && test prog != "$linkmode"; then + func_warning "'-l' is ignored for archives/objects" + continue + fi + func_stripname '-l' '' "$deplib" + name=$func_stripname_result + if test lib = "$linkmode"; then + searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" + else + searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" + fi + for searchdir in $searchdirs; do + for search_ext in .la $std_shrext .so .a; do + # Search the libtool library + lib=$searchdir/lib$name$search_ext + if test -f "$lib"; then + if test .la = "$search_ext"; then + found=: + else + found=false + fi + break 2 + fi + done + done + if $found; then + # deplib is a libtool library + # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, + # We need to do some special things here, and not later. + if test yes = "$allow_libtool_libs_with_static_runtimes"; then + case " $predeps $postdeps " in + *" $deplib "*) + if func_lalib_p "$lib"; then + library_names= + old_library= + func_source "$lib" + for l in $old_library $library_names; do + ll=$l + done + if test "X$ll" = "X$old_library"; then # only static version available + found=false + func_dirname "$lib" "" "." + ladir=$func_dirname_result + lib=$ladir/$old_library + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + fi + ;; + *) ;; + esac + fi + else + # deplib doesn't seem to be a libtool library + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + test lib = "$linkmode" && newdependency_libs="$deplib $newdependency_libs" + fi + continue + fi + ;; # -l + *.ltframework) + if test prog,link = "$linkmode,$pass"; then + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + deplibs="$deplib $deplibs" + if test lib = "$linkmode"; then + case "$new_inherited_linker_flags " in + *" $deplib "*) ;; + * ) func_append new_inherited_linker_flags " $deplib" ;; + esac + fi + fi + continue + ;; + -L*) + case $linkmode in + lib) + deplibs="$deplib $deplibs" + test conv = "$pass" && continue + newdependency_libs="$deplib $newdependency_libs" + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + prog) + if test conv = "$pass"; then + deplibs="$deplib $deplibs" + continue + fi + if test scan = "$pass"; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + *) + func_warning "'-L' is ignored for archives/objects" + ;; + esac # linkmode + continue + ;; # -L + -R*) + if test link = "$pass"; then + func_stripname '-R' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + dir=$func_resolve_sysroot_result + # Make sure the xrpath contains only unique directories. + case "$xrpath " in + *" $dir "*) ;; + *) func_append xrpath " $dir" ;; + esac + fi + deplibs="$deplib $deplibs" + continue + ;; + *.la) + func_resolve_sysroot "$deplib" + lib=$func_resolve_sysroot_result + ;; + *.$libext) + if test conv = "$pass"; then + deplibs="$deplib $deplibs" + continue + fi + case $linkmode in + lib) + # Linking convenience modules into shared libraries is allowed, + # but linking other static libraries is non-portable. + case " $dlpreconveniencelibs " in + *" $deplib "*) ;; + *) + valid_a_lib=false + case $deplibs_check_method in + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ + | $EGREP "$match_pattern_regex" > /dev/null; then + valid_a_lib=: + fi + ;; + pass_all) + valid_a_lib=: + ;; + esac + if $valid_a_lib; then + echo + $ECHO "*** Warning: Linking the shared library $output against the" + $ECHO "*** static library $deplib is not portable!" + deplibs="$deplib $deplibs" + else + echo + $ECHO "*** Warning: Trying to link with static lib archive $deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because the file extensions .$libext of this argument makes me believe" + echo "*** that it is just a static archive that I should not use here." + fi + ;; + esac + continue + ;; + prog) + if test link != "$pass"; then + deplibs="$deplib $deplibs" + else + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + fi + continue + ;; + esac # linkmode + ;; # *.$libext + *.lo | *.$objext) + if test conv = "$pass"; then + deplibs="$deplib $deplibs" + elif test prog = "$linkmode"; then + if test dlpreopen = "$pass" || test yes != "$dlopen_support" || test no = "$build_libtool_libs"; then + # If there is no dlopen support or we're linking statically, + # we need to preload. + func_append newdlprefiles " $deplib" + compile_deplibs="$deplib $compile_deplibs" + finalize_deplibs="$deplib $finalize_deplibs" + else + func_append newdlfiles " $deplib" + fi + fi + continue + ;; + %DEPLIBS%) + alldeplibs=: + continue + ;; + esac # case $deplib + + $found || test -f "$lib" \ + || func_fatal_error "cannot find the library '$lib' or unhandled argument '$deplib'" + + # Check to see that this really is a libtool archive. + func_lalib_unsafe_p "$lib" \ + || func_fatal_error "'$lib' is not a valid libtool archive" + + func_dirname "$lib" "" "." + ladir=$func_dirname_result + + dlname= + dlopen= + dlpreopen= + libdir= + library_names= + old_library= + inherited_linker_flags= + # If the library was installed with an old release of libtool, + # it will not redefine variables installed, or shouldnotlink + installed=yes + shouldnotlink=no + avoidtemprpath= + + + # Read the .la file + func_source "$lib" + + # Convert "-framework foo" to "foo.ltframework" + if test -n "$inherited_linker_flags"; then + tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` + for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do + case " $new_inherited_linker_flags " in + *" $tmp_inherited_linker_flag "*) ;; + *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; + esac + done + fi + dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + if test lib,link = "$linkmode,$pass" || + test prog,scan = "$linkmode,$pass" || + { test prog != "$linkmode" && test lib != "$linkmode"; }; then + test -n "$dlopen" && func_append dlfiles " $dlopen" + test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" + fi + + if test conv = "$pass"; then + # Only check for convenience libraries + deplibs="$lib $deplibs" + if test -z "$libdir"; then + if test -z "$old_library"; then + func_fatal_error "cannot find name of link library for '$lib'" + fi + # It is a libtool convenience library, so add in its objects. + func_append convenience " $ladir/$objdir/$old_library" + func_append old_convenience " $ladir/$objdir/$old_library" + elif test prog != "$linkmode" && test lib != "$linkmode"; then + func_fatal_error "'$lib' is not a convenience library" + fi + tmp_libs= + for deplib in $dependency_libs; do + deplibs="$deplib $deplibs" + if $opt_preserve_dup_deps; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done + continue + fi # $pass = conv + + + # Get the name of the library we link against. + linklib= + if test -n "$old_library" && + { test yes = "$prefer_static_libs" || + test built,no = "$prefer_static_libs,$installed"; }; then + linklib=$old_library + else + for l in $old_library $library_names; do + linklib=$l + done + fi + if test -z "$linklib"; then + func_fatal_error "cannot find name of link library for '$lib'" + fi + + # This library was specified with -dlopen. + if test dlopen = "$pass"; then + test -z "$libdir" \ + && func_fatal_error "cannot -dlopen a convenience library: '$lib'" + if test -z "$dlname" || + test yes != "$dlopen_support" || + test no = "$build_libtool_libs" + then + # If there is no dlname, no dlopen support or we're linking + # statically, we need to preload. We also need to preload any + # dependent libraries so libltdl's deplib preloader doesn't + # bomb out in the load deplibs phase. + func_append dlprefiles " $lib $dependency_libs" + else + func_append newdlfiles " $lib" + fi + continue + fi # $pass = dlopen + + # We need an absolute path. + case $ladir in + [\\/]* | [A-Za-z]:[\\/]*) abs_ladir=$ladir ;; + *) + abs_ladir=`cd "$ladir" && pwd` + if test -z "$abs_ladir"; then + func_warning "cannot determine absolute directory name of '$ladir'" + func_warning "passing it literally to the linker, although it might fail" + abs_ladir=$ladir + fi + ;; + esac + func_basename "$lib" + laname=$func_basename_result + + # Find the relevant object directory and library name. + if test yes = "$installed"; then + if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then + func_warning "library '$lib' was moved." + dir=$ladir + absdir=$abs_ladir + libdir=$abs_ladir + else + dir=$lt_sysroot$libdir + absdir=$lt_sysroot$libdir + fi + test yes = "$hardcode_automatic" && avoidtemprpath=yes + else + if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then + dir=$ladir + absdir=$abs_ladir + # Remove this search path later + func_append notinst_path " $abs_ladir" + else + dir=$ladir/$objdir + absdir=$abs_ladir/$objdir + # Remove this search path later + func_append notinst_path " $abs_ladir" + fi + fi # $installed = yes + func_stripname 'lib' '.la' "$laname" + name=$func_stripname_result + + # This library was specified with -dlpreopen. + if test dlpreopen = "$pass"; then + if test -z "$libdir" && test prog = "$linkmode"; then + func_fatal_error "only libraries may -dlpreopen a convenience library: '$lib'" + fi + case $host in + # special handling for platforms with PE-DLLs. + *cygwin* | *mingw* | *cegcc* ) + # Linker will automatically link against shared library if both + # static and shared are present. Therefore, ensure we extract + # symbols from the import library if a shared library is present + # (otherwise, the dlopen module name will be incorrect). We do + # this by putting the import library name into $newdlprefiles. + # We recover the dlopen module name by 'saving' the la file + # name in a special purpose variable, and (later) extracting the + # dlname from the la file. + if test -n "$dlname"; then + func_tr_sh "$dir/$linklib" + eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" + func_append newdlprefiles " $dir/$linklib" + else + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + fi + ;; + * ) + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + func_append newdlprefiles " $dir/$old_library" + # Keep a list of preopened convenience libraries to check + # that they are being used correctly in the link pass. + test -z "$libdir" && \ + func_append dlpreconveniencelibs " $dir/$old_library" + # Otherwise, use the dlname, so that lt_dlopen finds it. + elif test -n "$dlname"; then + func_append newdlprefiles " $dir/$dlname" + else + func_append newdlprefiles " $dir/$linklib" + fi + ;; + esac + fi # $pass = dlpreopen + + if test -z "$libdir"; then + # Link the convenience library + if test lib = "$linkmode"; then + deplibs="$dir/$old_library $deplibs" + elif test prog,link = "$linkmode,$pass"; then + compile_deplibs="$dir/$old_library $compile_deplibs" + finalize_deplibs="$dir/$old_library $finalize_deplibs" + else + deplibs="$lib $deplibs" # used for prog,scan pass + fi + continue + fi + + + if test prog = "$linkmode" && test link != "$pass"; then + func_append newlib_search_path " $ladir" + deplibs="$lib $deplibs" + + linkalldeplibs=false + if test no != "$link_all_deplibs" || test -z "$library_names" || + test no = "$build_libtool_libs"; then + linkalldeplibs=: + fi + + tmp_libs= + for deplib in $dependency_libs; do + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result" + func_append newlib_search_path " $func_resolve_sysroot_result" + ;; + esac + # Need to link against all dependency_libs? + if $linkalldeplibs; then + deplibs="$deplib $deplibs" + else + # Need to hardcode shared library paths + # or/and link against static libraries + newdependency_libs="$deplib $newdependency_libs" + fi + if $opt_preserve_dup_deps; then + case "$tmp_libs " in + *" $deplib "*) func_append specialdeplibs " $deplib" ;; + esac + fi + func_append tmp_libs " $deplib" + done # for deplib + continue + fi # $linkmode = prog... + + if test prog,link = "$linkmode,$pass"; then + if test -n "$library_names" && + { { test no = "$prefer_static_libs" || + test built,yes = "$prefer_static_libs,$installed"; } || + test -z "$old_library"; }; then + # We need to hardcode the library path + if test -n "$shlibpath_var" && test -z "$avoidtemprpath"; then + # Make sure the rpath contains only unique directories. + case $temp_rpath: in + *"$absdir:"*) ;; + *) func_append temp_rpath "$absdir:" ;; + esac + fi + + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi # $linkmode,$pass = prog,link... + + if $alldeplibs && + { test pass_all = "$deplibs_check_method" || + { test yes = "$build_libtool_libs" && + test -n "$library_names"; }; }; then + # We only need to search for static libraries + continue + fi + fi + + link_static=no # Whether the deplib will be linked statically + use_static_libs=$prefer_static_libs + if test built = "$use_static_libs" && test yes = "$installed"; then + use_static_libs=no + fi + if test -n "$library_names" && + { test no = "$use_static_libs" || test -z "$old_library"; }; then + case $host in + *cygwin* | *mingw* | *cegcc* | *os2*) + # No point in relinking DLLs because paths are not encoded + func_append notinst_deplibs " $lib" + need_relink=no + ;; + *) + if test no = "$installed"; then + func_append notinst_deplibs " $lib" + need_relink=yes + fi + ;; + esac + # This is a shared library + + # Warn about portability, can't link against -module's on some + # systems (darwin). Don't bleat about dlopened modules though! + dlopenmodule= + for dlpremoduletest in $dlprefiles; do + if test "X$dlpremoduletest" = "X$lib"; then + dlopenmodule=$dlpremoduletest + break + fi + done + if test -z "$dlopenmodule" && test yes = "$shouldnotlink" && test link = "$pass"; then + echo + if test prog = "$linkmode"; then + $ECHO "*** Warning: Linking the executable $output against the loadable module" + else + $ECHO "*** Warning: Linking the shared library $output against the loadable module" + fi + $ECHO "*** $linklib is not portable!" + fi + if test lib = "$linkmode" && + test yes = "$hardcode_into_libs"; then + # Hardcode the library path. + # Skip directories that are in the system default run-time + # search path. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) func_append compile_rpath " $absdir" ;; + esac + ;; + esac + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + ;; + esac + fi + + if test -n "$old_archive_from_expsyms_cmds"; then + # figure out the soname + set dummy $library_names + shift + realname=$1 + shift + libname=`eval "\\$ECHO \"$libname_spec\""` + # use dlname if we got it. it's perfectly good, no? + if test -n "$dlname"; then + soname=$dlname + elif test -n "$soname_spec"; then + # bleh windows + case $host in + *cygwin* | mingw* | *cegcc* | *os2*) + func_arith $current - $age + major=$func_arith_result + versuffix=-$major + ;; + esac + eval soname=\"$soname_spec\" + else + soname=$realname + fi + + # Make a new name for the extract_expsyms_cmds to use + soroot=$soname + func_basename "$soroot" + soname=$func_basename_result + func_stripname 'lib' '.dll' "$soname" + newlib=libimp-$func_stripname_result.a + + # If the library has no export list, then create one now + if test -f "$output_objdir/$soname-def"; then : + else + func_verbose "extracting exported symbol list from '$soname'" + func_execute_cmds "$extract_expsyms_cmds" 'exit $?' + fi + + # Create $newlib + if test -f "$output_objdir/$newlib"; then :; else + func_verbose "generating import library for '$soname'" + func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' + fi + # make sure the library variables are pointing to the new library + dir=$output_objdir + linklib=$newlib + fi # test -n "$old_archive_from_expsyms_cmds" + + if test prog = "$linkmode" || test relink != "$opt_mode"; then + add_shlibpath= + add_dir= + add= + lib_linked=yes + case $hardcode_action in + immediate | unsupported) + if test no = "$hardcode_direct"; then + add=$dir/$linklib + case $host in + *-*-sco3.2v5.0.[024]*) add_dir=-L$dir ;; + *-*-sysv4*uw2*) add_dir=-L$dir ;; + *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ + *-*-unixware7*) add_dir=-L$dir ;; + *-*-darwin* ) + # if the lib is a (non-dlopened) module then we cannot + # link against it, someone is ignoring the earlier warnings + if /usr/bin/file -L $add 2> /dev/null | + $GREP ": [^:]* bundle" >/dev/null; then + if test "X$dlopenmodule" != "X$lib"; then + $ECHO "*** Warning: lib $linklib is a module, not a shared library" + if test -z "$old_library"; then + echo + echo "*** And there doesn't seem to be a static archive available" + echo "*** The link will probably fail, sorry" + else + add=$dir/$old_library + fi + elif test -n "$old_library"; then + add=$dir/$old_library + fi + fi + esac + elif test no = "$hardcode_minus_L"; then + case $host in + *-*-sunos*) add_shlibpath=$dir ;; + esac + add_dir=-L$dir + add=-l$name + elif test no = "$hardcode_shlibpath_var"; then + add_shlibpath=$dir + add=-l$name + else + lib_linked=no + fi + ;; + relink) + if test yes = "$hardcode_direct" && + test no = "$hardcode_direct_absolute"; then + add=$dir/$linklib + elif test yes = "$hardcode_minus_L"; then + add_dir=-L$absdir + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add=-l$name + elif test yes = "$hardcode_shlibpath_var"; then + add_shlibpath=$dir + add=-l$name + else + lib_linked=no + fi + ;; + *) lib_linked=no ;; + esac + + if test yes != "$lib_linked"; then + func_fatal_configuration "unsupported hardcode properties" + fi + + if test -n "$add_shlibpath"; then + case :$compile_shlibpath: in + *":$add_shlibpath:"*) ;; + *) func_append compile_shlibpath "$add_shlibpath:" ;; + esac + fi + if test prog = "$linkmode"; then + test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" + test -n "$add" && compile_deplibs="$add $compile_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + if test yes != "$hardcode_direct" && + test yes != "$hardcode_minus_L" && + test yes = "$hardcode_shlibpath_var"; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + fi + fi + fi + + if test prog = "$linkmode" || test relink = "$opt_mode"; then + add_shlibpath= + add_dir= + add= + # Finalize command for both is simple: just hardcode it. + if test yes = "$hardcode_direct" && + test no = "$hardcode_direct_absolute"; then + add=$libdir/$linklib + elif test yes = "$hardcode_minus_L"; then + add_dir=-L$libdir + add=-l$name + elif test yes = "$hardcode_shlibpath_var"; then + case :$finalize_shlibpath: in + *":$libdir:"*) ;; + *) func_append finalize_shlibpath "$libdir:" ;; + esac + add=-l$name + elif test yes = "$hardcode_automatic"; then + if test -n "$inst_prefix_dir" && + test -f "$inst_prefix_dir$libdir/$linklib"; then + add=$inst_prefix_dir$libdir/$linklib + else + add=$libdir/$linklib + fi + else + # We cannot seem to hardcode it, guess we'll fake it. + add_dir=-L$libdir + # Try looking first in the location we're being installed to. + if test -n "$inst_prefix_dir"; then + case $libdir in + [\\/]*) + func_append add_dir " -L$inst_prefix_dir$libdir" + ;; + esac + fi + add=-l$name + fi + + if test prog = "$linkmode"; then + test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" + test -n "$add" && finalize_deplibs="$add $finalize_deplibs" + else + test -n "$add_dir" && deplibs="$add_dir $deplibs" + test -n "$add" && deplibs="$add $deplibs" + fi + fi + elif test prog = "$linkmode"; then + # 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 unsupported != "$hardcode_direct"; then + test -n "$old_library" && linklib=$old_library + compile_deplibs="$dir/$linklib $compile_deplibs" + finalize_deplibs="$dir/$linklib $finalize_deplibs" + else + compile_deplibs="-l$name -L$dir $compile_deplibs" + finalize_deplibs="-l$name -L$dir $finalize_deplibs" + fi + elif test yes = "$build_libtool_libs"; then + # Not a shared library + if test pass_all != "$deplibs_check_method"; then + # We're trying link a shared library against a static one + # but the system doesn't support it. + + # Just print a warning and add the library to dependency_libs so + # that the program can be linked against the static library. + echo + $ECHO "*** Warning: This system cannot link to static lib archive $lib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have." + if test yes = "$module"; then + echo "*** But as you try to build a module library, libtool will still create " + echo "*** a static module, that should work as long as the dlopening application" + echo "*** is linked with the -dlopen flag to resolve symbols at runtime." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using 'nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** 'nm' from GNU binutils and a full rebuild may help." + fi + if test no = "$build_old_libs"; then + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + else + deplibs="$dir/$old_library $deplibs" + link_static=yes + fi + fi # link shared/static library? + + if test lib = "$linkmode"; then + if test -n "$dependency_libs" && + { test yes != "$hardcode_into_libs" || + test yes = "$build_old_libs" || + test yes = "$link_static"; }; then + # Extract -R from dependency_libs + temp_deplibs= + for libdir in $dependency_libs; do + case $libdir in + -R*) func_stripname '-R' '' "$libdir" + temp_xrpath=$func_stripname_result + case " $xrpath " in + *" $temp_xrpath "*) ;; + *) func_append xrpath " $temp_xrpath";; + esac;; + *) func_append temp_deplibs " $libdir";; + esac + done + dependency_libs=$temp_deplibs + fi + + func_append newlib_search_path " $absdir" + # Link against this library + test no = "$link_static" && newdependency_libs="$abs_ladir/$laname $newdependency_libs" + # ... and its dependency_libs + tmp_libs= + for deplib in $dependency_libs; do + newdependency_libs="$deplib $newdependency_libs" + case $deplib in + -L*) func_stripname '-L' '' "$deplib" + func_resolve_sysroot "$func_stripname_result";; + *) func_resolve_sysroot "$deplib" ;; + esac + if $opt_preserve_dup_deps; then + case "$tmp_libs " in + *" $func_resolve_sysroot_result "*) + func_append specialdeplibs " $func_resolve_sysroot_result" ;; + esac + fi + func_append tmp_libs " $func_resolve_sysroot_result" + done + + if test no != "$link_all_deplibs"; then + # Add the search paths of all dependency libraries + for deplib in $dependency_libs; do + path= + case $deplib in + -L*) path=$deplib ;; + *.la) + func_resolve_sysroot "$deplib" + deplib=$func_resolve_sysroot_result + func_dirname "$deplib" "" "." + dir=$func_dirname_result + # We need an absolute path. + case $dir in + [\\/]* | [A-Za-z]:[\\/]*) absdir=$dir ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + func_warning "cannot determine absolute directory name of '$dir'" + absdir=$dir + fi + ;; + esac + if $GREP "^installed=no" $deplib > /dev/null; then + case $host in + *-*-darwin*) + depdepl= + eval deplibrary_names=`$SED -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` + if test -n "$deplibrary_names"; then + for tmp in $deplibrary_names; do + depdepl=$tmp + done + if test -f "$absdir/$objdir/$depdepl"; then + depdepl=$absdir/$objdir/$depdepl + darwin_install_name=`$OTOOL -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + if test -z "$darwin_install_name"; then + darwin_install_name=`$OTOOL64 -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` + fi + func_append compiler_flags " $wl-dylib_file $wl$darwin_install_name:$depdepl" + func_append linker_flags " -dylib_file $darwin_install_name:$depdepl" + path= + fi + fi + ;; + *) + path=-L$absdir/$objdir + ;; + esac + else + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` + test -z "$libdir" && \ + func_fatal_error "'$deplib' is not a valid libtool archive" + test "$absdir" != "$libdir" && \ + func_warning "'$deplib' seems to be moved" + + path=-L$absdir + fi + ;; + esac + case " $deplibs " in + *" $path "*) ;; + *) deplibs="$path $deplibs" ;; + esac + done + fi # link_all_deplibs != no + fi # linkmode = lib + done # for deplib in $libs + if test link = "$pass"; then + if test prog = "$linkmode"; then + compile_deplibs="$new_inherited_linker_flags $compile_deplibs" + finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" + else + compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + fi + fi + dependency_libs=$newdependency_libs + if test dlpreopen = "$pass"; then + # Link the dlpreopened libraries before other libraries + for deplib in $save_deplibs; do + deplibs="$deplib $deplibs" + done + fi + if test dlopen != "$pass"; then + test conv = "$pass" || { + # Make sure lib_search_path contains only unique directories. + lib_search_path= + for dir in $newlib_search_path; do + case "$lib_search_path " in + *" $dir "*) ;; + *) func_append lib_search_path " $dir" ;; + esac + done + newlib_search_path= + } + + if test prog,link = "$linkmode,$pass"; then + vars="compile_deplibs finalize_deplibs" + else + vars=deplibs + fi + for var in $vars dependency_libs; do + # Add libraries to $var in reverse order + eval tmp_libs=\"\$$var\" + new_libs= + for deplib in $tmp_libs; do + # FIXME: Pedantically, this is the right thing to do, so + # that some nasty dependency loop isn't accidentally + # broken: + #new_libs="$deplib $new_libs" + # Pragmatically, this seems to cause very few problems in + # practice: + case $deplib in + -L*) new_libs="$deplib $new_libs" ;; + -R*) ;; + *) + # And here is the reason: when a library appears more + # than once as an explicit dependence of a library, or + # is implicitly linked in more than once by the + # compiler, it is considered special, and multiple + # occurrences thereof are not removed. Compare this + # with having the same library being listed as a + # dependency of multiple other libraries: in this case, + # we know (pedantically, we assume) the library does not + # need to be listed more than once, so we keep only the + # last copy. This is not always right, but it is rare + # enough that we require users that really mean to play + # such unportable linking tricks to link the library + # using -Wl,-lname, so that libtool does not consider it + # for duplicate removal. + case " $specialdeplibs " in + *" $deplib "*) new_libs="$deplib $new_libs" ;; + *) + case " $new_libs " in + *" $deplib "*) ;; + *) new_libs="$deplib $new_libs" ;; + esac + ;; + esac + ;; + esac + done + tmp_libs= + for deplib in $new_libs; do + case $deplib in + -L*) + case " $tmp_libs " in + *" $deplib "*) ;; + *) func_append tmp_libs " $deplib" ;; + esac + ;; + *) func_append tmp_libs " $deplib" ;; + esac + done + eval $var=\"$tmp_libs\" + done # for var + fi + + # Add Sun CC postdeps if required: + test CXX = "$tagname" && { + case $host_os in + linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C++ 5.9 + func_suncc_cstd_abi + + if test no != "$suncc_use_cstd_abi"; then + func_append postdeps ' -library=Cstd -library=Crun' + fi + ;; + esac + ;; + + solaris*) + func_cc_basename "$CC" + case $func_cc_basename_result in + CC* | sunCC*) + func_suncc_cstd_abi + + if test no != "$suncc_use_cstd_abi"; then + func_append postdeps ' -library=Cstd -library=Crun' + fi + ;; + esac + ;; + esac + } + + # Last step: remove runtime libs from dependency_libs + # (they stay in deplibs) + tmp_libs= + for i in $dependency_libs; do + case " $predeps $postdeps $compiler_lib_search_path " in + *" $i "*) + i= + ;; + esac + if test -n "$i"; then + func_append tmp_libs " $i" + fi + done + dependency_libs=$tmp_libs + done # for pass + if test prog = "$linkmode"; then + dlfiles=$newdlfiles + fi + if test prog = "$linkmode" || test lib = "$linkmode"; then + dlprefiles=$newdlprefiles + fi + + case $linkmode in + oldlib) + if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then + func_warning "'-dlopen' is ignored for archives" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "'-l' and '-L' are ignored for archives" ;; + esac + + test -n "$rpath" && \ + func_warning "'-rpath' is ignored for archives" + + test -n "$xrpath" && \ + func_warning "'-R' is ignored for archives" + + test -n "$vinfo" && \ + func_warning "'-version-info/-version-number' is ignored for archives" + + test -n "$release" && \ + func_warning "'-release' is ignored for archives" + + test -n "$export_symbols$export_symbols_regex" && \ + func_warning "'-export-symbols' is ignored for archives" + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs=$output + func_append objs "$old_deplibs" + ;; + + lib) + # Make sure we only generate libraries of the form 'libNAME.la'. + case $outputname in + lib*) + func_stripname 'lib' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + ;; + *) + test no = "$module" \ + && func_fatal_help "libtool library '$output' must begin with 'lib'" + + if test no != "$need_lib_prefix"; then + # Add the "lib" prefix for modules if required + func_stripname '' '.la' "$outputname" + name=$func_stripname_result + eval shared_ext=\"$shrext_cmds\" + eval libname=\"$libname_spec\" + else + func_stripname '' '.la' "$outputname" + libname=$func_stripname_result + fi + ;; + esac + + if test -n "$objs"; then + if test pass_all != "$deplibs_check_method"; then + func_fatal_error "cannot build libtool library '$output' from non-libtool objects on this host:$objs" + else + echo + $ECHO "*** Warning: Linking the shared library $output against the non-libtool" + $ECHO "*** objects $objs is not portable!" + func_append libobjs " $objs" + fi + fi + + test no = "$dlself" \ + || func_warning "'-dlopen self' is ignored for libtool libraries" + + set dummy $rpath + shift + test 1 -lt "$#" \ + && func_warning "ignoring multiple '-rpath's for a libtool library" + + install_libdir=$1 + + oldlibs= + if test -z "$rpath"; then + if test yes = "$build_libtool_libs"; then + # Building a libtool convenience library. + # Some compilers have problems with a '.al' extension so + # convenience libraries should have the same extension an + # archive normally would. + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + + test -n "$vinfo" && \ + func_warning "'-version-info/-version-number' is ignored for convenience libraries" + + test -n "$release" && \ + func_warning "'-release' is ignored for convenience libraries" + else + + # Parse the version information argument. + save_ifs=$IFS; IFS=: + set dummy $vinfo 0 0 0 + shift + IFS=$save_ifs + + test -n "$7" && \ + func_fatal_help "too many parameters to '-version-info'" + + # convert absolute version numbers to libtool ages + # this retains compatibility with .la files and attempts + # to make the code below a bit more comprehensible + + case $vinfo_number in + yes) + number_major=$1 + number_minor=$2 + number_revision=$3 + # + # There are really only two kinds -- those that + # use the current revision as the major version + # and those that subtract age and use age as + # a minor version. But, then there is irix + # that has an extra 1 added just for fun + # + case $version_type in + # correct linux to gnu/linux during the next big refactor + darwin|freebsd-elf|linux|osf|windows|none) + func_arith $number_major + $number_minor + current=$func_arith_result + age=$number_minor + revision=$number_revision + ;; + freebsd-aout|qnx|sunos) + current=$number_major + revision=$number_minor + age=0 + ;; + irix|nonstopux) + func_arith $number_major + $number_minor + current=$func_arith_result + age=$number_minor + revision=$number_minor + lt_irix_increment=no + ;; + esac + ;; + no) + current=$1 + revision=$2 + age=$3 + ;; + esac + + # Check that each of the things are valid numbers. + case $current in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "CURRENT '$current' must be a nonnegative integer" + func_fatal_error "'$vinfo' is not valid version information" + ;; + esac + + case $revision in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "REVISION '$revision' must be a nonnegative integer" + func_fatal_error "'$vinfo' is not valid version information" + ;; + esac + + case $age in + 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; + *) + func_error "AGE '$age' must be a nonnegative integer" + func_fatal_error "'$vinfo' is not valid version information" + ;; + esac + + if test "$age" -gt "$current"; then + func_error "AGE '$age' is greater than the current interface number '$current'" + func_fatal_error "'$vinfo' is not valid version information" + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case $version_type in + none) ;; + + darwin) + # Like Linux, but with the current version available in + # verstring for coding it into the library header + func_arith $current - $age + major=.$func_arith_result + versuffix=$major.$age.$revision + # Darwin ld doesn't like 0 for these options... + func_arith $current + 1 + minor_current=$func_arith_result + xlcverstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + # On Darwin other compilers + case $CC in + nagfor*) + verstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision" + ;; + *) + verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" + ;; + esac + ;; + + freebsd-aout) + major=.$current + versuffix=.$current.$revision + ;; + + freebsd-elf) + func_arith $current - $age + major=.$func_arith_result + versuffix=$major.$age.$revision + ;; + + irix | nonstopux) + if test no = "$lt_irix_increment"; then + func_arith $current - $age + else + func_arith $current - $age + 1 + fi + major=$func_arith_result + + case $version_type in + nonstopux) verstring_prefix=nonstopux ;; + *) verstring_prefix=sgi ;; + esac + verstring=$verstring_prefix$major.$revision + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test 0 -ne "$loop"; do + func_arith $revision - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring=$verstring_prefix$major.$iface:$verstring + done + + # Before this point, $major must not contain '.'. + major=.$major + versuffix=$major.$revision + ;; + + linux) # correct to gnu/linux during the next big refactor + func_arith $current - $age + major=.$func_arith_result + versuffix=$major.$age.$revision + ;; + + osf) + func_arith $current - $age + major=.$func_arith_result + versuffix=.$current.$age.$revision + verstring=$current.$age.$revision + + # Add in all the interfaces that we are compatible with. + loop=$age + while test 0 -ne "$loop"; do + func_arith $current - $loop + iface=$func_arith_result + func_arith $loop - 1 + loop=$func_arith_result + verstring=$verstring:$iface.0 + done + + # Make executables depend on our current version. + func_append verstring ":$current.0" + ;; + + qnx) + major=.$current + versuffix=.$current + ;; + + sco) + major=.$current + versuffix=.$current + ;; + + sunos) + major=.$current + versuffix=.$current.$revision + ;; + + windows) + # Use '-' rather than '.', since we only want one + # extension on DOS 8.3 file systems. + func_arith $current - $age + major=$func_arith_result + versuffix=-$major + ;; + + *) + func_fatal_configuration "unknown library version type '$version_type'" + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + case $version_type in + darwin) + # we can't check for "0.0" in archive_cmds due to quoting + # problems, so we reset it completely + verstring= + ;; + *) + verstring=0.0 + ;; + esac + if test no = "$need_version"; then + versuffix= + else + versuffix=.0.0 + fi + fi + + # Remove version info from name if versioning should be avoided + if test yes,no = "$avoid_version,$need_version"; then + major= + versuffix= + verstring= + fi + + # Check to see if the archive will have undefined symbols. + if test yes = "$allow_undefined"; then + if test unsupported = "$allow_undefined_flag"; then + if test yes = "$build_old_libs"; then + func_warning "undefined symbols not allowed in $host shared libraries; building static only" + build_libtool_libs=no + else + func_fatal_error "can't build $host shared library unless -no-undefined is specified" + fi + fi + else + # Don't allow undefined symbols. + allow_undefined_flag=$no_undefined_flag + fi + + fi + + func_generate_dlsyms "$libname" "$libname" : + func_append libobjs " $symfileobj" + test " " = "$libobjs" && libobjs= + + if test relink != "$opt_mode"; then + # Remove our outputs, but don't remove object files since they + # may have been created when compiling PIC objects. + removelist= + tempremovelist=`$ECHO "$output_objdir/*"` + for p in $tempremovelist; do + case $p in + *.$objext | *.gcno) + ;; + $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/$libname$release.*) + if test -n "$precious_files_regex"; then + if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 + then + continue + fi + fi + func_append removelist " $p" + ;; + *) ;; + esac + done + test -n "$removelist" && \ + func_show_eval "${RM}r \$removelist" + fi + + # Now set the variables for building old libraries. + if test yes = "$build_old_libs" && test convenience != "$build_libtool_libs"; then + func_append oldlibs " $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; $lo2o" | $NL2SP` + fi + + # Eliminate all temporary directories. + #for path in $notinst_path; do + # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` + # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` + # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` + #done + + if test -n "$xrpath"; then + # If the user specified any rpath flags, then add them. + temp_xrpath= + for libdir in $xrpath; do + func_replace_sysroot "$libdir" + func_append temp_xrpath " -R$func_replace_sysroot_result" + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + if test yes != "$hardcode_into_libs" || test yes = "$build_old_libs"; then + dependency_libs="$temp_xrpath $dependency_libs" + fi + fi + + # Make sure dlfiles contains only unique files that won't be dlpreopened + old_dlfiles=$dlfiles + dlfiles= + for lib in $old_dlfiles; do + case " $dlprefiles $dlfiles " in + *" $lib "*) ;; + *) func_append dlfiles " $lib" ;; + esac + done + + # Make sure dlprefiles contains only unique files + old_dlprefiles=$dlprefiles + dlprefiles= + for lib in $old_dlprefiles; do + case "$dlprefiles " in + *" $lib "*) ;; + *) func_append dlprefiles " $lib" ;; + esac + done + + if test yes = "$build_libtool_libs"; then + if test -n "$rpath"; then + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) + # these systems don't actually have a c library (as such)! + ;; + *-*-rhapsody* | *-*-darwin1.[012]) + # Rhapsody C library is in the System framework + func_append deplibs " System.ltframework" + ;; + *-*-netbsd*) + # Don't link with libc until the a.out ld.so is fixed. + ;; + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) + # Do not include libc due to us having libc/libc_r. + ;; + *-*-sco3.2v5* | *-*-sco5v6*) + # Causes problems with __ctype + ;; + *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) + # Compiler inserts libc in the correct place for threads to work + ;; + *) + # Add libc to deplibs on all other systems if necessary. + if test yes = "$build_libtool_need_lc"; then + func_append deplibs " -lc" + fi + ;; + esac + fi + + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release= + versuffix= + major= + newdeplibs= + droppeddeps=no + case $deplibs_check_method in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behavior. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $opt_dry_run || $RM conftest.c + cat > conftest.c <<EOF + int main() { return 0; } +EOF + $opt_dry_run || $RM conftest + if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then + ldd_output=`ldd conftest` + for i in $deplibs; do + case $i in + -l*) + func_stripname -l '' "$i" + name=$func_stripname_result + if test yes = "$allow_libtool_libs_with_static_runtimes"; then + case " $predeps $postdeps " in + *" $i "*) + func_append newdeplibs " $i" + i= + ;; + esac + fi + if test -n "$i"; then + libname=`eval "\\$ECHO \"$libname_spec\""` + deplib_matches=`eval "\\$ECHO \"$library_names_spec\""` + set dummy $deplib_matches; shift + deplib_match=$1 + if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0; then + func_append newdeplibs " $i" + else + droppeddeps=yes + echo + $ECHO "*** Warning: dynamic linker does not accept needed library $i." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which I believe you do not have" + echo "*** because a test_compile did reveal that the linker did not use it for" + echo "*** its dynamic dependency list that programs get resolved with at runtime." + fi + fi + ;; + *) + func_append newdeplibs " $i" + ;; + esac + done + else + # Error occurred in the first compile. Let's try to salvage + # the situation: Compile a separate program for each library. + for i in $deplibs; do + case $i in + -l*) + func_stripname -l '' "$i" + name=$func_stripname_result + $opt_dry_run || $RM conftest + if $LTCC $LTCFLAGS -o conftest conftest.c $i; then + ldd_output=`ldd conftest` + if test yes = "$allow_libtool_libs_with_static_runtimes"; then + case " $predeps $postdeps " in + *" $i "*) + func_append newdeplibs " $i" + i= + ;; + esac + fi + if test -n "$i"; then + libname=`eval "\\$ECHO \"$libname_spec\""` + deplib_matches=`eval "\\$ECHO \"$library_names_spec\""` + set dummy $deplib_matches; shift + deplib_match=$1 + if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0; then + func_append newdeplibs " $i" + else + droppeddeps=yes + echo + $ECHO "*** Warning: dynamic linker does not accept needed library $i." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because a test_compile did reveal that the linker did not use this one" + echo "*** as a dynamic dependency that programs can get resolved with at runtime." + fi + fi + else + droppeddeps=yes + echo + $ECHO "*** Warning! Library $i is needed by this library but I was not able to" + echo "*** make it link in! You will probably need to install it or some" + echo "*** library that it depends on before this library will be fully" + echo "*** functional. Installing it before continuing would be even better." + fi + ;; + *) + func_append newdeplibs " $i" + ;; + esac + done + fi + ;; + file_magic*) + set dummy $deplibs_check_method; shift + file_magic_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + for a_deplib in $deplibs; do + case $a_deplib in + -l*) + func_stripname -l '' "$a_deplib" + name=$func_stripname_result + if test yes = "$allow_libtool_libs_with_static_runtimes"; then + case " $predeps $postdeps " in + *" $a_deplib "*) + func_append newdeplibs " $a_deplib" + a_deplib= + ;; + esac + fi + if test -n "$a_deplib"; then + libname=`eval "\\$ECHO \"$libname_spec\""` + if test -n "$file_magic_glob"; then + libnameglob=`func_echo_all "$libname" | $SED -e $file_magic_glob` + else + libnameglob=$libname + fi + test yes = "$want_nocaseglob" && nocaseglob=`shopt -p nocaseglob` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + if test yes = "$want_nocaseglob"; then + shopt -s nocaseglob + potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` + $nocaseglob + else + potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` + fi + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null | + $GREP " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib=$potent_lib + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | $SED 's/.* -> //'` + case $potliblink in + [\\/]* | [A-Za-z]:[\\/]*) potlib=$potliblink;; + *) potlib=`$ECHO "$potlib" | $SED 's|[^/]*$||'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | + $SED -e 10q | + $EGREP "$file_magic_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib= + break 2 + fi + done + done + fi + if test -n "$a_deplib"; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib"; then + $ECHO "*** with $libname but no candidates were found. (...for file magic test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a file magic. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + match_pattern*) + set dummy $deplibs_check_method; shift + match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` + for a_deplib in $deplibs; do + case $a_deplib in + -l*) + func_stripname -l '' "$a_deplib" + name=$func_stripname_result + if test yes = "$allow_libtool_libs_with_static_runtimes"; then + case " $predeps $postdeps " in + *" $a_deplib "*) + func_append newdeplibs " $a_deplib" + a_deplib= + ;; + esac + fi + if test -n "$a_deplib"; then + libname=`eval "\\$ECHO \"$libname_spec\""` + for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do + potential_libs=`ls $i/$libname[.-]* 2>/dev/null` + for potent_lib in $potential_libs; do + potlib=$potent_lib # see symlink-check above in file_magic test + if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ + $EGREP "$match_pattern_regex" > /dev/null; then + func_append newdeplibs " $a_deplib" + a_deplib= + break 2 + fi + done + done + fi + if test -n "$a_deplib"; then + droppeddeps=yes + echo + $ECHO "*** Warning: linker path does not have real file for library $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have" + echo "*** because I did check the linker path looking for a file starting" + if test -z "$potlib"; then + $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" + else + $ECHO "*** with $libname and none of the candidates passed a file format test" + $ECHO "*** using a regex pattern. Last file checked: $potlib" + fi + fi + ;; + *) + # Add a -L argument. + func_append newdeplibs " $a_deplib" + ;; + esac + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs= + tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` + if test yes = "$allow_libtool_libs_with_static_runtimes"; then + for i in $predeps $postdeps; do + # can't use Xsed below, because $i might contain '/' + tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s|$i||"` + done + fi + case $tmp_deplibs in + *[!\ \ ]*) + echo + if test none = "$deplibs_check_method"; then + echo "*** Warning: inter-library dependencies are not supported in this platform." + else + echo "*** Warning: inter-library dependencies are not known to be supported." + fi + echo "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + ;; + esac + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library with the System framework + newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + if test yes = "$droppeddeps"; then + if test yes = "$module"; then + echo + echo "*** Warning: libtool could not satisfy all declared inter-library" + $ECHO "*** dependencies of module $libname. Therefore, libtool will create" + echo "*** a static module, that should work as long as the dlopening" + echo "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using 'nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** 'nm' from GNU binutils and a full rebuild may help." + fi + if test no = "$build_old_libs"; then + oldlibs=$output_objdir/$libname.$libext + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + echo "*** The inter-library dependencies that have been dropped here will be" + echo "*** automatically added whenever a program is linked with this library" + echo "*** or is declared to -dlopen it." + + if test no = "$allow_undefined"; then + echo + echo "*** Since this library must not contain undefined symbols," + echo "*** because either the platform does not support them or" + echo "*** it was explicitly requested with -no-undefined," + echo "*** libtool will only create a static version of it." + if test no = "$build_old_libs"; then + oldlibs=$output_objdir/$libname.$libext + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + fi + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + case $host in + *-*-darwin*) + newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + deplibs=$new_libs + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test yes = "$build_libtool_libs"; then + # Remove $wl instances when linking with ld. + # FIXME: should test the right _cmds variable. + case $archive_cmds in + *\$LD\ *) wl= ;; + esac + if test yes = "$hardcode_into_libs"; then + # Hardcode the library paths + hardcode_libdirs= + dep_rpath= + rpath=$finalize_rpath + test relink = "$opt_mode" || rpath=$compile_rpath$rpath + for libdir in $rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + func_replace_sysroot "$libdir" + libdir=$func_replace_sysroot_result + if test -z "$hardcode_libdirs"; then + hardcode_libdirs=$libdir + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append dep_rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_append perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir=$hardcode_libdirs + eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" + fi + if test -n "$runpath_var" && test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" + fi + test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" + fi + + shlibpath=$finalize_shlibpath + test relink = "$opt_mode" || shlibpath=$compile_shlibpath$shlibpath + if test -n "$shlibpath"; then + eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" + fi + + # Get the real and link names of the library. + eval shared_ext=\"$shrext_cmds\" + eval library_names=\"$library_names_spec\" + set dummy $library_names + shift + realname=$1 + shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname=$realname + fi + if test -z "$dlname"; then + dlname=$soname + fi + + lib=$output_objdir/$realname + linknames= + for link + do + func_append linknames " $link" + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` + test "X$libobjs" = "X " && libobjs= + + delfiles= + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" + export_symbols=$output_objdir/$libname.uexp + func_append delfiles " $export_symbols" + fi + + orig_export_symbols= + case $host_os in + cygwin* | mingw* | cegcc*) + if test -n "$export_symbols" && test -z "$export_symbols_regex"; then + # exporting using user supplied symfile + func_dll_def_p "$export_symbols" || { + # and it's NOT already a .def file. Must figure out + # which of the given symbols are data symbols and tag + # them as such. So, trigger use of export_symbols_cmds. + # export_symbols gets reassigned inside the "prepare + # the list of exported symbols" if statement, so the + # include_expsyms logic still works. + orig_export_symbols=$export_symbols + export_symbols= + always_export_symbols=yes + } + fi + ;; + esac + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test yes = "$always_export_symbols" || test -n "$export_symbols_regex"; then + func_verbose "generating symbol list for '$libname.la'" + export_symbols=$output_objdir/$libname.exp + $opt_dry_run || $RM $export_symbols + cmds=$export_symbols_cmds + save_ifs=$IFS; IFS='~' + for cmd1 in $cmds; do + IFS=$save_ifs + # Take the normal branch if the nm_file_list_spec branch + # doesn't work or if tool conversion is not needed. + case $nm_file_list_spec~$to_tool_file_cmd in + *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) + try_normal_branch=yes + eval cmd=\"$cmd1\" + func_len " $cmd" + len=$func_len_result + ;; + *) + try_normal_branch=no + ;; + esac + if test yes = "$try_normal_branch" \ + && { test "$len" -lt "$max_cmd_len" \ + || test "$max_cmd_len" -le -1; } + then + func_show_eval "$cmd" 'exit $?' + skipped_export=false + elif test -n "$nm_file_list_spec"; then + func_basename "$output" + output_la=$func_basename_result + save_libobjs=$libobjs + save_output=$output + output=$output_objdir/$output_la.nm + func_to_tool_file "$output" + libobjs=$nm_file_list_spec$func_to_tool_file_result + func_append delfiles " $output" + func_verbose "creating $NM input file list: $output" + for obj in $save_libobjs; do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > "$output" + eval cmd=\"$cmd1\" + func_show_eval "$cmd" 'exit $?' + output=$save_output + libobjs=$save_libobjs + skipped_export=false + else + # The command line is too long to execute in one step. + func_verbose "using reloadable object file for export list..." + skipped_export=: + # Break out early, otherwise skipped_export may be + # set to false by a later but shorter cmd. + break + fi + done + IFS=$save_ifs + if test -n "$export_symbols_regex" && test : != "$skipped_export"; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols=$export_symbols + test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test : != "$skipped_export" && test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for '$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands, which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + func_append delfiles " $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + + tmp_deplibs= + for test_deplib in $deplibs; do + case " $convenience " in + *" $test_deplib "*) ;; + *) + func_append tmp_deplibs " $test_deplib" + ;; + esac + done + deplibs=$tmp_deplibs + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec" && + test yes = "$compiler_needs_object" && + test -z "$libobjs"; then + # extract the archives, so we have objects to list. + # TODO: could optimize this to just extract one archive. + whole_archive_flag_spec= + fi + if test -n "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + else + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + fi + + if test yes = "$thread_safe" && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + func_append linker_flags " $flag" + fi + + # Make a backup of the uninstalled library when relinking + if test relink = "$opt_mode"; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? + fi + + # Do each of the archive commands. + if test yes = "$module" && test -n "$module_cmds"; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + eval test_cmds=\"$module_expsym_cmds\" + cmds=$module_expsym_cmds + else + eval test_cmds=\"$module_cmds\" + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval test_cmds=\"$archive_expsym_cmds\" + cmds=$archive_expsym_cmds + else + eval test_cmds=\"$archive_cmds\" + cmds=$archive_cmds + fi + fi + + if test : != "$skipped_export" && + func_len " $test_cmds" && + len=$func_len_result && + test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + : + else + # The command line is too long to link in one step, link piecewise + # or, if using GNU ld and skipped_export is not :, use a linker + # script. + + # Save the value of $output and $libobjs because we want to + # use them later. If we have whole_archive_flag_spec, we + # want to use save_libobjs as it was before + # whole_archive_flag_spec was expanded, because we can't + # assume the linker understands whole_archive_flag_spec. + # This may have to be revisited, in case too many + # convenience libraries get linked in and end up exceeding + # the spec. + if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then + save_libobjs=$libobjs + fi + save_output=$output + func_basename "$output" + output_la=$func_basename_result + + # Clear the reloadable object creation command queue and + # initialize k to one. + test_cmds= + concat_cmds= + objlist= + last_robj= + k=1 + + if test -n "$save_libobjs" && test : != "$skipped_export" && test yes = "$with_gnu_ld"; then + output=$output_objdir/$output_la.lnkscript + func_verbose "creating GNU ld script: $output" + echo 'INPUT (' > $output + for obj in $save_libobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + echo ')' >> $output + func_append delfiles " $output" + func_to_tool_file "$output" + output=$func_to_tool_file_result + elif test -n "$save_libobjs" && test : != "$skipped_export" && test -n "$file_list_spec"; then + output=$output_objdir/$output_la.lnk + func_verbose "creating linker input file list: $output" + : > $output + set x $save_libobjs + shift + firstobj= + if test yes = "$compiler_needs_object"; then + firstobj="$1 " + shift + fi + for obj + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" >> $output + done + func_append delfiles " $output" + func_to_tool_file "$output" + output=$firstobj\"$file_list_spec$func_to_tool_file_result\" + else + if test -n "$save_libobjs"; then + func_verbose "creating reloadable object files..." + output=$output_objdir/$output_la-$k.$objext + eval test_cmds=\"$reload_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + + # Loop over the list of objects to be linked. + for obj in $save_libobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + if test -z "$objlist" || + test "$len" -lt "$max_cmd_len"; then + func_append objlist " $obj" + else + # The command $test_cmds is almost too long, add a + # command to the queue. + if test 1 -eq "$k"; then + # The first file doesn't have a previous command to add. + reload_objs=$objlist + eval concat_cmds=\"$reload_cmds\" + else + # All subsequent reloadable object files will link in + # the last one created. + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" + fi + last_robj=$output_objdir/$output_la-$k.$objext + func_arith $k + 1 + k=$func_arith_result + output=$output_objdir/$output_la-$k.$objext + objlist=" $obj" + func_len " $last_robj" + func_arith $len0 + $func_len_result + len=$func_arith_result + fi + done + # Handle the remaining objects by creating one last + # reloadable object file. All subsequent reloadable object + # files will link in the last one created. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + reload_objs="$objlist $last_robj" + eval concat_cmds=\"\$concat_cmds$reload_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" + fi + func_append delfiles " $output" + + else + output= + fi + + ${skipped_export-false} && { + func_verbose "generating symbol list for '$libname.la'" + export_symbols=$output_objdir/$libname.exp + $opt_dry_run || $RM $export_symbols + libobjs=$output + # Append the command to create the export file. + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" + if test -n "$last_robj"; then + eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" + fi + } + + test -n "$save_libobjs" && + func_verbose "creating a temporary reloadable object file: $output" + + # Loop through the commands generated above and execute them. + save_ifs=$IFS; IFS='~' + for cmd in $concat_cmds; do + IFS=$save_ifs + $opt_quiet || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test relink = "$opt_mode"; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS=$save_ifs + + if test -n "$export_symbols_regex" && ${skipped_export-false}; then + func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + func_show_eval '$MV "${export_symbols}T" "$export_symbols"' + fi + fi + + ${skipped_export-false} && { + if test -n "$export_symbols" && test -n "$include_expsyms"; then + tmp_export_symbols=$export_symbols + test -n "$orig_export_symbols" && tmp_export_symbols=$orig_export_symbols + $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' + fi + + if test -n "$orig_export_symbols"; then + # The given exports_symbols file has to be filtered, so filter it. + func_verbose "filter symbol list for '$libname.la' to tag DATA exports" + # FIXME: $output_objdir/$libname.filter potentially contains lots of + # 's' commands, which not all seds can handle. GNU sed should be fine + # though. Also, the filter scales superlinearly with the number of + # global variables. join(1) would be nice here, but unfortunately + # isn't a blessed tool. + $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter + func_append delfiles " $export_symbols $output_objdir/$libname.filter" + export_symbols=$output_objdir/$libname.def + $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols + fi + } + + libobjs=$output + # Restore the value of output. + output=$save_output + + if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + test "X$libobjs" = "X " && libobjs= + fi + # Expand the library linking commands again to reset the + # value of $libobjs for piecewise linking. + + # Do each of the archive commands. + if test yes = "$module" && test -n "$module_cmds"; then + if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then + cmds=$module_expsym_cmds + else + cmds=$module_cmds + fi + else + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + cmds=$archive_expsym_cmds + else + cmds=$archive_cmds + fi + fi + fi + + if test -n "$delfiles"; then + # Append the command to remove temporary files to $cmds. + eval cmds=\"\$cmds~\$RM $delfiles\" + fi + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append libobjs " $func_extract_archives_result" + test "X$libobjs" = "X " && libobjs= + fi + + save_ifs=$IFS; IFS='~' + for cmd in $cmds; do + IFS=$sp$nl + eval cmd=\"$cmd\" + IFS=$save_ifs + $opt_quiet || { + func_quote_for_expand "$cmd" + eval "func_echo $func_quote_for_expand_result" + } + $opt_dry_run || eval "$cmd" || { + lt_exit=$? + + # Restore the uninstalled library and exit + if test relink = "$opt_mode"; then + ( cd "$output_objdir" && \ + $RM "${realname}T" && \ + $MV "${realname}U" "$realname" ) + fi + + exit $lt_exit + } + done + IFS=$save_ifs + + # Restore the uninstalled library and exit + if test relink = "$opt_mode"; then + $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? + + if test -n "$convenience"; then + if test -z "$whole_archive_flag_spec"; then + func_show_eval '${RM}r "$gentop"' + fi + fi + + exit $EXIT_SUCCESS + fi + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test yes = "$module" || test yes = "$export_dynamic"; then + # On all known operating systems, these are identical. + dlname=$soname + fi + fi + ;; + + obj) + if test -n "$dlfiles$dlprefiles" || test no != "$dlself"; then + func_warning "'-dlopen' is ignored for objects" + fi + + case " $deplibs" in + *\ -l* | *\ -L*) + func_warning "'-l' and '-L' are ignored for objects" ;; + esac + + test -n "$rpath" && \ + func_warning "'-rpath' is ignored for objects" + + test -n "$xrpath" && \ + func_warning "'-R' is ignored for objects" + + test -n "$vinfo" && \ + func_warning "'-version-info' is ignored for objects" + + test -n "$release" && \ + func_warning "'-release' is ignored for objects" + + case $output in + *.lo) + test -n "$objs$old_deplibs" && \ + func_fatal_error "cannot build library object '$output' from non-libtool objects" + + libobj=$output + func_lo2o "$libobj" + obj=$func_lo2o_result + ;; + *) + libobj= + obj=$output + ;; + esac + + # Delete the old objects. + $opt_dry_run || $RM $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # if reload_cmds runs $LD directly, get rid of -Wl from + # whole_archive_flag_spec and hope we can get by with turning comma + # into space. + case $reload_cmds in + *\$LD[\ \$]*) wl= ;; + esac + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" + test -n "$wl" || tmp_whole_archive_flags=`$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` + reload_conv_objs=$reload_objs\ $tmp_whole_archive_flags + else + gentop=$output_objdir/${obj}x + func_append generated " $gentop" + + func_extract_archives $gentop $convenience + reload_conv_objs="$reload_objs $func_extract_archives_result" + fi + fi + + # If we're not building shared, we need to use non_pic_objs + test yes = "$build_libtool_libs" || libobjs=$non_pic_objects + + # Create the old-style object. + reload_objs=$objs$old_deplibs' '`$ECHO "$libobjs" | $SP2NL | $SED "/\.$libext$/d; /\.lib$/d; $lo2o" | $NL2SP`' '$reload_conv_objs + + output=$obj + func_execute_cmds "$reload_cmds" 'exit $?' + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + fi + + test yes = "$build_libtool_libs" || { + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + # $show "echo timestamp > $libobj" + # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? + exit $EXIT_SUCCESS + } + + if test -n "$pic_flag" || test default != "$pic_mode"; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output=$libobj + func_execute_cmds "$reload_cmds" 'exit $?' + fi + + if test -n "$gentop"; then + func_show_eval '${RM}r "$gentop"' + fi + + exit $EXIT_SUCCESS + ;; + + prog) + case $host in + *cygwin*) func_stripname '' '.exe' "$output" + output=$func_stripname_result.exe;; + esac + test -n "$vinfo" && \ + func_warning "'-version-info' is ignored for programs" + + test -n "$release" && \ + func_warning "'-release' is ignored for programs" + + $preload \ + && test unknown,unknown,unknown = "$dlopen_support,$dlopen_self,$dlopen_self_static" \ + && func_warning "'LT_INIT([dlopen])' not used. Assuming no dlopen support." + + case $host in + *-*-rhapsody* | *-*-darwin1.[012]) + # On Rhapsody replace the C library is the System framework + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` + ;; + esac + + case $host in + *-*-darwin*) + # Don't allow lazy linking, it breaks C++ global constructors + # But is supposedly fixed on 10.4 or later (yay!). + if test CXX = "$tagname"; then + case ${MACOSX_DEPLOYMENT_TARGET-10.0} in + 10.[0123]) + func_append compile_command " $wl-bind_at_load" + func_append finalize_command " $wl-bind_at_load" + ;; + esac + fi + # Time to change all our "foo.ltframework" stuff back to "-framework foo" + compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` + ;; + esac + + + # move library search paths that coincide with paths to not yet + # installed libraries to the beginning of the library search list + new_libs= + for path in $notinst_path; do + case " $new_libs " in + *" -L$path/$objdir "*) ;; + *) + case " $compile_deplibs " in + *" -L$path/$objdir "*) + func_append new_libs " -L$path/$objdir" ;; + esac + ;; + esac + done + for deplib in $compile_deplibs; do + case $deplib in + -L*) + case " $new_libs " in + *" $deplib "*) ;; + *) func_append new_libs " $deplib" ;; + esac + ;; + *) func_append new_libs " $deplib" ;; + esac + done + compile_deplibs=$new_libs + + + func_append compile_command " $compile_deplibs" + func_append finalize_command " $finalize_deplibs" + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$finalize_rpath " in + *" $libdir "*) ;; + *) func_append finalize_rpath " $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs=$libdir + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) func_append perm_rpath " $libdir" ;; + esac + fi + case $host in + *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + testbindir=`$ECHO "$libdir" | $SED -e 's*/lib$*/bin*'` + case :$dllsearchpath: in + *":$libdir:"*) ;; + ::) dllsearchpath=$libdir;; + *) func_append dllsearchpath ":$libdir";; + esac + case :$dllsearchpath: in + *":$testbindir:"*) ;; + ::) dllsearchpath=$testbindir;; + *) func_append dllsearchpath ":$testbindir";; + esac + ;; + esac + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir=$hardcode_libdirs + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath=$rpath + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs=$libdir + else + # Just accumulate the unique libdirs. + case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + func_append rpath " $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) func_append finalize_perm_rpath " $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir=$hardcode_libdirs + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath=$rpath + + if test -n "$libobjs" && test yes = "$build_old_libs"; then + # Transform all the library objects into standard objects. + compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` + fi + + func_generate_dlsyms "$outputname" "@PROGRAM@" false + + # template prelinking step + if test -n "$prelink_cmds"; then + func_execute_cmds "$prelink_cmds" 'exit $?' + fi + + wrappers_required=: + case $host in + *cegcc* | *mingw32ce*) + # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. + wrappers_required=false + ;; + *cygwin* | *mingw* ) + test yes = "$build_libtool_libs" || wrappers_required=false + ;; + *) + if test no = "$need_relink" || test yes != "$build_libtool_libs"; then + wrappers_required=false + fi + ;; + esac + $wrappers_required || { + # Replace the output file specification. + compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + link_command=$compile_command$compile_rpath + + # We have no uninstalled library dependencies, so finalize right now. + exit_status=0 + func_show_eval "$link_command" 'exit_status=$?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + # Delete the generated files. + if test -f "$output_objdir/${outputname}S.$objext"; then + func_show_eval '$RM "$output_objdir/${outputname}S.$objext"' + fi + + exit $exit_status + } + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + func_append rpath "$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + func_append rpath "$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test yes = "$no_install"; then + # We don't need to create a wrapper script. + link_command=$compile_var$compile_command$compile_rpath + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` + # Delete the old output file. + $opt_dry_run || $RM $output + # Link the executable and exit + func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + exit $EXIT_SUCCESS + fi + + case $hardcode_action,$fast_install in + relink,*) + # Fast installation is not supported + link_command=$compile_var$compile_command$compile_rpath + relink_command=$finalize_var$finalize_command$finalize_rpath + + func_warning "this platform does not like uninstalled shared libraries" + func_warning "'$output' will be relinked during installation" + ;; + *,yes) + link_command=$finalize_var$compile_command$finalize_rpath + relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` + ;; + *,no) + link_command=$compile_var$compile_command$compile_rpath + relink_command=$finalize_var$finalize_command$finalize_rpath + ;; + *,needless) + link_command=$finalize_var$compile_command$finalize_rpath + relink_command= + ;; + esac + + # Replace the output file specification. + link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname + + func_show_eval "$link_command" 'exit $?' + + if test -n "$postlink_cmds"; then + func_to_tool_file "$output_objdir/$outputname" + postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` + func_execute_cmds "$postlink_cmds" 'exit $?' + fi + + # Now create the wrapper script. + func_verbose "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + relink_command="(cd `pwd`; $relink_command)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + fi + + # Only actually do things if not in dry run mode. + $opt_dry_run || { + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) func_stripname '' '.exe' "$output" + output=$func_stripname_result ;; + esac + # test for cygwin because mv fails w/o .exe extensions + case $host in + *cygwin*) + exeext=.exe + func_stripname '' '.exe' "$outputname" + outputname=$func_stripname_result ;; + *) exeext= ;; + esac + case $host in + *cygwin* | *mingw* ) + func_dirname_and_basename "$output" "" "." + output_name=$func_basename_result + output_path=$func_dirname_result + cwrappersource=$output_path/$objdir/lt-$output_name.c + cwrapper=$output_path/$output_name.exe + $RM $cwrappersource $cwrapper + trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 + + func_emit_cwrapperexe_src > $cwrappersource + + # The wrapper executable is built using the $host compiler, + # because it contains $host paths and files. If cross- + # compiling, it, like the target executable, must be + # executed on the $host or under an emulation environment. + $opt_dry_run || { + $LTCC $LTCFLAGS -o $cwrapper $cwrappersource + $STRIP $cwrapper + } + + # Now, create the wrapper script for func_source use: + func_ltwrapper_scriptname $cwrapper + $RM $func_ltwrapper_scriptname_result + trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 + $opt_dry_run || { + # note: this script will not be executed, so do not chmod. + if test "x$build" = "x$host"; then + $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result + else + func_emit_wrapper no > $func_ltwrapper_scriptname_result + fi + } + ;; + * ) + $RM $output + trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 + + func_emit_wrapper no > $output + chmod +x $output + ;; + esac + } + exit $EXIT_SUCCESS + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + case $build_libtool_libs in + convenience) + oldobjs="$libobjs_save $symfileobj" + addlibs=$convenience + build_libtool_libs=no + ;; + module) + oldobjs=$libobjs_save + addlibs=$old_convenience + build_libtool_libs=no + ;; + *) + oldobjs="$old_deplibs $non_pic_objects" + $preload && test -f "$symfileobj" \ + && func_append oldobjs " $symfileobj" + addlibs=$old_convenience + ;; + esac + + if test -n "$addlibs"; then + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + + func_extract_archives $gentop $addlibs + func_append oldobjs " $func_extract_archives_result" + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test yes = "$build_libtool_libs"; then + cmds=$old_archive_from_new_cmds + else + + # Add any objects from preloaded convenience libraries + if test -n "$dlprefiles"; then + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + + func_extract_archives $gentop $dlprefiles + func_append oldobjs " $func_extract_archives_result" + fi + + # POSIX demands no paths to be encoded in archives. We have + # to avoid creating archives with duplicate basenames if we + # might have to extract them afterwards, e.g., when creating a + # static archive out of a convenience library, or when linking + # the entirety of a libtool archive into another (currently + # not supported by libtool). + if (for obj in $oldobjs + do + func_basename "$obj" + $ECHO "$func_basename_result" + done | sort | sort -uc >/dev/null 2>&1); then + : + else + echo "copying selected object files to avoid basename conflicts..." + gentop=$output_objdir/${outputname}x + func_append generated " $gentop" + func_mkdir_p "$gentop" + save_oldobjs=$oldobjs + oldobjs= + counter=1 + for obj in $save_oldobjs + do + func_basename "$obj" + objbase=$func_basename_result + case " $oldobjs " in + " ") oldobjs=$obj ;; + *[\ /]"$objbase "*) + while :; do + # Make sure we don't pick an alternate name that also + # overlaps. + newobj=lt$counter-$objbase + func_arith $counter + 1 + counter=$func_arith_result + case " $oldobjs " in + *[\ /]"$newobj "*) ;; + *) if test ! -f "$gentop/$newobj"; then break; fi ;; + esac + done + func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" + func_append oldobjs " $gentop/$newobj" + ;; + *) func_append oldobjs " $obj" ;; + esac + done + fi + func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 + tool_oldlib=$func_to_tool_file_result + eval cmds=\"$old_archive_cmds\" + + func_len " $cmds" + len=$func_len_result + if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then + cmds=$old_archive_cmds + elif test -n "$archiver_list_spec"; then + func_verbose "using command file archive linking..." + for obj in $oldobjs + do + func_to_tool_file "$obj" + $ECHO "$func_to_tool_file_result" + done > $output_objdir/$libname.libcmd + func_to_tool_file "$output_objdir/$libname.libcmd" + oldobjs=" $archiver_list_spec$func_to_tool_file_result" + cmds=$old_archive_cmds + else + # the command line is too long to link in one step, link in parts + func_verbose "using piecewise archive linking..." + save_RANLIB=$RANLIB + RANLIB=: + objlist= + concat_cmds= + save_oldobjs=$oldobjs + oldobjs= + # Is there a better way of finding the last object in the list? + for obj in $save_oldobjs + do + last_oldobj=$obj + done + eval test_cmds=\"$old_archive_cmds\" + func_len " $test_cmds" + len0=$func_len_result + len=$len0 + for obj in $save_oldobjs + do + func_len " $obj" + func_arith $len + $func_len_result + len=$func_arith_result + func_append objlist " $obj" + if test "$len" -lt "$max_cmd_len"; then + : + else + # the above command should be used before it gets too long + oldobjs=$objlist + if test "$obj" = "$last_oldobj"; then + RANLIB=$save_RANLIB + fi + test -z "$concat_cmds" || concat_cmds=$concat_cmds~ + eval concat_cmds=\"\$concat_cmds$old_archive_cmds\" + objlist= + len=$len0 + fi + done + RANLIB=$save_RANLIB + oldobjs=$objlist + if test -z "$oldobjs"; then + eval cmds=\"\$concat_cmds\" + else + eval cmds=\"\$concat_cmds~\$old_archive_cmds\" + fi + fi + fi + func_execute_cmds "$cmds" 'exit $?' + done + + test -n "$generated" && \ + func_show_eval "${RM}r$generated" + + # Now create the libtool archive. + case $output in + *.la) + old_library= + test yes = "$build_old_libs" && old_library=$libname.$libext + func_verbose "creating $output" + + # Preserve any variables that may affect compiler behavior + for var in $variables_saved_for_relink; do + if eval test -z \"\${$var+set}\"; then + relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" + elif eval var_value=\$$var; test -z "$var_value"; then + relink_command="$var=; export $var; $relink_command" + else + func_quote_for_eval "$var_value" + relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" + fi + done + # Quote the link command for shipping. + relink_command="(cd `pwd`; $SHELL \"$progpath\" $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" + relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` + if test yes = "$hardcode_automatic"; then + relink_command= + fi + + # Only create the output if not a dry run. + $opt_dry_run || { + for installed in no yes; do + if test yes = "$installed"; then + if test -z "$install_libdir"; then + break + fi + output=$output_objdir/${outputname}i + # Replace all uninstalled libtool libraries with the installed ones + newdependency_libs= + for deplib in $dependency_libs; do + case $deplib in + *.la) + func_basename "$deplib" + name=$func_basename_result + func_resolve_sysroot "$deplib" + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` + test -z "$libdir" && \ + func_fatal_error "'$deplib' is not a valid libtool archive" + func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" + ;; + -L*) + func_stripname -L '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -L$func_replace_sysroot_result" + ;; + -R*) + func_stripname -R '' "$deplib" + func_replace_sysroot "$func_stripname_result" + func_append newdependency_libs " -R$func_replace_sysroot_result" + ;; + *) func_append newdependency_libs " $deplib" ;; + esac + done + dependency_libs=$newdependency_libs + newdlfiles= + + for lib in $dlfiles; do + case $lib in + *.la) + func_basename "$lib" + name=$func_basename_result + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "'$lib' is not a valid libtool archive" + func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" + ;; + *) func_append newdlfiles " $lib" ;; + esac + done + dlfiles=$newdlfiles + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + *.la) + # Only pass preopened files to the pseudo-archive (for + # eventual linking with the app. that links it) if we + # didn't already link the preopened objects directly into + # the library: + func_basename "$lib" + name=$func_basename_result + eval libdir=`$SED -n -e 's/^libdir=\(.*\)$/\1/p' $lib` + test -z "$libdir" && \ + func_fatal_error "'$lib' is not a valid libtool archive" + func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" + ;; + esac + done + dlprefiles=$newdlprefiles + else + newdlfiles= + for lib in $dlfiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlfiles " $abs" + done + dlfiles=$newdlfiles + newdlprefiles= + for lib in $dlprefiles; do + case $lib in + [\\/]* | [A-Za-z]:[\\/]*) abs=$lib ;; + *) abs=`pwd`"/$lib" ;; + esac + func_append newdlprefiles " $abs" + done + dlprefiles=$newdlprefiles + fi + $RM $output + # place dlname in correct position for cygwin + # In fact, it would be nice if we could use this code for all target + # systems that can't hard-code library paths into their executables + # and that have no shared library path variable independent of PATH, + # but it turns out we can't easily determine that from inspecting + # libtool variables, so we have to hard-code the OSs to which it + # applies here; at the moment, that means platforms that use the PE + # object format with DLL files. See the long comment at the top of + # tests/bindir.at for full details. + tdlname=$dlname + case $host,$output,$installed,$module,$dlname in + *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) + # If a -bindir argument was supplied, place the dll there. + if test -n "$bindir"; then + func_relative_path "$install_libdir" "$bindir" + tdlname=$func_relative_path_result/$dlname + else + # Otherwise fall back on heuristic. + tdlname=../bin/$dlname + fi + ;; + esac + $ECHO > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM (GNU $PACKAGE) $VERSION +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$tdlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Linker flags that cannot go in dependency_libs. +inherited_linker_flags='$new_inherited_linker_flags' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Names of additional weak libraries provided by this library +weak_library_names='$weak_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Should we warn about portability when linking against -modules? +shouldnotlink=$module + +# Files to dlopen/dlpreopen +dlopen='$dlfiles' +dlpreopen='$dlprefiles' + +# Directory that this library needs to be installed in: +libdir='$install_libdir'" + if test no,yes = "$installed,$need_relink"; then + $ECHO >> $output "\ +relink_command=\"$relink_command\"" + fi + done + } + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' + ;; + esac + exit $EXIT_SUCCESS +} + +if test link = "$opt_mode" || test relink = "$opt_mode"; then + func_mode_link ${1+"$@"} +fi + + +# func_mode_uninstall arg... +func_mode_uninstall () +{ + $debug_cmd + + RM=$nonopt + files= + rmforce=false + exit_status=0 + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic=$magic + + for arg + do + case $arg in + -f) func_append RM " $arg"; rmforce=: ;; + -*) func_append RM " $arg" ;; + *) func_append files " $arg" ;; + esac + done + + test -z "$RM" && \ + func_fatal_help "you must specify an RM program" + + rmdirs= + + for file in $files; do + func_dirname "$file" "" "." + dir=$func_dirname_result + if test . = "$dir"; then + odir=$objdir + else + odir=$dir/$objdir + fi + func_basename "$file" + name=$func_basename_result + test uninstall = "$opt_mode" && odir=$dir + + # Remember odir for removal later, being careful to avoid duplicates + if test clean = "$opt_mode"; then + case " $rmdirs " in + *" $odir "*) ;; + *) func_append rmdirs " $odir" ;; + esac + fi + + # Don't error if the file doesn't exist and rm -f was used. + if { test -L "$file"; } >/dev/null 2>&1 || + { test -h "$file"; } >/dev/null 2>&1 || + test -f "$file"; then + : + elif test -d "$file"; then + exit_status=1 + continue + elif $rmforce; then + continue + fi + + rmfiles=$file + + case $name in + *.la) + # Possibly a libtool archive, so verify it. + if func_lalib_p "$file"; then + func_source $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + func_append rmfiles " $odir/$n" + done + test -n "$old_library" && func_append rmfiles " $odir/$old_library" + + case $opt_mode in + clean) + case " $library_names " in + *" $dlname "*) ;; + *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; + esac + test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" + ;; + uninstall) + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + func_execute_cmds "$postuninstall_cmds" '$rmforce || exit_status=1' + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + func_execute_cmds "$old_postuninstall_cmds" '$rmforce || exit_status=1' + fi + # FIXME: should reinstall the best remaining shared library. + ;; + esac + fi + ;; + + *.lo) + # Possibly a libtool object, so verify it. + if func_lalib_p "$file"; then + + # Read the .lo file + func_source $dir/$name + + # Add PIC object to the list of files to remove. + if test -n "$pic_object" && test none != "$pic_object"; then + func_append rmfiles " $dir/$pic_object" + fi + + # Add non-PIC object to the list of files to remove. + if test -n "$non_pic_object" && test none != "$non_pic_object"; then + func_append rmfiles " $dir/$non_pic_object" + fi + fi + ;; + + *) + if test clean = "$opt_mode"; then + noexename=$name + case $file in + *.exe) + func_stripname '' '.exe' "$file" + file=$func_stripname_result + func_stripname '' '.exe' "$name" + noexename=$func_stripname_result + # $file with .exe has already been added to rmfiles, + # add $file without .exe + func_append rmfiles " $file" + ;; + esac + # Do a test to see if this is a libtool program. + if func_ltwrapper_p "$file"; then + if func_ltwrapper_executable_p "$file"; then + func_ltwrapper_scriptname "$file" + relink_command= + func_source $func_ltwrapper_scriptname_result + func_append rmfiles " $func_ltwrapper_scriptname_result" + else + relink_command= + func_source $dir/$noexename + fi + + # note $name still contains .exe if it was in $file originally + # as does the version of $file that was added into $rmfiles + func_append rmfiles " $odir/$name $odir/${name}S.$objext" + if test yes = "$fast_install" && test -n "$relink_command"; then + func_append rmfiles " $odir/lt-$name" + fi + if test "X$noexename" != "X$name"; then + func_append rmfiles " $odir/lt-$noexename.c" + fi + fi + fi + ;; + esac + func_show_eval "$RM $rmfiles" 'exit_status=1' + done + + # Try to remove the $objdir's in the directories where we deleted files + for dir in $rmdirs; do + if test -d "$dir"; then + func_show_eval "rmdir $dir >/dev/null 2>&1" + fi + done + + exit $exit_status +} + +if test uninstall = "$opt_mode" || test clean = "$opt_mode"; then + func_mode_uninstall ${1+"$@"} +fi + +test -z "$opt_mode" && { + help=$generic_help + func_fatal_help "you must specify a MODE" +} + +test -z "$exec_cmd" && \ + func_fatal_help "invalid operation mode '$opt_mode'" + +if test -n "$exec_cmd"; then + eval exec "$exec_cmd" + exit $EXIT_FAILURE +fi + +exit $exit_status + + +# The TAGs below are defined such that we never get into a situation +# where we disable both kinds of libraries. Given conflicting +# choices, we go for a static library, that is the most portable, +# since we can't tell whether shared libraries were disabled because +# the user asked for that or because the platform doesn't support +# them. This is particularly important on AIX, because we don't +# support having both static and shared libraries enabled at the same +# time on that platform, so we default to a shared-only configuration. +# If a disable-shared tag is given, we'll fallback to a static-only +# configuration. But we'll never go from static-only to shared-only. + +# ### BEGIN LIBTOOL TAG CONFIG: disable-shared +build_libtool_libs=no +build_old_libs=yes +# ### END LIBTOOL TAG CONFIG: disable-shared + +# ### BEGIN LIBTOOL TAG CONFIG: disable-static +build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` +# ### END LIBTOOL TAG CONFIG: disable-static + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: diff --git a/config/ltoptions.m4 b/config/ltoptions.m4 new file mode 100644 index 0000000..94b0829 --- /dev/null +++ b/config/ltoptions.m4 @@ -0,0 +1,437 @@ +# Helper functions for option handling. -*- Autoconf -*- +# +# Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software +# Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 8 ltoptions.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) + + +# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) +# ------------------------------------------ +m4_define([_LT_MANGLE_OPTION], +[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) + + +# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) +# --------------------------------------- +# Set option OPTION-NAME for macro MACRO-NAME, and if there is a +# matching handler defined, dispatch to it. Other OPTION-NAMEs are +# saved as a flag. +m4_define([_LT_SET_OPTION], +[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl +m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), + _LT_MANGLE_DEFUN([$1], [$2]), + [m4_warning([Unknown $1 option '$2'])])[]dnl +]) + + +# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) +# ------------------------------------------------------------ +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +m4_define([_LT_IF_OPTION], +[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) + + +# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) +# ------------------------------------------------------- +# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME +# are set. +m4_define([_LT_UNLESS_OPTIONS], +[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), + [m4_define([$0_found])])])[]dnl +m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 +])[]dnl +]) + + +# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) +# ---------------------------------------- +# OPTION-LIST is a space-separated list of Libtool options associated +# with MACRO-NAME. If any OPTION has a matching handler declared with +# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about +# the unknown option and exit. +m4_defun([_LT_SET_OPTIONS], +[# Set options +m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), + [_LT_SET_OPTION([$1], _LT_Option)]) + +m4_if([$1],[LT_INIT],[ + dnl + dnl Simply set some default values (i.e off) if boolean options were not + dnl specified: + _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no + ]) + _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no + ]) + dnl + dnl If no reference was made to various pairs of opposing options, then + dnl we run the default mode handler for the pair. For example, if neither + dnl 'shared' nor 'disable-shared' was passed, we enable building of shared + dnl archives by default: + _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) + _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) + _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], + [_LT_ENABLE_FAST_INSTALL]) + _LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4], + [_LT_WITH_AIX_SONAME([aix])]) + ]) +])# _LT_SET_OPTIONS + + +## --------------------------------- ## +## Macros to handle LT_INIT options. ## +## --------------------------------- ## + +# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) +# ----------------------------------------- +m4_define([_LT_MANGLE_DEFUN], +[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) + + +# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) +# ----------------------------------------------- +m4_define([LT_OPTION_DEFINE], +[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl +])# LT_OPTION_DEFINE + + +# dlopen +# ------ +LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes +]) + +AU_DEFUN([AC_LIBTOOL_DLOPEN], +[_LT_SET_OPTION([LT_INIT], [dlopen]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the 'dlopen' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) + + +# win32-dll +# --------- +# Declare package support for building win32 dll's. +LT_OPTION_DEFINE([LT_INIT], [win32-dll], +[enable_win32_dll=yes + +case $host in +*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + ;; +esac + +test -z "$AS" && AS=as +_LT_DECL([], [AS], [1], [Assembler program])dnl + +test -z "$DLLTOOL" && DLLTOOL=dlltool +_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl + +test -z "$OBJDUMP" && OBJDUMP=objdump +_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl +])# win32-dll + +AU_DEFUN([AC_LIBTOOL_WIN32_DLL], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +_LT_SET_OPTION([LT_INIT], [win32-dll]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the 'win32-dll' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) + + +# _LT_ENABLE_SHARED([DEFAULT]) +# ---------------------------- +# implement the --enable-shared flag, and supports the 'shared' and +# 'disable-shared' LT_INIT options. +# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. +m4_define([_LT_ENABLE_SHARED], +[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([shared], + [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], + [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], + [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. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) + + _LT_DECL([build_libtool_libs], [enable_shared], [0], + [Whether or not to build shared libraries]) +])# _LT_ENABLE_SHARED + +LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) +]) + +AC_DEFUN([AC_DISABLE_SHARED], +[_LT_SET_OPTION([LT_INIT], [disable-shared]) +]) + +AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_SHARED], []) +dnl AC_DEFUN([AM_DISABLE_SHARED], []) + + + +# _LT_ENABLE_STATIC([DEFAULT]) +# ---------------------------- +# implement the --enable-static flag, and support the 'static' and +# 'disable-static' LT_INIT options. +# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. +m4_define([_LT_ENABLE_STATIC], +[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([static], + [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], + [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], + [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. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [enable_static=]_LT_ENABLE_STATIC_DEFAULT) + + _LT_DECL([build_old_libs], [enable_static], [0], + [Whether or not to build static libraries]) +])# _LT_ENABLE_STATIC + +LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) + +# Old names: +AC_DEFUN([AC_ENABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) +]) + +AC_DEFUN([AC_DISABLE_STATIC], +[_LT_SET_OPTION([LT_INIT], [disable-static]) +]) + +AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AM_ENABLE_STATIC], []) +dnl AC_DEFUN([AM_DISABLE_STATIC], []) + + + +# _LT_ENABLE_FAST_INSTALL([DEFAULT]) +# ---------------------------------- +# implement the --enable-fast-install flag, and support the 'fast-install' +# and 'disable-fast-install' LT_INIT options. +# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'. +m4_define([_LT_ENABLE_FAST_INSTALL], +[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl +AC_ARG_ENABLE([fast-install], + [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], + [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], + [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. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) + +_LT_DECL([fast_install], [enable_fast_install], [0], + [Whether or not to optimize for fast installation])dnl +])# _LT_ENABLE_FAST_INSTALL + +LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) +LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) + +# Old names: +AU_DEFUN([AC_ENABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the 'fast-install' option into LT_INIT's first parameter.]) +]) + +AU_DEFUN([AC_DISABLE_FAST_INSTALL], +[_LT_SET_OPTION([LT_INIT], [disable-fast-install]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you put +the 'disable-fast-install' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) +dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) + + +# _LT_WITH_AIX_SONAME([DEFAULT]) +# ---------------------------------- +# implement the --with-aix-soname flag, and support the `aix-soname=aix' +# and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT +# is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'. +m4_define([_LT_WITH_AIX_SONAME], +[m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl +shared_archive_member_spec= +case $host,$enable_shared in +power*-*-aix[[5-9]]*,yes) + AC_MSG_CHECKING([which variant of shared library versioning to provide]) + AC_ARG_WITH([aix-soname], + [AS_HELP_STRING([--with-aix-soname=aix|svr4|both], + [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])], + [case $withval in + aix|svr4|both) + ;; + *) + AC_MSG_ERROR([Unknown argument to --with-aix-soname]) + ;; + esac + lt_cv_with_aix_soname=$with_aix_soname], + [AC_CACHE_VAL([lt_cv_with_aix_soname], + [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT) + with_aix_soname=$lt_cv_with_aix_soname]) + AC_MSG_RESULT([$with_aix_soname]) + if test aix != "$with_aix_soname"; then + # For the AIX way of multilib, we name the shared archive member + # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', + # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. + # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, + # the AIX toolchain works better with OBJECT_MODE set (default 32). + if test 64 = "${OBJECT_MODE-32}"; then + shared_archive_member_spec=shr_64 + else + shared_archive_member_spec=shr + fi + fi + ;; +*) + with_aix_soname=aix + ;; +esac + +_LT_DECL([], [shared_archive_member_spec], [0], + [Shared archive member basename, for filename based shared library versioning on AIX])dnl +])# _LT_WITH_AIX_SONAME + +LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])]) +LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])]) +LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])]) + + +# _LT_WITH_PIC([MODE]) +# -------------------- +# implement the --with-pic flag, and support the 'pic-only' and 'no-pic' +# LT_INIT options. +# MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'. +m4_define([_LT_WITH_PIC], +[AC_ARG_WITH([pic], + [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], + [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], + [lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for lt_pkg in $withval; do + IFS=$lt_save_ifs + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [pic_mode=m4_default([$1], [default])]) + +_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl +])# _LT_WITH_PIC + +LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) +LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) + +# Old name: +AU_DEFUN([AC_LIBTOOL_PICMODE], +[_LT_SET_OPTION([LT_INIT], [pic-only]) +AC_DIAGNOSE([obsolete], +[$0: Remove this warning and the call to _LT_SET_OPTION when you +put the 'pic-only' option into LT_INIT's first parameter.]) +]) + +dnl aclocal-1.4 backwards compatibility: +dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) + +## ----------------- ## +## LTDL_INIT Options ## +## ----------------- ## + +m4_define([_LTDL_MODE], []) +LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], + [m4_define([_LTDL_MODE], [nonrecursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [recursive], + [m4_define([_LTDL_MODE], [recursive])]) +LT_OPTION_DEFINE([LTDL_INIT], [subproject], + [m4_define([_LTDL_MODE], [subproject])]) + +m4_define([_LTDL_TYPE], []) +LT_OPTION_DEFINE([LTDL_INIT], [installable], + [m4_define([_LTDL_TYPE], [installable])]) +LT_OPTION_DEFINE([LTDL_INIT], [convenience], + [m4_define([_LTDL_TYPE], [convenience])]) diff --git a/config/ltsugar.m4 b/config/ltsugar.m4 new file mode 100644 index 0000000..48bc934 --- /dev/null +++ b/config/ltsugar.m4 @@ -0,0 +1,124 @@ +# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- +# +# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software +# Foundation, Inc. +# Written by Gary V. Vaughan, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 6 ltsugar.m4 + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) + + +# lt_join(SEP, ARG1, [ARG2...]) +# ----------------------------- +# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their +# associated separator. +# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier +# versions in m4sugar had bugs. +m4_define([lt_join], +[m4_if([$#], [1], [], + [$#], [2], [[$2]], + [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) +m4_define([_lt_join], +[m4_if([$#$2], [2], [], + [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) + + +# lt_car(LIST) +# lt_cdr(LIST) +# ------------ +# Manipulate m4 lists. +# These macros are necessary as long as will still need to support +# Autoconf-2.59, which quotes differently. +m4_define([lt_car], [[$1]]) +m4_define([lt_cdr], +[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], + [$#], 1, [], + [m4_dquote(m4_shift($@))])]) +m4_define([lt_unquote], $1) + + +# lt_append(MACRO-NAME, STRING, [SEPARATOR]) +# ------------------------------------------ +# Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'. +# Note that neither SEPARATOR nor STRING are expanded; they are appended +# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). +# No SEPARATOR is output if MACRO-NAME was previously undefined (different +# than defined and empty). +# +# This macro is needed until we can rely on Autoconf 2.62, since earlier +# versions of m4sugar mistakenly expanded SEPARATOR but not STRING. +m4_define([lt_append], +[m4_define([$1], + m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) + + + +# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) +# ---------------------------------------------------------- +# Produce a SEP delimited list of all paired combinations of elements of +# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list +# has the form PREFIXmINFIXSUFFIXn. +# Needed until we can rely on m4_combine added in Autoconf 2.62. +m4_define([lt_combine], +[m4_if(m4_eval([$# > 3]), [1], + [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl +[[m4_foreach([_Lt_prefix], [$2], + [m4_foreach([_Lt_suffix], + ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, + [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) + + +# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) +# ----------------------------------------------------------------------- +# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited +# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. +m4_define([lt_if_append_uniq], +[m4_ifdef([$1], + [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], + [lt_append([$1], [$2], [$3])$4], + [$5])], + [lt_append([$1], [$2], [$3])$4])]) + + +# lt_dict_add(DICT, KEY, VALUE) +# ----------------------------- +m4_define([lt_dict_add], +[m4_define([$1($2)], [$3])]) + + +# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) +# -------------------------------------------- +m4_define([lt_dict_add_subkey], +[m4_define([$1($2:$3)], [$4])]) + + +# lt_dict_fetch(DICT, KEY, [SUBKEY]) +# ---------------------------------- +m4_define([lt_dict_fetch], +[m4_ifval([$3], + m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), + m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) + + +# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) +# ----------------------------------------------------------------- +m4_define([lt_if_dict_fetch], +[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], + [$5], + [$6])]) + + +# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) +# -------------------------------------------------------------- +m4_define([lt_dict_filter], +[m4_if([$5], [], [], + [lt_join(m4_quote(m4_default([$4], [[, ]])), + lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), + [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl +]) diff --git a/config/ltversion.m4 b/config/ltversion.m4 new file mode 100644 index 0000000..fa04b52 --- /dev/null +++ b/config/ltversion.m4 @@ -0,0 +1,23 @@ +# ltversion.m4 -- version numbers -*- Autoconf -*- +# +# Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc. +# Written by Scott James Remnant, 2004 +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# @configure_input@ + +# serial 4179 ltversion.m4 +# This file is part of GNU Libtool + +m4_define([LT_PACKAGE_VERSION], [2.4.6]) +m4_define([LT_PACKAGE_REVISION], [2.4.6]) + +AC_DEFUN([LTVERSION_VERSION], +[macro_version='2.4.6' +macro_revision='2.4.6' +_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) +_LT_DECL(, macro_revision, 0) +]) diff --git a/config/lt~obsolete.m4 b/config/lt~obsolete.m4 new file mode 100644 index 0000000..c6b26f8 --- /dev/null +++ b/config/lt~obsolete.m4 @@ -0,0 +1,99 @@ +# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- +# +# Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software +# Foundation, Inc. +# Written by Scott James Remnant, 2004. +# +# This file is free software; the Free Software Foundation gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. + +# serial 5 lt~obsolete.m4 + +# These exist entirely to fool aclocal when bootstrapping libtool. +# +# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN), +# which have later been changed to m4_define as they aren't part of the +# exported API, or moved to Autoconf or Automake where they belong. +# +# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN +# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us +# using a macro with the same name in our local m4/libtool.m4 it'll +# pull the old libtool.m4 in (it doesn't see our shiny new m4_define +# and doesn't know about Autoconf macros at all.) +# +# So we provide this file, which has a silly filename so it's always +# included after everything else. This provides aclocal with the +# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything +# because those macros already exist, or will be overwritten later. +# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. +# +# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. +# Yes, that means every name once taken will need to remain here until +# we give up compatibility with versions before 1.7, at which point +# we need to keep only those names which we still refer to. + +# This is to help aclocal find these macros, as it can't see m4_define. +AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) + +m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) +m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) +m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) +m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) +m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) +m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) +m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) +m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) +m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) +m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) +m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) +m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) +m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) +m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) +m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) +m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) +m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) +m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) +m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) +m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) +m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) +m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) +m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) +m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) +m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) +m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) +m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) +m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) +m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) +m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) +m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) +m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) +m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) +m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) +m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) +m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) +m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) +m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) +m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) +m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) +m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) +m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) +m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) +m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) +m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) +m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) +m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) +m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) +m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) +m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) +m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) +m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) +m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) +m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) +m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) diff --git a/config/missing b/config/missing new file mode 100755 index 0000000..625aeb1 --- /dev/null +++ b/config/missing @@ -0,0 +1,215 @@ +#! /bin/sh +# Common wrapper for a few potentially missing GNU programs. + +scriptversion=2018-03-07.03; # UTC + +# Copyright (C) 1996-2018 Free Software Foundation, Inc. +# Originally written by Fran,cois 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, see <https://www.gnu.org/licenses/>. + +# 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. + +if test $# -eq 0; then + echo 1>&2 "Try '$0 --help' for more information" + exit 1 +fi + +case $1 in + + --is-lightweight) + # Used by our autoconf macros to check whether the available missing + # script is modern enough. + exit 0 + ;; + + --run) + # Back-compat with the calling convention used by older automake. + shift + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due +to PROGRAM being missing or too old. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + +Supported PROGRAM values: + aclocal autoconf autoheader autom4te automake makeinfo + bison yacc flex lex help2man + +Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and +'g' are ignored when checking the name. + +Send bug reports to <bug-automake@gnu.org>." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: unknown '$1' option" + echo 1>&2 "Try '$0 --help' for more information" + exit 1 + ;; + +esac + +# Run the given program, remember its exit status. +"$@"; st=$? + +# If it succeeded, we are done. +test $st -eq 0 && exit 0 + +# Also exit now if we it failed (or wasn't found), and '--version' was +# passed; such an option is passed most likely to detect whether the +# program is present and works. +case $2 in --version|--help) exit $st;; esac + +# Exit code 63 means version mismatch. This often happens when the user +# tries to use an ancient version of a tool on a file that requires a +# minimum version. +if test $st -eq 63; then + msg="probably too old" +elif test $st -eq 127; then + # Program was missing. + msg="missing on your system" +else + # Program was found and executed, but failed. Give up. + exit $st +fi + +perl_URL=https://www.perl.org/ +flex_URL=https://github.com/westes/flex +gnu_software_URL=https://www.gnu.org/software + +program_details () +{ + case $1 in + aclocal|automake) + echo "The '$1' program is part of the GNU Automake package:" + echo "<$gnu_software_URL/automake>" + echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/autoconf>" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + autoconf|autom4te|autoheader) + echo "The '$1' program is part of the GNU Autoconf package:" + echo "<$gnu_software_URL/autoconf/>" + echo "It also requires GNU m4 and Perl in order to run:" + echo "<$gnu_software_URL/m4/>" + echo "<$perl_URL>" + ;; + esac +} + +give_advice () +{ + # Normalize program name to check for. + normalized_program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + + printf '%s\n' "'$1' is $msg." + + configure_deps="'configure.ac' or m4 files included by 'configure.ac'" + case $normalized_program in + autoconf*) + echo "You should only need it if you modified 'configure.ac'," + echo "or m4 files included by it." + program_details 'autoconf' + ;; + autoheader*) + echo "You should only need it if you modified 'acconfig.h' or" + echo "$configure_deps." + program_details 'autoheader' + ;; + automake*) + echo "You should only need it if you modified 'Makefile.am' or" + echo "$configure_deps." + program_details 'automake' + ;; + aclocal*) + echo "You should only need it if you modified 'acinclude.m4' or" + echo "$configure_deps." + program_details 'aclocal' + ;; + autom4te*) + echo "You might have modified some maintainer files that require" + echo "the 'autom4te' program to be rebuilt." + program_details 'autom4te' + ;; + bison*|yacc*) + echo "You should only need it if you modified a '.y' file." + echo "You may want to install the GNU Bison package:" + echo "<$gnu_software_URL/bison/>" + ;; + lex*|flex*) + echo "You should only need it if you modified a '.l' file." + echo "You may want to install the Fast Lexical Analyzer package:" + echo "<$flex_URL>" + ;; + help2man*) + echo "You should only need it if you modified a dependency" \ + "of a man page." + echo "You may want to install the GNU Help2man package:" + echo "<$gnu_software_URL/help2man/>" + ;; + makeinfo*) + echo "You should only need it if you modified a '.texi' file, or" + echo "any other file indirectly affecting the aspect of the manual." + echo "You might want to install the Texinfo package:" + echo "<$gnu_software_URL/texinfo/>" + echo "The spurious makeinfo call might also be the consequence of" + echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" + echo "want to install GNU make:" + echo "<$gnu_software_URL/make/>" + ;; + *) + echo "You might have modified some files without having the proper" + echo "tools for further handling them. Check the 'README' file, it" + echo "often tells you about the needed prerequisites for installing" + echo "this package. You may also peek at any GNU archive site, in" + echo "case some other package contains this missing '$1' program." + ;; + esac +} + +give_advice "$1" | sed -e '1s/^/WARNING: /' \ + -e '2,$s/^/ /' >&2 + +# Propagate the correct exit status (expected to be 127 for a program +# not found, 63 for a program that failed due to version mismatch). +exit $st + +# Local variables: +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/config/mk-shdefs.in b/config/mk-shdefs.in new file mode 100644 index 0000000..68aed2a --- /dev/null +++ b/config/mk-shdefs.in @@ -0,0 +1,138 @@ +#! @CONFIG_SHELL@ +# -*- Mode: shell-script -*- + +## mk-shdefs.in - extract the substitutions in config.status into +## environment variables. +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see <http://www.gnu.org/licenses/>. + +die() { + echo "$prog fatal error: $*" + kill -TERM $progpid + exit 1 +} >&2 + +init() { + prog=`basename $1 .sh` + progpid=$$ + + if (exec 2> /dev/null ; unset CDPATH) + then unset CDPATH + elif test ${#CDPATH} -gt 0 + then CDPATH= + fi + + SED='@SED@' + AWK='@AWK@' + GREP='@GREP@' + EGREP='@EGREP@' + target=`basename $2` + builddir=`dirname $2` + builddir=`cd $builddir >/dev/null && pwd` + srcdir=`dirname $1` + srcdir=`cd $srcdir >/dev/null && pwd` + + cd ${builddir} || die no builddir + + # top_builddir may be relative to the build directory that corresponds + # to the source directory for this file. Make it absolute + # + top_builddir=`cd @top_builddir@ >/dev/null && pwd` + top_srcdir=` + cd ${builddir} >/dev/null && cd @top_srcdir@ >/dev/null && pwd` + + rm -f ${target} + exec 3> shdef-temp.in || die cannot create output + cd .. +} + +mk_config() { + cat >&3 <<- _EOF_ + prefix='@prefix@' + exec_prefix="@exec_prefix@" + PACKAGE_TARNAME='@PACKAGE_TARNAME@' + _EOF_ + + # Skip the stuff we force to be first + # + skip_list='top_srcdir|top_builddir|prefix|exec_prefix|PACKAGE_TARNAME' + + # skip the autoconf/automake internal names + # + skip_list=${skip_list}"|a[mc]_.*|.*_TRUE|.*_FALSE|HAVE_.*|AM*" + + # These must be in the correct order. Ensure it and don't do 'em twice + # + eval_fmt='eval "%s=\\"@%s@\\""\n' + for v in datarootdir mandir localedir infodir docdir datadir \ + libdir libexecdir sbindir bindir \ + includedir localstatedir sharedstatedir sysconfdir oldincludedir + do printf "${eval_fmt}" $v $v + skip_list=${skip_list}"|$v" + done >&3 + + for f in `${GREP} '^S\["' config.status` + do + v=`echo "$f" | ${SED} 's/".=.*//;s/[SD]\["//'` + x=`echo "$v" | ${EGREP} "^($skip_list)\$"` + test "X$x" = X || continue + + case "$f" in + *'$('* ) : ;; # no make file only substitutions + *'missing --run '* ) : ;; # no bootstrap tools + S*\$* ) printf "${eval_fmt}" $v $v ;; + S* ) echo "$v='@$v@'" ;; + esac + done >&3 + + exec 3>&- +} + +configure() { + cd config + + ../config.status --file shdef-temp + { + cmd='`set -o | '${AWK}" '/^allexport/ {print \$2}'"\` + cat <<- _EOF_ + #! `which echo` this-file-should-be-sourced,-not-executed + # -*- Mode: shell-script -*- + + case "$cmd" in + on ) cleara=: ;; + * ) cleara='set +a' ; set -a ;; + esac + + top_srcdir="$top_srcdir" + top_builddir="$top_builddir" + _EOF_ + + cat shdef-temp + echo 'eval $cleara' + } > ${target} + + rm -f shdef-temp* +} + +set -x +exec 9>&2 +tmp=$(mktemp --suffix=.tdir -d /tmp/shdefs-XXXXXXXXX) +exec 2>> $tmp/mk-shdef.log +init $0 $1 +mk_config +configure +exec 2>&9 9>&- diff --git a/config/onceonly.m4 b/config/onceonly.m4 new file mode 100644 index 0000000..5ab3dd7 --- /dev/null +++ b/config/onceonly.m4 @@ -0,0 +1,104 @@ +# onceonly.m4 serial 9 +dnl Copyright (C) 2002-2003, 2005-2006, 2008-2018 Free Software Foundation, +dnl Inc. +dnl +dnl This file is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3 of the License, or +dnl (at your option) any later version. +dnl +dnl This file is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this file. If not, see <https://www.gnu.org/licenses/>. +dnl +dnl As a special exception to the GNU General Public License, +dnl this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl This file defines some "once only" variants of standard autoconf macros. +dnl AC_CHECK_HEADERS_ONCE like AC_CHECK_HEADERS +dnl AC_CHECK_FUNCS_ONCE like AC_CHECK_FUNCS +dnl AC_CHECK_DECLS_ONCE like AC_CHECK_DECLS +dnl AC_REQUIRE([AC_FUNC_STRCOLL]) like AC_FUNC_STRCOLL +dnl The advantage is that the check for each of the headers/functions/decls +dnl will be put only once into the 'configure' file. It keeps the size of +dnl the 'configure' file down, and avoids redundant output when 'configure' +dnl is run. +dnl The drawback is that the checks cannot be conditionalized. If you write +dnl if some_condition; then gl_CHECK_HEADERS(stdlib.h); fi +dnl inside an AC_DEFUNed function, the gl_CHECK_HEADERS macro call expands to +dnl empty, and the check will be inserted before the body of the AC_DEFUNed +dnl function. + +dnl The original code implemented AC_CHECK_HEADERS_ONCE and AC_CHECK_FUNCS_ONCE +dnl in terms of AC_DEFUN and AC_REQUIRE. This implementation uses diversions to +dnl named sections DEFAULTS and INIT_PREPARE in order to check all requested +dnl headers at once, thus reducing the size of 'configure'. It is known to work +dnl with autoconf 2.57..2.62 at least . The size reduction is ca. 9%. + +dnl Autoconf version 2.59 plus gnulib is required; this file is not needed +dnl with Autoconf 2.60 or greater. But note that autoconf's implementation of +dnl AC_CHECK_DECLS_ONCE expects a comma-separated list of symbols as first +dnl argument! +AC_PREREQ([2.59]) + +# AC_CHECK_HEADERS_ONCE(HEADER1 HEADER2 ...) is a once-only variant of +# AC_CHECK_HEADERS(HEADER1 HEADER2 ...). +AC_DEFUN([AC_CHECK_HEADERS_ONCE], [ + : + m4_foreach_w([gl_HEADER_NAME], [$1], [ + AC_DEFUN([gl_CHECK_HEADER_]m4_quote(m4_translit(gl_HEADER_NAME, + [./-], [___])), [ + m4_divert_text([INIT_PREPARE], + [gl_header_list="$gl_header_list gl_HEADER_NAME"]) + gl_HEADERS_EXPANSION + AH_TEMPLATE(AS_TR_CPP([HAVE_]m4_defn([gl_HEADER_NAME])), + [Define to 1 if you have the <]m4_defn([gl_HEADER_NAME])[> header file.]) + ]) + AC_REQUIRE([gl_CHECK_HEADER_]m4_quote(m4_translit(gl_HEADER_NAME, + [./-], [___]))) + ]) +]) +m4_define([gl_HEADERS_EXPANSION], [ + m4_divert_text([DEFAULTS], [gl_header_list=]) + AC_CHECK_HEADERS([$gl_header_list]) + m4_define([gl_HEADERS_EXPANSION], []) +]) + +# AC_CHECK_FUNCS_ONCE(FUNC1 FUNC2 ...) is a once-only variant of +# AC_CHECK_FUNCS(FUNC1 FUNC2 ...). +AC_DEFUN([AC_CHECK_FUNCS_ONCE], [ + : + m4_foreach_w([gl_FUNC_NAME], [$1], [ + AC_DEFUN([gl_CHECK_FUNC_]m4_defn([gl_FUNC_NAME]), [ + m4_divert_text([INIT_PREPARE], + [gl_func_list="$gl_func_list gl_FUNC_NAME"]) + gl_FUNCS_EXPANSION + AH_TEMPLATE(AS_TR_CPP([HAVE_]m4_defn([gl_FUNC_NAME])), + [Define to 1 if you have the ']m4_defn([gl_FUNC_NAME])[' function.]) + ]) + AC_REQUIRE([gl_CHECK_FUNC_]m4_defn([gl_FUNC_NAME])) + ]) +]) +m4_define([gl_FUNCS_EXPANSION], [ + m4_divert_text([DEFAULTS], [gl_func_list=]) + AC_CHECK_FUNCS([$gl_func_list]) + m4_define([gl_FUNCS_EXPANSION], []) +]) + +# AC_CHECK_DECLS_ONCE(DECL1 DECL2 ...) is a once-only variant of +# AC_CHECK_DECLS(DECL1, DECL2, ...). +AC_DEFUN([AC_CHECK_DECLS_ONCE], [ + : + m4_foreach_w([gl_DECL_NAME], [$1], [ + AC_DEFUN([gl_CHECK_DECL_]m4_defn([gl_DECL_NAME]), [ + AC_CHECK_DECLS(m4_defn([gl_DECL_NAME])) + ]) + AC_REQUIRE([gl_CHECK_DECL_]m4_defn([gl_DECL_NAME])) + ]) +]) diff --git a/config/pkg.m4 b/config/pkg.m4 new file mode 100644 index 0000000..82bea96 --- /dev/null +++ b/config/pkg.m4 @@ -0,0 +1,275 @@ +dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +dnl serial 11 (pkg-config-0.29.1) +dnl +dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>. +dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com> +dnl +dnl This program is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 2 of the License, or +dnl (at your option) any later version. +dnl +dnl This program is distributed in the hope that it will be useful, but +dnl WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with this program; if not, write to the Free Software +dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +dnl 02111-1307, USA. +dnl +dnl As a special exception to the GNU General Public License, if you +dnl distribute this file as part of a program that contains a +dnl configuration script generated by Autoconf, you may include it under +dnl the same distribution terms that you use for the rest of that +dnl program. + +dnl PKG_PREREQ(MIN-VERSION) +dnl ----------------------- +dnl Since: 0.29 +dnl +dnl Verify that the version of the pkg-config macros are at least +dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's +dnl installed version of pkg-config, this checks the developer's version +dnl of pkg.m4 when generating configure. +dnl +dnl To ensure that this macro is defined, also add: +dnl m4_ifndef([PKG_PREREQ], +dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])]) +dnl +dnl See the "Since" comment for each macro you use to see what version +dnl of the macros you require. +m4_defun([PKG_PREREQ], +[m4_define([PKG_MACROS_VERSION], [0.29.1]) +m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, + [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) +])dnl PKG_PREREQ + +dnl PKG_PROG_PKG_CONFIG([MIN-VERSION]) +dnl ---------------------------------- +dnl Since: 0.16 +dnl +dnl Search for the pkg-config tool and set the PKG_CONFIG variable to +dnl first found in the path. Checks that the version of pkg-config found +dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is +dnl used since that's the first version where most current features of +dnl pkg-config existed. +AC_DEFUN([PKG_PROG_PKG_CONFIG], +[m4_pattern_forbid([^_?PKG_[A-Z_]+$]) +m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) +m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) +AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) +AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) +AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=m4_default([$1], [0.9.0]) + AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + PKG_CONFIG="" + fi +fi[]dnl +])dnl PKG_PROG_PKG_CONFIG + +dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +dnl ------------------------------------------------------------------- +dnl Since: 0.18 +dnl +dnl Check to see whether a particular set of modules exists. Similar to +dnl PKG_CHECK_MODULES(), but does not set variables or print errors. +dnl +dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +dnl only at the first occurence in configure.ac, so if the first place +dnl it's called might be skipped (such as if it is within an "if", you +dnl have to call PKG_CHECK_EXISTS manually +AC_DEFUN([PKG_CHECK_EXISTS], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +if test -n "$PKG_CONFIG" && \ + AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then + m4_default([$2], [:]) +m4_ifvaln([$3], [else + $3])dnl +fi]) + +dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) +dnl --------------------------------------------- +dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting +dnl pkg_failed based on the result. +m4_define([_PKG_CONFIG], +[if test -n "$$1"; then + pkg_cv_[]$1="$$1" + elif test -n "$PKG_CONFIG"; then + PKG_CHECK_EXISTS([$3], + [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes ], + [pkg_failed=yes]) + else + pkg_failed=untried +fi[]dnl +])dnl _PKG_CONFIG + +dnl _PKG_SHORT_ERRORS_SUPPORTED +dnl --------------------------- +dnl Internal check to see if pkg-config supports short errors. +AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG]) +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi[]dnl +])dnl _PKG_SHORT_ERRORS_SUPPORTED + + +dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +dnl [ACTION-IF-NOT-FOUND]) +dnl -------------------------------------------------------------- +dnl Since: 0.4.0 +dnl +dnl Note that if there is a possibility the first call to +dnl PKG_CHECK_MODULES might not happen, you should be sure to include an +dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac +AC_DEFUN([PKG_CHECK_MODULES], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl +AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl + +pkg_failed=no +AC_MSG_CHECKING([for $1]) + +_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) +_PKG_CONFIG([$1][_LIBS], [libs], [$2]) + +m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS +and $1[]_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details.]) + +if test $pkg_failed = yes; then + AC_MSG_RESULT([no]) + _PKG_SHORT_ERRORS_SUPPORTED + if test $_pkg_short_errors_supported = yes; then + $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` + else + $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD + + m4_default([$4], [AC_MSG_ERROR( +[Package requirements ($2) were not met: + +$$1_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +_PKG_TEXT])[]dnl + ]) +elif test $pkg_failed = untried; then + AC_MSG_RESULT([no]) + m4_default([$4], [AC_MSG_FAILURE( +[The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +_PKG_TEXT + +To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl + ]) +else + $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS + $1[]_LIBS=$pkg_cv_[]$1[]_LIBS + AC_MSG_RESULT([yes]) + $3 +fi[]dnl +])dnl PKG_CHECK_MODULES + + +dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], +dnl [ACTION-IF-NOT-FOUND]) +dnl --------------------------------------------------------------------- +dnl Since: 0.29 +dnl +dnl Checks for existence of MODULES and gathers its build flags with +dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags +dnl and VARIABLE-PREFIX_LIBS from --libs. +dnl +dnl Note that if there is a possibility the first call to +dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to +dnl include an explicit call to PKG_PROG_PKG_CONFIG in your +dnl configure.ac. +AC_DEFUN([PKG_CHECK_MODULES_STATIC], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +_save_PKG_CONFIG=$PKG_CONFIG +PKG_CONFIG="$PKG_CONFIG --static" +PKG_CHECK_MODULES($@) +PKG_CONFIG=$_save_PKG_CONFIG[]dnl +])dnl PKG_CHECK_MODULES_STATIC + + +dnl PKG_INSTALLDIR([DIRECTORY]) +dnl ------------------------- +dnl Since: 0.27 +dnl +dnl Substitutes the variable pkgconfigdir as the location where a module +dnl should install pkg-config .pc files. By default the directory is +dnl $libdir/pkgconfig, but the default can be changed by passing +dnl DIRECTORY. The user can override through the --with-pkgconfigdir +dnl parameter. +AC_DEFUN([PKG_INSTALLDIR], +[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) +m4_pushdef([pkg_description], + [pkg-config installation directory @<:@]pkg_default[@:>@]) +AC_ARG_WITH([pkgconfigdir], + [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, + [with_pkgconfigdir=]pkg_default) +AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) +m4_popdef([pkg_default]) +m4_popdef([pkg_description]) +])dnl PKG_INSTALLDIR + + +dnl PKG_NOARCH_INSTALLDIR([DIRECTORY]) +dnl -------------------------------- +dnl Since: 0.27 +dnl +dnl Substitutes the variable noarch_pkgconfigdir as the location where a +dnl module should install arch-independent pkg-config .pc files. By +dnl default the directory is $datadir/pkgconfig, but the default can be +dnl changed by passing DIRECTORY. The user can override through the +dnl --with-noarch-pkgconfigdir parameter. +AC_DEFUN([PKG_NOARCH_INSTALLDIR], +[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) +m4_pushdef([pkg_description], + [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) +AC_ARG_WITH([noarch-pkgconfigdir], + [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, + [with_noarch_pkgconfigdir=]pkg_default) +AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) +m4_popdef([pkg_default]) +m4_popdef([pkg_description]) +])dnl PKG_NOARCH_INSTALLDIR + + +dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE, +dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +dnl ------------------------------------------- +dnl Since: 0.28 +dnl +dnl Retrieves the value of the pkg-config variable for the given module. +AC_DEFUN([PKG_CHECK_VAR], +[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl +AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl + +_PKG_CONFIG([$1], [variable="][$3]["], [$2]) +AS_VAR_COPY([$1], [pkg_cv_][$1]) + +AS_VAR_IF([$1], [""], [$5], [$4])dnl +])dnl PKG_CHECK_VAR diff --git a/config/snprintfv.m4 b/config/snprintfv.m4 new file mode 100644 index 0000000..02d6fd0 --- /dev/null +++ b/config/snprintfv.m4 @@ -0,0 +1,98 @@ + +dnl AC_SNPRINTFV_CONVENIENCE[(dir)] - sets LIBSNPRINTFV to the link flags for +dnl the snprintfv convenience library and INCSNPRINTFV to the include flags for +dnl the snprintfv header and adds --enable-snprintfv-convenience to the +dnl configure arguments. Note that AC_CONFIG_SUBDIRS is not called. If DIR +dnl is not provided, it is assumed to be `snprintfv'. LIBSNPRINTFV will be +dnl prefixed with '${top_builddir}/' and INCSNPRINTFV will be prefixed with +dnl '${top_srcdir}/' (note the single quotes!). If your package is not +dnl flat and you're not using automake, define top_builddir and +dnl top_srcdir appropriately in the Makefiles. +AC_DEFUN([AC_SNPRINTFV_CONVENIENCE], +[case $enable_snprintfv_convenience in + no) AC_MSG_ERROR([this package needs a convenience snprintfv]) ;; + "") enable_snprintfv_convenience=yes + ac_configure_args="$ac_configure_args --enable-snprintfv-convenience" ;; + esac + LIBSNPRINTFV='${top_builddir}/'ifelse($#,1,[$1],['snprintfv'])/snprintfv/libsnprintfvc.la + INCSNPRINTFV='-I${top_builddir}/'ifelse($#,1,[$1],['snprintfv'])' -I${top_srcdir}/'ifelse($#,1,[$1],['snprintfv']) + AC_SUBST(LIBSNPRINTFV) + AC_SUBST(INCSNPRINTFV) +]) + +AC_DEFUN([INVOKE_SNPRINTFV_MACROS],[ + AC_SNPRINTFV_CONVENIENCE + # ---------------------------------------------------------------------- + # Set up and process configure options + # ---------------------------------------------------------------------- + AC_ARG_ENABLE(snprintfv-install, + [ --enable-snprintfv-install install libsnprintfv [yes]]) + AM_CONDITIONAL(INSTALL_SNPRINTFV, + test x"${enable_snprintfv_install-no}" != xno) + AM_CONDITIONAL(CONVENIENCE_SNPRINTFV, + test x"${enable_snprintfv_convenience-no}" != xno) + AM_CONDITIONAL(SUBDIR_SNPRINTFV, + test x"${enable_subdir-no}" != xno) + + AM_WITH_DMALLOC + AC_PROG_AWK + + # ---------------------------------------------------------------------- + # check for various programs used during the build. + # On OS/X, "wchar.h" needs "runetype.h" to work properly. + # ---------------------------------------------------------------------- + AC_CHECK_HEADERS([runetype.h wchar.h], [], [],[ + AC_INCLUDES_DEFAULT + #if HAVE_RUNETYPE_H + # include <runetype.h> + #endif + ]) + dnl am_cv_prog_cc_stdc is set by AC_PROG_CC_STDC + case x$am_cv_prog_cc_stdc in + xno) + # Non ansi C => won't work with stdarg.h + AC_CHECK_HEADER(varargs.h) + ;; + *) + case x$ac_cv_header_varargs_h in + xyes) + # Parent package is using varargs.h which is incompatible with + # stdarg.h, so we do the same. + AC_CHECK_HEADER(varargs.h) + ;; + *) + # If stdarg.h is present define HAVE_STDARG_H, otherwise if varargs.h + # is present define HAVE_VARARGS_H. + AC_CHECK_HEADERS(stdarg.h varargs.h, break) + ;; + esac + ;; + esac + + case x$ac_cv_header_stdarg_h$ac_cv_header_varargs_h in + x*yes*) ;; + *) AC_MSG_ERROR(Could not find either stdarg.h or varargs.h.) ;; + esac + + # ---------------------------------------------------------------------- + # Checks for typedefs + # ---------------------------------------------------------------------- + AC_CHECK_TYPES(wchar_t) + AC_CHECK_TYPES(wint_t, [], [], [ + AC_INCLUDES_DEFAULT + #if HAVE_RUNETYPE_H + # include <runetype.h> + #endif + #if HAVE_WCHAR_H + # include <wchar.h> + #endif + ]) + AC_CHECK_TYPES([long double]) + + # ---------------------------------------------------------------------- + # Checks for library calls + # ---------------------------------------------------------------------- + AC_REPLACE_FUNCS(strtoul ldexpl frexpl) + AC_CHECK_LIB(m, log) + AC_CHECK_FUNCS(copysign copysignl) +]) diff --git a/config/stdnoreturn.m4 b/config/stdnoreturn.m4 new file mode 100644 index 0000000..a7ce376 --- /dev/null +++ b/config/stdnoreturn.m4 @@ -0,0 +1,51 @@ +# Check for stdnoreturn.h that conforms to C11. + +dnl Copyright 2012-2018 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. + +# Prepare for substituting <stdnoreturn.h> if it is not supported. + +AC_DEFUN([gl_STDNORETURN_H], +[ + AC_REQUIRE([AC_CANONICAL_HOST]) + case "$host_os" in + cygwin*) + dnl Regardless whether a working <stdnoreturn.h> exists or not, + dnl we need our own <stdnoreturn.h>, because of the definition + dnl of _Noreturn done by gnulib-common.m4. + STDNORETURN_H='stdnoreturn.h' + ;; + *) + AC_CACHE_CHECK([for working stdnoreturn.h], + [gl_cv_header_working_stdnoreturn_h], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include <stdlib.h> + #include <stdnoreturn.h> + /* Do not check for 'noreturn' after the return type. + C11 allows it, but it's rarely done that way + and circa-2012 bleeding-edge GCC rejects it when given + -Werror=old-style-declaration. */ + noreturn void foo1 (void) { exit (0); } + _Noreturn void foo2 (void) { exit (0); } + int testit (int argc, char **argv) + { + if (argc & 1) + return 0; + (argv[0][0] ? foo1 : foo2) (); + } + ]])], + [gl_cv_header_working_stdnoreturn_h=yes], + [gl_cv_header_working_stdnoreturn_h=no])]) + if test $gl_cv_header_working_stdnoreturn_h = yes; then + STDNORETURN_H='' + else + STDNORETURN_H='stdnoreturn.h' + fi + ;; + esac + AC_SUBST([STDNORETURN_H]) + AM_CONDITIONAL([GL_GENERATE_STDNORETURN_H], [test -n "$STDNORETURN_H"]) +]) diff --git a/config/test-driver b/config/test-driver new file mode 100755 index 0000000..b8521a4 --- /dev/null +++ b/config/test-driver @@ -0,0 +1,148 @@ +#! /bin/sh +# test-driver - basic testsuite driver script. + +scriptversion=2018-03-07.03; # UTC + +# Copyright (C) 2011-2018 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, see <https://www.gnu.org/licenses/>. + +# 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 file is maintained in Automake, please report +# bugs to <bug-automake@gnu.org> or send patches to +# <automake-patches@gnu.org>. + +# Make unconditional expansion of undefined variables an error. This +# helps a lot in preventing typo-related bugs. +set -u + +usage_error () +{ + echo "$0: $*" >&2 + print_usage >&2 + exit 2 +} + +print_usage () +{ + cat <<END +Usage: + test-driver --test-name=NAME --log-file=PATH --trs-file=PATH + [--expect-failure={yes|no}] [--color-tests={yes|no}] + [--enable-hard-errors={yes|no}] [--] + TEST-SCRIPT [TEST-SCRIPT-ARGUMENTS] +The '--test-name', '--log-file' and '--trs-file' options are mandatory. +END +} + +test_name= # Used for reporting. +log_file= # Where to save the output of the test script. +trs_file= # Where to save the metadata of the test run. +expect_failure=no +color_tests=no +enable_hard_errors=yes +while test $# -gt 0; do + case $1 in + --help) print_usage; exit $?;; + --version) echo "test-driver $scriptversion"; exit $?;; + --test-name) test_name=$2; shift;; + --log-file) log_file=$2; shift;; + --trs-file) trs_file=$2; shift;; + --color-tests) color_tests=$2; shift;; + --expect-failure) expect_failure=$2; shift;; + --enable-hard-errors) enable_hard_errors=$2; shift;; + --) shift; break;; + -*) usage_error "invalid option: '$1'";; + *) break;; + esac + shift +done + +missing_opts= +test x"$test_name" = x && missing_opts="$missing_opts --test-name" +test x"$log_file" = x && missing_opts="$missing_opts --log-file" +test x"$trs_file" = x && missing_opts="$missing_opts --trs-file" +if test x"$missing_opts" != x; then + usage_error "the following mandatory options are missing:$missing_opts" +fi + +if test $# -eq 0; then + usage_error "missing argument" +fi + +if test $color_tests = yes; then + # Keep this in sync with 'lib/am/check.am:$(am__tty_colors)'. + red='' # Red. + grn='' # Green. + lgn='' # Light green. + blu='' # Blue. + mgn='' # Magenta. + std='' # No color. +else + red= grn= lgn= blu= mgn= std= +fi + +do_exit='rm -f $log_file $trs_file; (exit $st); exit $st' +trap "st=129; $do_exit" 1 +trap "st=130; $do_exit" 2 +trap "st=141; $do_exit" 13 +trap "st=143; $do_exit" 15 + +# Test script is run here. +"$@" >$log_file 2>&1 +estatus=$? + +if test $enable_hard_errors = no && test $estatus -eq 99; then + tweaked_estatus=1 +else + tweaked_estatus=$estatus +fi + +case $tweaked_estatus:$expect_failure in + 0:yes) col=$red res=XPASS recheck=yes gcopy=yes;; + 0:*) col=$grn res=PASS recheck=no gcopy=no;; + 77:*) col=$blu res=SKIP recheck=no gcopy=yes;; + 99:*) col=$mgn res=ERROR recheck=yes gcopy=yes;; + *:yes) col=$lgn res=XFAIL recheck=no gcopy=yes;; + *:*) col=$red res=FAIL recheck=yes gcopy=yes;; +esac + +# Report the test outcome and exit status in the logs, so that one can +# know whether the test passed or failed simply by looking at the '.log' +# file, without the need of also peaking into the corresponding '.trs' +# file (automake bug#11814). +echo "$res $test_name (exit status: $estatus)" >>$log_file + +# Report outcome to console. +echo "${col}${res}${std}: $test_name" + +# Register the test result, and other relevant metadata. +echo ":test-result: $res" > $trs_file +echo ":global-test-result: $res" >> $trs_file +echo ":recheck: $recheck" >> $trs_file +echo ":copy-in-global-log: $gcopy" >> $trs_file + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/config/texinfo.tex b/config/texinfo.tex new file mode 100644 index 0000000..ac5c1d9 --- /dev/null +++ b/config/texinfo.tex @@ -0,0 +1,11727 @@ +% texinfo.tex -- TeX macros to handle Texinfo files. +% +% Load plain if necessary, i.e., if running under initex. +\expandafter\ifx\csname fmtname\endcsname\relax\input plain\fi +% +\def\texinfoversion{2018-02-12.17} +% +% Copyright 1985, 1986, 1988, 1990, 1991, 1992, 1993, 1994, 1995, +% 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, +% 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 +% 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 3 of the +% License, 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 program. If not, see <https://www.gnu.org/licenses/>. +% +% As a special exception, when this file is read by TeX when processing +% a Texinfo source document, you may use the result without +% restriction. This Exception is an additional permission under section 7 +% of the GNU General Public License, version 3 ("GPLv3"). +% +% Please try the latest version of texinfo.tex before submitting bug +% reports; you can get the latest version from: +% https://ftp.gnu.org/gnu/texinfo/ (the Texinfo release area), or +% https://ftpmirror.gnu.org/texinfo/ (same, via a mirror), or +% https://www.gnu.org/software/texinfo/ (the Texinfo home page) +% The texinfo.tex in any given distribution could well be out +% of date, so if that's what you're using, please check. +% +% Send bug reports to bug-texinfo@gnu.org. Please include including a +% complete document in each bug report with which we can reproduce the +% problem. Patches are, of course, greatly appreciated. +% +% To process a Texinfo manual with TeX, it's most reliable to use the +% texi2dvi shell script that comes with the distribution. For a simple +% manual foo.texi, however, you can get away with this: +% tex foo.texi +% texindex foo.?? +% tex foo.texi +% tex foo.texi +% dvips foo.dvi -o # or whatever; this makes foo.ps. +% The extra TeX runs get the cross-reference information correct. +% Sometimes one run after texindex suffices, and sometimes you need more +% than two; texi2dvi does it as many times as necessary. +% +% It is possible to adapt texinfo.tex for other languages, to some +% extent. You can get the existing language-specific files from the +% full Texinfo distribution. +% +% The GNU Texinfo home page is https://www.gnu.org/software/texinfo. + + +\message{Loading texinfo [version \texinfoversion]:} + +% If in a .fmt file, print the version number +% and turn on active characters that we couldn't do earlier because +% they might have appeared in the input file name. +\everyjob{\message{[Texinfo version \texinfoversion]}% + \catcode`+=\active \catcode`\_=\active} + +% LaTeX's \typeout. This ensures that the messages it is used for +% are identical in format to the corresponding ones from latex/pdflatex. +\def\typeout{\immediate\write17}% + +\chardef\other=12 + +% We never want plain's \outer definition of \+ in Texinfo. +% For @tex, we can use \tabalign. +\let\+ = \relax + +% Save some plain tex macros whose names we will redefine. +\let\ptexb=\b +\let\ptexbullet=\bullet +\let\ptexc=\c +\let\ptexcomma=\, +\let\ptexdot=\. +\let\ptexdots=\dots +\let\ptexend=\end +\let\ptexequiv=\equiv +\let\ptexexclam=\! +\let\ptexfootnote=\footnote +\let\ptexgtr=> +\let\ptexhat=^ +\let\ptexi=\i +\let\ptexindent=\indent +\let\ptexinsert=\insert +\let\ptexlbrace=\{ +\let\ptexless=< +\let\ptexnewwrite\newwrite +\let\ptexnoindent=\noindent +\let\ptexplus=+ +\let\ptexraggedright=\raggedright +\let\ptexrbrace=\} +\let\ptexslash=\/ +\let\ptexsp=\sp +\let\ptexstar=\* +\let\ptexsup=\sup +\let\ptext=\t +\let\ptextop=\top +{\catcode`\'=\active \global\let\ptexquoteright'}% active in plain's math mode + +% If this character appears in an error message or help string, it +% starts a new line in the output. +\newlinechar = `^^J + +% 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 % Pre-3.0. +\else + \def\linenumber{l.\the\inputlineno:\space} +\fi + +% Set up fixed words for English if not already set. +\ifx\putwordAppendix\undefined \gdef\putwordAppendix{Appendix}\fi +\ifx\putwordChapter\undefined \gdef\putwordChapter{Chapter}\fi +\ifx\putworderror\undefined \gdef\putworderror{error}\fi +\ifx\putwordfile\undefined \gdef\putwordfile{file}\fi +\ifx\putwordin\undefined \gdef\putwordin{in}\fi +\ifx\putwordIndexIsEmpty\undefined \gdef\putwordIndexIsEmpty{(Index is empty)}\fi +\ifx\putwordIndexNonexistent\undefined \gdef\putwordIndexNonexistent{(Index is nonexistent)}\fi +\ifx\putwordInfo\undefined \gdef\putwordInfo{Info}\fi +\ifx\putwordInstanceVariableof\undefined \gdef\putwordInstanceVariableof{Instance Variable of}\fi +\ifx\putwordMethodon\undefined \gdef\putwordMethodon{Method on}\fi +\ifx\putwordNoTitle\undefined \gdef\putwordNoTitle{No Title}\fi +\ifx\putwordof\undefined \gdef\putwordof{of}\fi +\ifx\putwordon\undefined \gdef\putwordon{on}\fi +\ifx\putwordpage\undefined \gdef\putwordpage{page}\fi +\ifx\putwordsection\undefined \gdef\putwordsection{section}\fi +\ifx\putwordSection\undefined \gdef\putwordSection{Section}\fi +\ifx\putwordsee\undefined \gdef\putwordsee{see}\fi +\ifx\putwordSee\undefined \gdef\putwordSee{See}\fi +\ifx\putwordShortTOC\undefined \gdef\putwordShortTOC{Short Contents}\fi +\ifx\putwordTOC\undefined \gdef\putwordTOC{Table of Contents}\fi +% +\ifx\putwordMJan\undefined \gdef\putwordMJan{January}\fi +\ifx\putwordMFeb\undefined \gdef\putwordMFeb{February}\fi +\ifx\putwordMMar\undefined \gdef\putwordMMar{March}\fi +\ifx\putwordMApr\undefined \gdef\putwordMApr{April}\fi +\ifx\putwordMMay\undefined \gdef\putwordMMay{May}\fi +\ifx\putwordMJun\undefined \gdef\putwordMJun{June}\fi +\ifx\putwordMJul\undefined \gdef\putwordMJul{July}\fi +\ifx\putwordMAug\undefined \gdef\putwordMAug{August}\fi +\ifx\putwordMSep\undefined \gdef\putwordMSep{September}\fi +\ifx\putwordMOct\undefined \gdef\putwordMOct{October}\fi +\ifx\putwordMNov\undefined \gdef\putwordMNov{November}\fi +\ifx\putwordMDec\undefined \gdef\putwordMDec{December}\fi +% +\ifx\putwordDefmac\undefined \gdef\putwordDefmac{Macro}\fi +\ifx\putwordDefspec\undefined \gdef\putwordDefspec{Special Form}\fi +\ifx\putwordDefvar\undefined \gdef\putwordDefvar{Variable}\fi +\ifx\putwordDefopt\undefined \gdef\putwordDefopt{User Option}\fi +\ifx\putwordDeffunc\undefined \gdef\putwordDeffunc{Function}\fi + +% Give the space character the catcode for a space. +\def\spaceisspace{\catcode`\ =10\relax} + +% Likewise for ^^M, the end of line character. +\def\endlineisspace{\catcode13=10\relax} + +\chardef\dashChar = `\- +\chardef\slashChar = `\/ +\chardef\underChar = `\_ + +% Ignore a token. +% +\def\gobble#1{} + +% The following is used inside several \edef's. +\def\makecsname#1{\expandafter\noexpand\csname#1\endcsname} + +% Hyphenation fixes. +\hyphenation{ + Flor-i-da Ghost-script Ghost-view Mac-OS Post-Script + auto-ma-ti-cal-ly ap-pen-dix bit-map bit-maps + data-base data-bases eshell fall-ing half-way long-est man-u-script + man-u-scripts mini-buf-fer mini-buf-fers over-view par-a-digm + par-a-digms rath-er rec-tan-gu-lar ro-bot-ics se-vere-ly set-up spa-ces + spell-ing spell-ings + stand-alone strong-est time-stamp time-stamps which-ever white-space + wide-spread wrap-around +} + +% 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. We also make +% some effort to order the tracing commands to reduce output in the log +% file; cf. trace.sty in LaTeX. +% +\def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}% +\def\loggingall{% + \tracingstats2 + \tracingpages1 + \tracinglostchars2 % 2 gives us more in etex + \tracingparagraphs1 + \tracingoutput1 + \tracingmacros2 + \tracingrestores1 + \showboxbreadth\maxdimen \showboxdepth\maxdimen + \ifx\eTeXversion\thisisundefined\else % etex gives us more logging + \tracingscantokens1 + \tracingifs1 + \tracinggroups1 + \tracingnesting2 + \tracingassigns1 + \fi + \tracingcommands3 % 3 gives us more in etex + \errorcontextlines16 +}% + +% @errormsg{MSG}. Do the index-like expansions on MSG, but if things +% aren't perfect, it's not the end of the world, being an error message, +% after all. +% +\def\errormsg{\begingroup \indexnofonts \doerrormsg} +\def\doerrormsg#1{\errmessage{#1}} + +% add check for \lastpenalty to plain's definitions. If the last thing +% we did was a \nobreak, we don't want to insert more space. +% +\def\smallbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\smallskipamount + \removelastskip\penalty-50\smallskip\fi\fi} +\def\medbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\medskipamount + \removelastskip\penalty-100\medskip\fi\fi} +\def\bigbreak{\ifnum\lastpenalty<10000\par\ifdim\lastskip<\bigskipamount + \removelastskip\penalty-200\bigskip\fi\fi} + +% Output routine +% + +% 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 } + +% Do @cropmarks to get crop marks. +% +\newif\ifcropmarks +\let\cropmarks = \cropmarkstrue +% +% Dimensions to add cropmarks at corners. +% Added by P. A. MacKay, 12 Nov. 1986 +% +\newdimen\outerhsize \newdimen\outervsize % set by the paper size routines +\newdimen\cornerlong \cornerlong=1pc +\newdimen\cornerthick \cornerthick=.3pt +\newdimen\topandbottommargin \topandbottommargin=.75in + +% Output a mark which sets \thischapter, \thissection and \thiscolor. +% We dump everything together because we only have one kind of mark. +% This works because we only use \botmark / \topmark, not \firstmark. +% +% A mark contains a subexpression of the \ifcase ... \fi construct. +% \get*marks macros below extract the needed part using \ifcase. +% +% Another complication is to let the user choose whether \thischapter +% (\thissection) refers to the chapter (section) in effect at the top +% of a page, or that at the bottom of a page. + +% \domark is called twice inside \chapmacro, to add one +% mark before the section break, and one after. +% In the second call \prevchapterdefs is the same as \lastchapterdefs, +% and \prevsectiondefs is the same as \lastsectiondefs. +% Then if the page is not broken at the mark, some of the previous +% section appears on the page, and we can get the name of this section +% from \firstmark for @everyheadingmarks top. +% @everyheadingmarks bottom uses \botmark. +% +% See page 260 of The TeXbook. +\def\domark{% + \toks0=\expandafter{\lastchapterdefs}% + \toks2=\expandafter{\lastsectiondefs}% + \toks4=\expandafter{\prevchapterdefs}% + \toks6=\expandafter{\prevsectiondefs}% + \toks8=\expandafter{\lastcolordefs}% + \mark{% + \the\toks0 \the\toks2 % 0: marks for @everyheadingmarks top + \noexpand\or \the\toks4 \the\toks6 % 1: for @everyheadingmarks bottom + \noexpand\else \the\toks8 % 2: color marks + }% +} + +% \gettopheadingmarks, \getbottomheadingmarks, +% \getcolormarks - extract needed part of mark. +% +% \topmark doesn't work for the very first chapter (after the title +% page or the contents), so we use \firstmark there -- this gets us +% the mark with the chapter defs, unless the user sneaks in, e.g., +% @setcolor (or @url, or @link, etc.) between @contents and the very +% first @chapter. +\def\gettopheadingmarks{% + \ifcase0\topmark\fi + \ifx\thischapter\empty \ifcase0\firstmark\fi \fi +} +\def\getbottomheadingmarks{\ifcase1\botmark\fi} +\def\getcolormarks{\ifcase2\topmark\fi} + +% Avoid "undefined control sequence" errors. +\def\lastchapterdefs{} +\def\lastsectiondefs{} +\def\lastsection{} +\def\prevchapterdefs{} +\def\prevsectiondefs{} +\def\lastcolordefs{} + +% Margin to add to right of even pages, to left of odd pages. +\newdimen\bindingoffset +\newdimen\normaloffset +\newdimen\txipagewidth \newdimen\txipageheight + +% Main output routine. +% +\chardef\PAGE = 255 +\output = {\onepageout{\pagecontents\PAGE}} + +\newbox\headlinebox +\newbox\footlinebox + +% \onepageout takes a vbox as an argument. +% \shipout a vbox for a single page, adding an optional header, footer, +% cropmarks, and footnote. This also causes index entries for this page +% to be written to the auxiliary files. +% +\def\onepageout#1{% + \ifcropmarks \hoffset=0pt \else \hoffset=\normaloffset \fi + % + \ifodd\pageno \advance\hoffset by \bindingoffset + \else \advance\hoffset by -\bindingoffset\fi + % + % Common context changes for both heading and footing. + % Do this outside of the \shipout so @code etc. will be expanded in + % the headline as they should be, not taken literally (outputting ''code). + \def\commmonheadfootline{\let\hsize=\txipagewidth \texinfochars} + % + % Retrieve the information for the headings from the marks in the page, + % and call Plain TeX's \makeheadline and \makefootline, which use the + % values in \headline and \footline. + % + % This is used to check if we are on the first page of a chapter. + \ifcase1\topmark\fi + \let\prevchaptername\thischaptername + \ifcase0\firstmark\fi + \let\curchaptername\thischaptername + % + \ifodd\pageno \getoddheadingmarks \else \getevenheadingmarks \fi + \ifodd\pageno \getoddfootingmarks \else \getevenfootingmarks \fi + % + \ifx\curchaptername\prevchaptername + \let\thischapterheading\thischapter + \else + % \thischapterheading is the same as \thischapter except it is blank + % for the first page of a chapter. This is to prevent the chapter name + % being shown twice. + \def\thischapterheading{}% + \fi + % + \global\setbox\headlinebox = \vbox{\commmonheadfootline \makeheadline}% + \global\setbox\footlinebox = \vbox{\commmonheadfootline \makefootline}% + % + {% + % Set context for writing to auxiliary files like index files. + % Have to do this stuff outside the \shipout because we want it to + % take effect in \write's, yet the group defined by the \vbox ends + % before the \shipout runs. + % + \indexdummies % don't expand commands in the output. + \normalturnoffactive % \ in index entries must not stay \, e.g., if + % the page break happens to be in the middle of an example. + % We don't want .vr (or whatever) entries like this: + % \entry{{\indexbackslash }acronym}{32}{\code {\acronym}} + % "\acronym" won't work when it's read back in; + % it needs to be + % {\code {{\backslashcurfont }acronym} + \shipout\vbox{% + % Do this early so pdf references go to the beginning of the page. + \ifpdfmakepagedest \pdfdest name{\the\pageno} xyz\fi + % + \ifcropmarks \vbox to \outervsize\bgroup + \hsize = \outerhsize + \vskip-\topandbottommargin + \vtop to0pt{% + \line{\ewtop\hfil\ewtop}% + \nointerlineskip + \line{% + \vbox{\moveleft\cornerthick\nstop}% + \hfill + \vbox{\moveright\cornerthick\nstop}% + }% + \vss}% + \vskip\topandbottommargin + \line\bgroup + \hfil % center the page within the outer (page) hsize. + \ifodd\pageno\hskip\bindingoffset\fi + \vbox\bgroup + \fi + % + \unvbox\headlinebox + \pagebody{#1}% + \ifdim\ht\footlinebox > 0pt + % Only leave this space if the footline is nonempty. + % (We lessened \vsize for it in \oddfootingyyy.) + % The \baselineskip=24pt in plain's \makefootline has no effect. + \vskip 24pt + \unvbox\footlinebox + \fi + % + \ifcropmarks + \egroup % end of \vbox\bgroup + \hfil\egroup % end of (centering) \line\bgroup + \vskip\topandbottommargin plus1fill minus1fill + \boxmaxdepth = \cornerthick + \vbox to0pt{\vss + \line{% + \vbox{\moveleft\cornerthick\nsbot}% + \hfill + \vbox{\moveright\cornerthick\nsbot}% + }% + \nointerlineskip + \line{\ewbot\hfil\ewbot}% + }% + \egroup % \vbox from first cropmarks clause + \fi + }% end of \shipout\vbox + }% end of group with \indexdummies + \advancepageno + \ifnum\outputpenalty>-20000 \else\dosupereject\fi +} + +\newinsert\margin \dimen\margin=\maxdimen + +% Main part of page, including any footnotes +\def\pagebody#1{\vbox to\txipageheight{\boxmaxdepth=\maxdepth #1}} +{\catcode`\@ =11 +\gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi +% marginal hacks, juha@viisa.uucp (Juha Takala) +\ifvoid\margin\else % marginal info is present + \rlap{\kern\hsize\vbox to\z@{\kern1pt\box\margin \vss}}\fi +\dimen@=\dp#1\relax \unvbox#1\relax +\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}} + + +% Argument parsing + +% 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. +% For example, \def\foo{\parsearg\fooxxx}. +% +\def\parsearg{\parseargusing{}} +\def\parseargusing#1#2{% + \def\argtorun{#2}% + \begingroup + \obeylines + \spaceisspace + #1% + \parseargline\empty% Insert the \empty token, see \finishparsearg below. +} + +{\obeylines % + \gdef\parseargline#1^^M{% + \endgroup % End of the group started in \parsearg. + \argremovecomment #1\comment\ArgTerm% + }% +} + +% First remove any @comment, then any @c comment. Also remove a @texinfoc +% comment (see \scanmacro for details). Pass the result on to \argcheckspaces. +\def\argremovecomment#1\comment#2\ArgTerm{\argremovec #1\c\ArgTerm} +\def\argremovec#1\c#2\ArgTerm{\argremovetexinfoc #1\texinfoc\ArgTerm} +\def\argremovetexinfoc#1\texinfoc#2\ArgTerm{\argcheckspaces#1\^^M\ArgTerm} + +% Each occurrence of `\^^M' or `<space>\^^M' is replaced by a single space. +% +% \argremovec might leave us with trailing space, e.g., +% @end itemize @c foo +% This space token undergoes the same procedure and is eventually removed +% by \finishparsearg. +% +\def\argcheckspaces#1\^^M{\argcheckspacesX#1\^^M \^^M} +\def\argcheckspacesX#1 \^^M{\argcheckspacesY#1\^^M} +\def\argcheckspacesY#1\^^M#2\^^M#3\ArgTerm{% + \def\temp{#3}% + \ifx\temp\empty + % Do not use \next, perhaps the caller of \parsearg uses it; reuse \temp: + \let\temp\finishparsearg + \else + \let\temp\argcheckspaces + \fi + % Put the space token in: + \temp#1 #3\ArgTerm +} + +% If a _delimited_ argument is enclosed in braces, they get stripped; so +% to get _exactly_ the rest of the line, we had to prevent such situation. +% We prepended an \empty token at the very beginning and we expand it now, +% just before passing the control to \argtorun. +% (Similarly, we have to think about #3 of \argcheckspacesY above: it is +% either the null string, or it ends with \^^M---thus there is no danger +% that a pair of braces would be stripped. +% +% But first, we have to remove the trailing space token. +% +\def\finishparsearg#1 \ArgTerm{\expandafter\argtorun\expandafter{#1}} + + +% \parseargdef - define a command taking an argument on the line +% +% \parseargdef\foo{...} +% is roughly equivalent to +% \def\foo{\parsearg\Xfoo} +% \def\Xfoo#1{...} +\def\parseargdef#1{% + \expandafter \doparseargdef \csname\string#1\endcsname #1% +} +\def\doparseargdef#1#2{% + \def#2{\parsearg#1}% + \def#1##1% +} + +% Several utility definitions with active space: +{ + \obeyspaces + \gdef\obeyedspace{ } + + % 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. + % + \gdef\sepspaces{\obeyspaces\let =\tie} + + % If an index command is used in an @example environment, any spaces + % therein should become regular spaces in the raw index file, not the + % expansion of \tie (\leavevmode \penalty \@M \ ). + \gdef\unsepspaces{\let =\space} +} + + +\def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next} + +% Define the framework for environments in texinfo.tex. It's used like this: +% +% \envdef\foo{...} +% \def\Efoo{...} +% +% It's the responsibility of \envdef to insert \begingroup before the +% actual body; @end closes the group after calling \Efoo. \envdef also +% defines \thisenv, so the current environment is known; @end checks +% whether the environment name matches. The \checkenv macro can also be +% used to check whether the current environment is the one expected. +% +% Non-false conditionals (@iftex, @ifset) don't fit into this, so they +% are not treated as environments; they don't open a group. (The +% implementation of @end takes care not to call \endgroup in this +% special case.) + + +% At run-time, environments start with this: +\def\startenvironment#1{\begingroup\def\thisenv{#1}} +% initialize +\let\thisenv\empty + +% ... but they get defined via ``\envdef\foo{...}'': +\long\def\envdef#1#2{\def#1{\startenvironment#1#2}} +\def\envparseargdef#1#2{\parseargdef#1{\startenvironment#1#2}} + +% Check whether we're in the right environment: +\def\checkenv#1{% + \def\temp{#1}% + \ifx\thisenv\temp + \else + \badenverr + \fi +} + +% Environment mismatch, #1 expected: +\def\badenverr{% + \errhelp = \EMsimple + \errmessage{This command can appear only \inenvironment\temp, + not \inenvironment\thisenv}% +} +\def\inenvironment#1{% + \ifx#1\empty + outside of any environment% + \else + in environment \expandafter\string#1% + \fi +} + +% @end foo executes the definition of \Efoo. +% But first, it executes a specialized version of \checkenv +% +\parseargdef\end{% + \if 1\csname iscond.#1\endcsname + \else + % The general wording of \badenverr may not be ideal. + \expandafter\checkenv\csname#1\endcsname + \csname E#1\endcsname + \endgroup + \fi +} + +\newhelp\EMsimple{Press RETURN to continue.} + + +% 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 + % Avoid using \@M directly, because that causes trouble + % if the definition is written into an index file. + \global\let\tiepenalty = \@M + \gdef\tie{\leavevmode\penalty\tiepenalty\ } +} + +% @: forces normal size whitespace following. +\def\:{\spacefactor=1000 } + +% @* forces a line break. +\def\*{\unskip\hfil\break\hbox{}\ignorespaces} + +% @/ allows a line break. +\let\/=\allowbreak + +% @. is an end-of-sentence period. +\def\.{.\spacefactor=\endofsentencespacefactor\space} + +% @! is an end-of-sentence bang. +\def\!{!\spacefactor=\endofsentencespacefactor\space} + +% @? is an end-of-sentence query. +\def\?{?\spacefactor=\endofsentencespacefactor\space} + +% @frenchspacing on|off says whether to put extra space after punctuation. +% +\def\onword{on} +\def\offword{off} +% +\parseargdef\frenchspacing{% + \def\temp{#1}% + \ifx\temp\onword \plainfrenchspacing + \else\ifx\temp\offword \plainnonfrenchspacing + \else + \errhelp = \EMsimple + \errmessage{Unknown @frenchspacing option `\temp', must be on|off}% + \fi\fi +} + +% @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. +% +% Another complication is that the group might be very large. This can +% cause the glue on the previous page to be unduly stretched, because it +% does not have much material. In this case, it's better to add an +% explicit \vfill so that the extra space is at the bottom. The +% threshold for doing this is if the group is more than \vfilllimit +% percent of a page (\vfilllimit can be changed inside of @tex). +% +\newbox\groupbox +\def\vfilllimit{0.7} +% +\envdef\group{% + \ifnum\catcode`\^^M=\active \else + \errhelp = \groupinvalidhelp + \errmessage{@group invalid in context where filling is enabled}% + \fi + \startsavinginserts + % + \setbox\groupbox = \vtop\bgroup + % 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 +} +% +% The \vtop 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. Thus, space below is not quite equal to space +% above. But it's pretty close. +\def\Egroup{% + % To get correct interline space between the last line of the group + % and the first line afterwards, we have to propagate \prevdepth. + \endgraf % Not \par, as it may have been set to \lisppar. + \global\dimen1 = \prevdepth + \egroup % End the \vtop. + \addgroupbox + \prevdepth = \dimen1 + \checkinserts +} + +\def\addgroupbox{ + % \dimen0 is the vertical size of the group's box. + \dimen0 = \ht\groupbox \advance\dimen0 by \dp\groupbox + % \dimen2 is how much space is left on the page (more or less). + \dimen2 = \txipageheight \advance\dimen2 by -\pagetotal + % if the group doesn't fit on the current page, and it's a big big + % group, force a page break. + \ifdim \dimen0 > \dimen2 + \ifdim \pagetotal < \vfilllimit\txipageheight + \page + \fi + \fi + \box\groupbox +} + +% +% 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 + +\parseargdef\need{% + % Ensure vertical mode, so we don't make a big box in the middle of a + % paragraph. + \par + % + % If the @need value is less than one line space, it's useless. + \dimen0 = #1\mil + \dimen2 = \ht\strutbox + \advance\dimen2 by \dp\strutbox + \ifdim\dimen0 > \dimen2 + % + % Do a \strut just to make the height of this box be normal, so the + % normal leading is inserted relative to the preceding line. + % And a page break here is fine. + \vtop to #1\mil{\strut\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 + \fi +} + +% @br forces paragraph break (and is undocumented). + +\let\br = \par + +% @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. +\parseargdef\exdent{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break} + +% This defn is used inside nofill environments such as @example. +\parseargdef\nofillexdent{{\advance \leftskip by -\exdentamount + \leftline{\hskip\leftskip{\rm#1}}}} + +% @inmargin{WHICH}{TEXT} puts TEXT in the WHICH margin next to the current +% paragraph. For more general purposes, use the \margin insertion +% class. WHICH is `l' or `r'. Not documented, written for gawk manual. +% +\newskip\inmarginspacing \inmarginspacing=1cm +\def\strutdepth{\dp\strutbox} +% +\def\doinmargin#1#2{\strut\vadjust{% + \nobreak + \kern-\strutdepth + \vtop to \strutdepth{% + \baselineskip=\strutdepth + \vss + % if you have multiple lines of stuff to put here, you'll need to + % make the vbox yourself of the appropriate size. + \ifx#1l% + \llap{\ignorespaces #2\hskip\inmarginspacing}% + \else + \rlap{\hskip\hsize \hskip\inmarginspacing \ignorespaces #2}% + \fi + \null + }% +}} +\def\inleftmargin{\doinmargin l} +\def\inrightmargin{\doinmargin r} +% +% @inmargin{TEXT [, RIGHT-TEXT]} +% (if RIGHT-TEXT is given, use TEXT for left page, RIGHT-TEXT for right; +% else use TEXT for both). +% +\def\inmargin#1{\parseinmargin #1,,\finish} +\def\parseinmargin#1,#2,#3\finish{% not perfect, but better than nothing. + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0 > 0pt + \def\lefttext{#1}% have both texts + \def\righttext{#2}% + \else + \def\lefttext{#1}% have only one text + \def\righttext{#1}% + \fi + % + \ifodd\pageno + \def\temp{\inrightmargin\righttext}% odd page -> outside is right margin + \else + \def\temp{\inleftmargin\lefttext}% + \fi + \temp +} + +% @include FILE -- \input text of FILE. +% +\def\include{\parseargusing\filenamecatcodes\includezzz} +\def\includezzz#1{% + \pushthisfilestack + \def\thisfile{#1}% + {% + \makevalueexpandable % we want to expand any @value in FILE. + \turnoffactive % and allow special characters in the expansion + \indexnofonts % Allow `@@' and other weird things in file names. + \wlog{texinfo.tex: doing @include of #1^^J}% + \edef\temp{\noexpand\input #1 }% + % + % This trickery is to read FILE outside of a group, in case it makes + % definitions, etc. + \expandafter + }\temp + \popthisfilestack +} +\def\filenamecatcodes{% + \catcode`\\=\other + \catcode`~=\other + \catcode`^=\other + \catcode`_=\other + \catcode`|=\other + \catcode`<=\other + \catcode`>=\other + \catcode`+=\other + \catcode`-=\other + \catcode`\`=\other + \catcode`\'=\other +} + +\def\pushthisfilestack{% + \expandafter\pushthisfilestackX\popthisfilestack\StackTerm +} +\def\pushthisfilestackX{% + \expandafter\pushthisfilestackY\thisfile\StackTerm +} +\def\pushthisfilestackY #1\StackTerm #2\StackTerm {% + \gdef\popthisfilestack{\gdef\thisfile{#1}\gdef\popthisfilestack{#2}}% +} + +\def\popthisfilestack{\errthisfilestackempty} +\def\errthisfilestackempty{\errmessage{Internal error: + the stack of filenames is empty.}} +% +\def\thisfile{} + +% @center line +% outputs that line, centered. +% +\parseargdef\center{% + \ifhmode + \let\centersub\centerH + \else + \let\centersub\centerV + \fi + \centersub{\hfil \ignorespaces#1\unskip \hfil}% + \let\centersub\relax % don't let the definition persist, just in case +} +\def\centerH#1{{% + \hfil\break + \advance\hsize by -\leftskip + \advance\hsize by -\rightskip + \line{#1}% + \break +}} +% +\newcount\centerpenalty +\def\centerV#1{% + % The idea here is the same as in \startdefun, \cartouche, etc.: if + % @center is the first thing after a section heading, we need to wipe + % out the negative parskip inserted by \sectionheading, but still + % prevent a page break here. + \centerpenalty = \lastpenalty + \ifnum\centerpenalty>10000 \vskip\parskip \fi + \ifnum\centerpenalty>9999 \penalty\centerpenalty \fi + \line{\kern\leftskip #1\kern\rightskip}% +} + +% @sp n outputs n lines of vertical space +% +\parseargdef\sp{\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\c{\begingroup \catcode`\^^M=\active% +\catcode`\@=\other \catcode`\{=\other \catcode`\}=\other% +\cxxx} +{\catcode`\^^M=\active \gdef\cxxx#1^^M{\endgroup}} +% +\let\comment\c + +% @paragraphindent NCHARS +% We'll use ems for NCHARS, close enough. +% NCHARS can also be the word `asis' or `none'. +% We cannot feasibly implement @paragraphindent asis, though. +% +\def\asisword{asis} % no translation, these are keywords +\def\noneword{none} +% +\parseargdef\paragraphindent{% + \def\temp{#1}% + \ifx\temp\asisword + \else + \ifx\temp\noneword + \defaultparindent = 0pt + \else + \defaultparindent = #1em + \fi + \fi + \parindent = \defaultparindent +} + +% @exampleindent NCHARS +% We'll use ems for NCHARS like @paragraphindent. +% It seems @exampleindent asis isn't necessary, but +% I preserve it to make it similar to @paragraphindent. +\parseargdef\exampleindent{% + \def\temp{#1}% + \ifx\temp\asisword + \else + \ifx\temp\noneword + \lispnarrowing = 0pt + \else + \lispnarrowing = #1em + \fi + \fi +} + +% @firstparagraphindent WORD +% If WORD is `none', then suppress indentation of the first paragraph +% after a section heading. If WORD is `insert', then do indent at such +% paragraphs. +% +% The paragraph indentation is suppressed or not by calling +% \suppressfirstparagraphindent, which the sectioning commands do. +% We switch the definition of this back and forth according to WORD. +% By default, we suppress indentation. +% +\def\suppressfirstparagraphindent{\dosuppressfirstparagraphindent} +\def\insertword{insert} +% +\parseargdef\firstparagraphindent{% + \def\temp{#1}% + \ifx\temp\noneword + \let\suppressfirstparagraphindent = \dosuppressfirstparagraphindent + \else\ifx\temp\insertword + \let\suppressfirstparagraphindent = \relax + \else + \errhelp = \EMsimple + \errmessage{Unknown @firstparagraphindent option `\temp'}% + \fi\fi +} + +% Here is how we actually suppress indentation. Redefine \everypar to +% \kern backwards by \parindent, and then reset itself to empty. +% +% We also make \indent itself not actually do anything until the next +% paragraph. +% +\gdef\dosuppressfirstparagraphindent{% + \gdef\indent {\restorefirstparagraphindent \indent}% + \gdef\noindent{\restorefirstparagraphindent \noindent}% + \global\everypar = {\kern -\parindent \restorefirstparagraphindent}% +} +% +\gdef\restorefirstparagraphindent{% + \global\let\indent = \ptexindent + \global\let\noindent = \ptexnoindent + \global\everypar = {}% +} + + +% @refill is a no-op. +\let\refill=\relax + +% @setfilename INFO-FILENAME - ignored +\let\setfilename=\comment + +% @bye. +\outer\def\bye{\pagealignmacro\tracingstats=1\ptexend} + + +\message{pdf,} +% adobe `portable' document format +\newcount\tempnum +\newcount\lnkcount +\newtoks\filename +\newcount\filenamelength +\newcount\pgn +\newtoks\toksA +\newtoks\toksB +\newtoks\toksC +\newtoks\toksD +\newbox\boxA +\newbox\boxB +\newcount\countA +\newif\ifpdf +\newif\ifpdfmakepagedest + +% +% For LuaTeX +% + +\newif\iftxiuseunicodedestname +\txiuseunicodedestnamefalse % For pdfTeX etc. + +\ifx\luatexversion\thisisundefined +\else + % Use Unicode destination names + \txiuseunicodedestnametrue + % Escape PDF strings with converting UTF-16 from UTF-8 + \begingroup + \catcode`\%=12 + \directlua{ + function UTF16oct(str) + tex.sprint(string.char(0x5c) .. '376' .. string.char(0x5c) .. '377') + for c in string.utfvalues(str) do + if c < 0x10000 then + tex.sprint( + string.format(string.char(0x5c) .. string.char(0x25) .. '03o' .. + string.char(0x5c) .. string.char(0x25) .. '03o', + (c / 256), (c % 256))) + else + c = c - 0x10000 + local c_hi = c / 1024 + 0xd800 + local c_lo = c % 1024 + 0xdc00 + tex.sprint( + string.format(string.char(0x5c) .. string.char(0x25) .. '03o' .. + string.char(0x5c) .. string.char(0x25) .. '03o' .. + string.char(0x5c) .. string.char(0x25) .. '03o' .. + string.char(0x5c) .. string.char(0x25) .. '03o', + (c_hi / 256), (c_hi % 256), + (c_lo / 256), (c_lo % 256))) + end + end + end + } + \endgroup + \def\pdfescapestrutfsixteen#1{\directlua{UTF16oct('\luaescapestring{#1}')}} + % Escape PDF strings without converting + \begingroup + \directlua{ + function PDFescstr(str) + for c in string.bytes(str) do + if c <= 0x20 or c >= 0x80 or c == 0x28 or c == 0x29 or c == 0x5c then + tex.sprint( + string.format(string.char(0x5c) .. string.char(0x25) .. '03o', + c)) + else + tex.sprint(string.char(c)) + end + end + end + } + \endgroup + \def\pdfescapestring#1{\directlua{PDFescstr('\luaescapestring{#1}')}} + \ifnum\luatexversion>84 + % For LuaTeX >= 0.85 + \def\pdfdest{\pdfextension dest} + \let\pdfoutput\outputmode + \def\pdfliteral{\pdfextension literal} + \def\pdfcatalog{\pdfextension catalog} + \def\pdftexversion{\numexpr\pdffeedback version\relax} + \let\pdfximage\saveimageresource + \let\pdfrefximage\useimageresource + \let\pdflastximage\lastsavedimageresourceindex + \def\pdfendlink{\pdfextension endlink\relax} + \def\pdfoutline{\pdfextension outline} + \def\pdfstartlink{\pdfextension startlink} + \def\pdffontattr{\pdfextension fontattr} + \def\pdfobj{\pdfextension obj} + \def\pdflastobj{\numexpr\pdffeedback lastobj\relax} + \let\pdfpagewidth\pagewidth + \let\pdfpageheight\pageheight + \edef\pdfhorigin{\pdfvariable horigin} + \edef\pdfvorigin{\pdfvariable vorigin} + \fi +\fi + +% when pdftex is run in dvi mode, \pdfoutput is defined (so \pdfoutput=1 +% can be set). So we test for \relax and 0 as well as being undefined. +\ifx\pdfoutput\thisisundefined +\else + \ifx\pdfoutput\relax + \else + \ifcase\pdfoutput + \else + \pdftrue + \fi + \fi +\fi + +% PDF uses PostScript string constants for the names of xref targets, +% for display in the outlines, and in other places. Thus, we have to +% double any backslashes. Otherwise, a name like "\node" will be +% interpreted as a newline (\n), followed by o, d, e. Not good. +% +% See http://www.ntg.nl/pipermail/ntg-pdftex/2004-July/000654.html and +% related messages. The final outcome is that it is up to the TeX user +% to double the backslashes and otherwise make the string valid, so +% that's what we do. pdftex 1.30.0 (ca.2005) introduced a primitive to +% do this reliably, so we use it. + +% #1 is a control sequence in which to do the replacements, +% which we \xdef. +\def\txiescapepdf#1{% + \ifx\pdfescapestring\thisisundefined + % No primitive available; should we give a warning or log? + % Many times it won't matter. + \xdef#1{#1}% + \else + % The expandable \pdfescapestring primitive escapes parentheses, + % backslashes, and other special chars. + \xdef#1{\pdfescapestring{#1}}% + \fi +} +\def\txiescapepdfutfsixteen#1{% + \ifx\pdfescapestrutfsixteen\thisisundefined + % No UTF-16 converting macro available. + \txiescapepdf{#1}% + \else + \xdef#1{\pdfescapestrutfsixteen{#1}}% + \fi +} + +\newhelp\nopdfimagehelp{Texinfo supports .png, .jpg, .jpeg, and .pdf images +with PDF output, and none of those formats could be found. (.eps cannot +be supported due to the design of the PDF format; use regular TeX (DVI +output) for that.)} + +\ifpdf + % + % Color manipulation macros using ideas from pdfcolor.tex, + % except using rgb instead of cmyk; the latter is said to render as a + % very dark gray on-screen and a very dark halftone in print, instead + % of actual black. The dark red here is dark enough to print on paper as + % nearly black, but still distinguishable for online viewing. We use + % black by default, though. + \def\rgbDarkRed{0.50 0.09 0.12} + \def\rgbBlack{0 0 0} + % + % rg sets the color for filling (usual text, etc.); + % RG sets the color for stroking (thin rules, e.g., normal _'s). + \def\pdfsetcolor#1{\pdfliteral{#1 rg #1 RG}} + % + % Set color, and create a mark which defines \thiscolor accordingly, + % so that \makeheadline knows which color to restore. + \def\setcolor#1{% + \xdef\lastcolordefs{\gdef\noexpand\thiscolor{#1}}% + \domark + \pdfsetcolor{#1}% + } + % + \def\maincolor{\rgbBlack} + \pdfsetcolor{\maincolor} + \edef\thiscolor{\maincolor} + \def\lastcolordefs{} + % + \def\makefootline{% + \baselineskip24pt + \line{\pdfsetcolor{\maincolor}\the\footline}% + } + % + \def\makeheadline{% + \vbox to 0pt{% + \vskip-22.5pt + \line{% + \vbox to8.5pt{}% + % Extract \thiscolor definition from the marks. + \getcolormarks + % Typeset the headline with \maincolor, then restore the color. + \pdfsetcolor{\maincolor}\the\headline\pdfsetcolor{\thiscolor}% + }% + \vss + }% + \nointerlineskip + } + % + % + \pdfcatalog{/PageMode /UseOutlines} + % + % #1 is image name, #2 width (might be empty/whitespace), #3 height (ditto). + \def\dopdfimage#1#2#3{% + \def\pdfimagewidth{#2}\setbox0 = \hbox{\ignorespaces #2}% + \def\pdfimageheight{#3}\setbox2 = \hbox{\ignorespaces #3}% + % + % pdftex (and the PDF format) support .pdf, .png, .jpg (among + % others). Let's try in that order, PDF first since if + % someone has a scalable image, presumably better to use that than a + % bitmap. + \let\pdfimgext=\empty + \begingroup + \openin 1 #1.pdf \ifeof 1 + \openin 1 #1.PDF \ifeof 1 + \openin 1 #1.png \ifeof 1 + \openin 1 #1.jpg \ifeof 1 + \openin 1 #1.jpeg \ifeof 1 + \openin 1 #1.JPG \ifeof 1 + \errhelp = \nopdfimagehelp + \errmessage{Could not find image file #1 for pdf}% + \else \gdef\pdfimgext{JPG}% + \fi + \else \gdef\pdfimgext{jpeg}% + \fi + \else \gdef\pdfimgext{jpg}% + \fi + \else \gdef\pdfimgext{png}% + \fi + \else \gdef\pdfimgext{PDF}% + \fi + \else \gdef\pdfimgext{pdf}% + \fi + \closein 1 + \endgroup + % + % without \immediate, ancient pdftex seg faults when the same image is + % included twice. (Version 3.14159-pre-1.0-unofficial-20010704.) + \ifnum\pdftexversion < 14 + \immediate\pdfimage + \else + \immediate\pdfximage + \fi + \ifdim \wd0 >0pt width \pdfimagewidth \fi + \ifdim \wd2 >0pt height \pdfimageheight \fi + \ifnum\pdftexversion<13 + #1.\pdfimgext + \else + {#1.\pdfimgext}% + \fi + \ifnum\pdftexversion < 14 \else + \pdfrefximage \pdflastximage + \fi} + % + \def\setpdfdestname#1{{% + % We have to set dummies so commands such as @code, and characters + % such as \, aren't expanded when present in a section title. + \indexnofonts + \makevalueexpandable + \turnoffactive + \iftxiuseunicodedestname + \ifx \declaredencoding \latone + % Pass through Latin-1 characters. + % LuaTeX with byte wise I/O converts Latin-1 characters to Unicode. + \else + \ifx \declaredencoding \utfeight + % Pass through Unicode characters. + \else + % Use ASCII approximations in destination names. + \passthroughcharsfalse + \fi + \fi + \else + % Use ASCII approximations in destination names. + \passthroughcharsfalse + \fi + \def\pdfdestname{#1}% + \txiescapepdf\pdfdestname + }} + % + \def\setpdfoutlinetext#1{{% + \indexnofonts + \makevalueexpandable + \turnoffactive + \ifx \declaredencoding \latone + % The PDF format can use an extended form of Latin-1 in bookmark + % strings. See Appendix D of the PDF Reference, Sixth Edition, for + % the "PDFDocEncoding". + \passthroughcharstrue + % Pass through Latin-1 characters. + % LuaTeX: Convert to Unicode + % pdfTeX: Use Latin-1 as PDFDocEncoding + \def\pdfoutlinetext{#1}% + \else + \ifx \declaredencoding \utfeight + \ifx\luatexversion\thisisundefined + % For pdfTeX with UTF-8. + % TODO: the PDF format can use UTF-16 in bookmark strings, + % but the code for this isn't done yet. + % Use ASCII approximations. + \passthroughcharsfalse + \def\pdfoutlinetext{#1}% + \else + % For LuaTeX with UTF-8. + % Pass through Unicode characters for title texts. + \passthroughcharstrue + \def\pdfoutlinetext{#1}% + \fi + \else + % For non-Latin-1 or non-UTF-8 encodings. + % Use ASCII approximations. + \passthroughcharsfalse + \def\pdfoutlinetext{#1}% + \fi + \fi + % LuaTeX: Convert to UTF-16 + % pdfTeX: Use Latin-1 as PDFDocEncoding + \txiescapepdfutfsixteen\pdfoutlinetext + }} + % + \def\pdfmkdest#1{% + \setpdfdestname{#1}% + \safewhatsit{\pdfdest name{\pdfdestname} xyz}% + } + % + % used to mark target names; must be expandable. + \def\pdfmkpgn#1{#1} + % + % by default, use black for everything. + \def\urlcolor{\rgbBlack} + \def\linkcolor{\rgbBlack} + \def\endlink{\setcolor{\maincolor}\pdfendlink} + % + % Adding outlines to PDF; macros for calculating structure of outlines + % come from Petr Olsak + \def\expnumber#1{\expandafter\ifx\csname#1\endcsname\relax 0% + \else \csname#1\endcsname \fi} + \def\advancenumber#1{\tempnum=\expnumber{#1}\relax + \advance\tempnum by 1 + \expandafter\xdef\csname#1\endcsname{\the\tempnum}} + % + % #1 is the section text, which is what will be displayed in the + % outline by the pdf viewer. #2 is the pdf expression for the number + % of subentries (or empty, for subsubsections). #3 is the node text, + % which might be empty if this toc entry had no corresponding node. + % #4 is the page number + % + \def\dopdfoutline#1#2#3#4{% + % Generate a link to the node text if that exists; else, use the + % page number. We could generate a destination for the section + % text in the case where a section has no node, but it doesn't + % seem worth the trouble, since most documents are normally structured. + \setpdfoutlinetext{#1} + \setpdfdestname{#3} + \ifx\pdfdestname\empty + \def\pdfdestname{#4}% + \fi + % + \pdfoutline goto name{\pdfmkpgn{\pdfdestname}}#2{\pdfoutlinetext}% + } + % + \def\pdfmakeoutlines{% + \begingroup + % Read toc silently, to get counts of subentries for \pdfoutline. + \def\partentry##1##2##3##4{}% ignore parts in the outlines + \def\numchapentry##1##2##3##4{% + \def\thischapnum{##2}% + \def\thissecnum{0}% + \def\thissubsecnum{0}% + }% + \def\numsecentry##1##2##3##4{% + \advancenumber{chap\thischapnum}% + \def\thissecnum{##2}% + \def\thissubsecnum{0}% + }% + \def\numsubsecentry##1##2##3##4{% + \advancenumber{sec\thissecnum}% + \def\thissubsecnum{##2}% + }% + \def\numsubsubsecentry##1##2##3##4{% + \advancenumber{subsec\thissubsecnum}% + }% + \def\thischapnum{0}% + \def\thissecnum{0}% + \def\thissubsecnum{0}% + % + % use \def rather than \let here because we redefine \chapentry et + % al. a second time, below. + \def\appentry{\numchapentry}% + \def\appsecentry{\numsecentry}% + \def\appsubsecentry{\numsubsecentry}% + \def\appsubsubsecentry{\numsubsubsecentry}% + \def\unnchapentry{\numchapentry}% + \def\unnsecentry{\numsecentry}% + \def\unnsubsecentry{\numsubsecentry}% + \def\unnsubsubsecentry{\numsubsubsecentry}% + \readdatafile{toc}% + % + % Read toc second time, this time actually producing the outlines. + % The `-' means take the \expnumber as the absolute number of + % subentries, which we calculated on our first read of the .toc above. + % + % We use the node names as the destinations. + \def\numchapentry##1##2##3##4{% + \dopdfoutline{##1}{count-\expnumber{chap##2}}{##3}{##4}}% + \def\numsecentry##1##2##3##4{% + \dopdfoutline{##1}{count-\expnumber{sec##2}}{##3}{##4}}% + \def\numsubsecentry##1##2##3##4{% + \dopdfoutline{##1}{count-\expnumber{subsec##2}}{##3}{##4}}% + \def\numsubsubsecentry##1##2##3##4{% count is always zero + \dopdfoutline{##1}{}{##3}{##4}}% + % + % PDF outlines are displayed using system fonts, instead of + % document fonts. Therefore we cannot use special characters, + % since the encoding is unknown. For example, the eogonek from + % Latin 2 (0xea) gets translated to a | character. Info from + % Staszek Wawrykiewicz, 19 Jan 2004 04:09:24 +0100. + % + % TODO this right, we have to translate 8-bit characters to + % their "best" equivalent, based on the @documentencoding. Too + % much work for too little return. Just use the ASCII equivalents + % we use for the index sort strings. + % + \indexnofonts + \setupdatafile + % We can have normal brace characters in the PDF outlines, unlike + % Texinfo index files. So set that up. + \def\{{\lbracecharliteral}% + \def\}{\rbracecharliteral}% + \catcode`\\=\active \otherbackslash + \input \tocreadfilename + \endgroup + } + {\catcode`[=1 \catcode`]=2 + \catcode`{=\other \catcode`}=\other + \gdef\lbracecharliteral[{]% + \gdef\rbracecharliteral[}]% + ] + % + \def\skipspaces#1{\def\PP{#1}\def\D{|}% + \ifx\PP\D\let\nextsp\relax + \else\let\nextsp\skipspaces + \addtokens{\filename}{\PP}% + \advance\filenamelength by 1 + \fi + \nextsp} + \def\getfilename#1{% + \filenamelength=0 + % If we don't expand the argument now, \skipspaces will get + % snagged on things like "@value{foo}". + \edef\temp{#1}% + \expandafter\skipspaces\temp|\relax + } + \ifnum\pdftexversion < 14 + \let \startlink \pdfannotlink + \else + \let \startlink \pdfstartlink + \fi + % make a live url in pdf output. + \def\pdfurl#1{% + \begingroup + % it seems we really need yet another set of dummies; have not + % tried to figure out what each command should do in the context + % of @url. for now, just make @/ a no-op, that's the only one + % people have actually reported a problem with. + % + \normalturnoffactive + \def\@{@}% + \let\/=\empty + \makevalueexpandable + % do we want to go so far as to use \indexnofonts instead of just + % special-casing \var here? + \def\var##1{##1}% + % + \leavevmode\setcolor{\urlcolor}% + \startlink attr{/Border [0 0 0]}% + user{/Subtype /Link /A << /S /URI /URI (#1) >>}% + \endgroup} + \def\pdfgettoks#1.{\setbox\boxA=\hbox{\toksA={#1.}\toksB={}\maketoks}} + \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks} + \def\adn#1{\addtokens{\toksC}{#1}\global\countA=1\let\next=\maketoks} + \def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}\toksA={#2}} + \def\maketoks{% + \expandafter\poptoks\the\toksA|ENDTOKS|\relax + \ifx\first0\adn0 + \else\ifx\first1\adn1 \else\ifx\first2\adn2 \else\ifx\first3\adn3 + \else\ifx\first4\adn4 \else\ifx\first5\adn5 \else\ifx\first6\adn6 + \else\ifx\first7\adn7 \else\ifx\first8\adn8 \else\ifx\first9\adn9 + \else + \ifnum0=\countA\else\makelink\fi + \ifx\first.\let\next=\done\else + \let\next=\maketoks + \addtokens{\toksB}{\the\toksD} + \ifx\first,\addtokens{\toksB}{\space}\fi + \fi + \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi + \next} + \def\makelink{\addtokens{\toksB}% + {\noexpand\pdflink{\the\toksC}}\toksC={}\global\countA=0} + \def\pdflink#1{% + \startlink attr{/Border [0 0 0]} goto name{\pdfmkpgn{#1}} + \setcolor{\linkcolor}#1\endlink} + \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st} +\else + % non-pdf mode + \let\pdfmkdest = \gobble + \let\pdfurl = \gobble + \let\endlink = \relax + \let\setcolor = \gobble + \let\pdfsetcolor = \gobble + \let\pdfmakeoutlines = \relax +\fi % \ifx\pdfoutput + +% +% For XeTeX +% +\ifx\XeTeXrevision\thisisundefined +\else + % + % XeTeX version check + % + \ifnum\strcmp{\the\XeTeXversion\XeTeXrevision}{0.99996}>-1 + % TeX Live 2016 contains XeTeX 0.99996 and xdvipdfmx 20160307. + % It can use the `dvipdfmx:config' special (from TeX Live SVN r40941). + % For avoiding PDF destination name replacement, we use this special + % instead of xdvipdfmx's command line option `-C 0x0010'. + \special{dvipdfmx:config C 0x0010} + % XeTeX 0.99995+ comes with xdvipdfmx 20160307+. + % It can handle Unicode destination names for PDF. + \txiuseunicodedestnametrue + \else + % XeTeX < 0.99996 (TeX Live < 2016) cannot use the + % `dvipdfmx:config' special. + % So for avoiding PDF destination name replacement, + % xdvipdfmx's command line option `-C 0x0010' is necessary. + % + % XeTeX < 0.99995 can not handle Unicode destination names for PDF + % because xdvipdfmx 20150315 has a UTF-16 conversion issue. + % It is fixed by xdvipdfmx 20160106 (TeX Live SVN r39753). + \txiuseunicodedestnamefalse + \fi + % + % Color support + % + \def\rgbDarkRed{0.50 0.09 0.12} + \def\rgbBlack{0 0 0} + % + \def\pdfsetcolor#1{\special{pdf:scolor [#1]}} + % + % Set color, and create a mark which defines \thiscolor accordingly, + % so that \makeheadline knows which color to restore. + \def\setcolor#1{% + \xdef\lastcolordefs{\gdef\noexpand\thiscolor{#1}}% + \domark + \pdfsetcolor{#1}% + } + % + \def\maincolor{\rgbBlack} + \pdfsetcolor{\maincolor} + \edef\thiscolor{\maincolor} + \def\lastcolordefs{} + % + \def\makefootline{% + \baselineskip24pt + \line{\pdfsetcolor{\maincolor}\the\footline}% + } + % + \def\makeheadline{% + \vbox to 0pt{% + \vskip-22.5pt + \line{% + \vbox to8.5pt{}% + % Extract \thiscolor definition from the marks. + \getcolormarks + % Typeset the headline with \maincolor, then restore the color. + \pdfsetcolor{\maincolor}\the\headline\pdfsetcolor{\thiscolor}% + }% + \vss + }% + \nointerlineskip + } + % + % PDF outline support + % + % Emulate pdfTeX primitive + \def\pdfdest name#1 xyz{% + \special{pdf:dest (#1) [@thispage /XYZ @xpos @ypos null]}% + } + % + \def\setpdfdestname#1{{% + % We have to set dummies so commands such as @code, and characters + % such as \, aren't expanded when present in a section title. + \indexnofonts + \makevalueexpandable + \turnoffactive + \iftxiuseunicodedestname + % Pass through Unicode characters. + \else + % Use ASCII approximations in destination names. + \passthroughcharsfalse + \fi + \def\pdfdestname{#1}% + \txiescapepdf\pdfdestname + }} + % + \def\setpdfoutlinetext#1{{% + \turnoffactive + % Always use Unicode characters in title texts. + \def\pdfoutlinetext{#1}% + % For XeTeX, xdvipdfmx converts to UTF-16. + % So we do not convert. + \txiescapepdf\pdfoutlinetext + }} + % + \def\pdfmkdest#1{% + \setpdfdestname{#1}% + \safewhatsit{\pdfdest name{\pdfdestname} xyz}% + } + % + % by default, use black for everything. + \def\urlcolor{\rgbBlack} + \def\linkcolor{\rgbBlack} + \def\endlink{\setcolor{\maincolor}\pdfendlink} + % + \def\dopdfoutline#1#2#3#4{% + \setpdfoutlinetext{#1} + \setpdfdestname{#3} + \ifx\pdfdestname\empty + \def\pdfdestname{#4}% + \fi + % + \special{pdf:out [-] #2 << /Title (\pdfoutlinetext) /A + << /S /GoTo /D (\pdfdestname) >> >> }% + } + % + \def\pdfmakeoutlines{% + \begingroup + % + % For XeTeX, counts of subentries are not necessary. + % Therefore, we read toc only once. + % + % We use node names as destinations. + \def\partentry##1##2##3##4{}% ignore parts in the outlines + \def\numchapentry##1##2##3##4{% + \dopdfoutline{##1}{1}{##3}{##4}}% + \def\numsecentry##1##2##3##4{% + \dopdfoutline{##1}{2}{##3}{##4}}% + \def\numsubsecentry##1##2##3##4{% + \dopdfoutline{##1}{3}{##3}{##4}}% + \def\numsubsubsecentry##1##2##3##4{% + \dopdfoutline{##1}{4}{##3}{##4}}% + % + \let\appentry\numchapentry% + \let\appsecentry\numsecentry% + \let\appsubsecentry\numsubsecentry% + \let\appsubsubsecentry\numsubsubsecentry% + \let\unnchapentry\numchapentry% + \let\unnsecentry\numsecentry% + \let\unnsubsecentry\numsubsecentry% + \let\unnsubsubsecentry\numsubsubsecentry% + % + % For XeTeX, xdvipdfmx converts strings to UTF-16. + % Therefore, the encoding and the language may not be considered. + % + \indexnofonts + \setupdatafile + % We can have normal brace characters in the PDF outlines, unlike + % Texinfo index files. So set that up. + \def\{{\lbracecharliteral}% + \def\}{\rbracecharliteral}% + \catcode`\\=\active \otherbackslash + \input \tocreadfilename + \endgroup + } + {\catcode`[=1 \catcode`]=2 + \catcode`{=\other \catcode`}=\other + \gdef\lbracecharliteral[{]% + \gdef\rbracecharliteral[}]% + ] + + \special{pdf:docview << /PageMode /UseOutlines >> } + % ``\special{pdf:tounicode ...}'' is not necessary + % because xdvipdfmx converts strings from UTF-8 to UTF-16 without it. + % However, due to a UTF-16 conversion issue of xdvipdfmx 20150315, + % ``\special{pdf:dest ...}'' cannot handle non-ASCII strings. + % It is fixed by xdvipdfmx 20160106 (TeX Live SVN r39753). +% + \def\skipspaces#1{\def\PP{#1}\def\D{|}% + \ifx\PP\D\let\nextsp\relax + \else\let\nextsp\skipspaces + \addtokens{\filename}{\PP}% + \advance\filenamelength by 1 + \fi + \nextsp} + \def\getfilename#1{% + \filenamelength=0 + % If we don't expand the argument now, \skipspaces will get + % snagged on things like "@value{foo}". + \edef\temp{#1}% + \expandafter\skipspaces\temp|\relax + } + % make a live url in pdf output. + \def\pdfurl#1{% + \begingroup + % it seems we really need yet another set of dummies; have not + % tried to figure out what each command should do in the context + % of @url. for now, just make @/ a no-op, that's the only one + % people have actually reported a problem with. + % + \normalturnoffactive + \def\@{@}% + \let\/=\empty + \makevalueexpandable + % do we want to go so far as to use \indexnofonts instead of just + % special-casing \var here? + \def\var##1{##1}% + % + \leavevmode\setcolor{\urlcolor}% + \special{pdf:bann << /Border [0 0 0] + /Subtype /Link /A << /S /URI /URI (#1) >> >>}% + \endgroup} + \def\endlink{\setcolor{\maincolor}\special{pdf:eann}} + \def\pdfgettoks#1.{\setbox\boxA=\hbox{\toksA={#1.}\toksB={}\maketoks}} + \def\addtokens#1#2{\edef\addtoks{\noexpand#1={\the#1#2}}\addtoks} + \def\adn#1{\addtokens{\toksC}{#1}\global\countA=1\let\next=\maketoks} + \def\poptoks#1#2|ENDTOKS|{\let\first=#1\toksD={#1}\toksA={#2}} + \def\maketoks{% + \expandafter\poptoks\the\toksA|ENDTOKS|\relax + \ifx\first0\adn0 + \else\ifx\first1\adn1 \else\ifx\first2\adn2 \else\ifx\first3\adn3 + \else\ifx\first4\adn4 \else\ifx\first5\adn5 \else\ifx\first6\adn6 + \else\ifx\first7\adn7 \else\ifx\first8\adn8 \else\ifx\first9\adn9 + \else + \ifnum0=\countA\else\makelink\fi + \ifx\first.\let\next=\done\else + \let\next=\maketoks + \addtokens{\toksB}{\the\toksD} + \ifx\first,\addtokens{\toksB}{\space}\fi + \fi + \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi + \next} + \def\makelink{\addtokens{\toksB}% + {\noexpand\pdflink{\the\toksC}}\toksC={}\global\countA=0} + \def\pdflink#1{% + \special{pdf:bann << /Border [0 0 0] + /Type /Annot /Subtype /Link /A << /S /GoTo /D (#1) >> >>}% + \setcolor{\linkcolor}#1\endlink} + \def\done{\edef\st{\global\noexpand\toksA={\the\toksB}}\st} +% + % + % @image support + % + % #1 is image name, #2 width (might be empty/whitespace), #3 height (ditto). + \def\doxeteximage#1#2#3{% + \def\xeteximagewidth{#2}\setbox0 = \hbox{\ignorespaces #2}% + \def\xeteximageheight{#3}\setbox2 = \hbox{\ignorespaces #3}% + % + % XeTeX (and the PDF format) supports .pdf, .png, .jpg (among + % others). Let's try in that order, PDF first since if + % someone has a scalable image, presumably better to use that than a + % bitmap. + \let\xeteximgext=\empty + \begingroup + \openin 1 #1.pdf \ifeof 1 + \openin 1 #1.PDF \ifeof 1 + \openin 1 #1.png \ifeof 1 + \openin 1 #1.jpg \ifeof 1 + \openin 1 #1.jpeg \ifeof 1 + \openin 1 #1.JPG \ifeof 1 + \errmessage{Could not find image file #1 for XeTeX}% + \else \gdef\xeteximgext{JPG}% + \fi + \else \gdef\xeteximgext{jpeg}% + \fi + \else \gdef\xeteximgext{jpg}% + \fi + \else \gdef\xeteximgext{png}% + \fi + \else \gdef\xeteximgext{PDF}% + \fi + \else \gdef\xeteximgext{pdf}% + \fi + \closein 1 + \endgroup + % + \def\xetexpdfext{pdf}% + \ifx\xeteximgext\xetexpdfext + \XeTeXpdffile "#1".\xeteximgext "" + \else + \def\xetexpdfext{PDF}% + \ifx\xeteximgext\xetexpdfext + \XeTeXpdffile "#1".\xeteximgext "" + \else + \XeTeXpicfile "#1".\xeteximgext "" + \fi + \fi + \ifdim \wd0 >0pt width \xeteximagewidth \fi + \ifdim \wd2 >0pt height \xeteximageheight \fi \relax + } +\fi + + +% +\message{fonts,} + +% 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} +% +% can get a sort of poor man's double spacing by redefining this. +\def\baselinefactor{1} +% +\newdimen\textleading +\def\setleading#1{% + \dimen0 = #1\relax + \normalbaselineskip = \baselinefactor\dimen0 + \normallineskip = \lineskipfactor\normalbaselineskip + \normalbaselines + \setbox\strutbox =\hbox{% + \vrule width0pt height\strutheightpercent\baselineskip + depth \strutdepthpercent \baselineskip + }% +} + +% PDF CMaps. See also LaTeX's t1.cmap. +% +% do nothing with this by default. +\expandafter\let\csname cmapOT1\endcsname\gobble +\expandafter\let\csname cmapOT1IT\endcsname\gobble +\expandafter\let\csname cmapOT1TT\endcsname\gobble + +% if we are producing pdf, and we have \pdffontattr, then define cmaps. +% (\pdffontattr was introduced many years ago, but people still run +% older pdftex's; it's easy to conditionalize, so we do.) +\ifpdf \ifx\pdffontattr\thisisundefined \else + \begingroup + \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char. + \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap +%%DocumentNeededResources: ProcSet (CIDInit) +%%IncludeResource: ProcSet (CIDInit) +%%BeginResource: CMap (TeX-OT1-0) +%%Title: (TeX-OT1-0 TeX OT1 0) +%%Version: 1.000 +%%EndComments +/CIDInit /ProcSet findresource begin +12 dict begin +begincmap +/CIDSystemInfo +<< /Registry (TeX) +/Ordering (OT1) +/Supplement 0 +>> def +/CMapName /TeX-OT1-0 def +/CMapType 2 def +1 begincodespacerange +<00> <7F> +endcodespacerange +8 beginbfrange +<00> <01> <0393> +<09> <0A> <03A8> +<23> <26> <0023> +<28> <3B> <0028> +<3F> <5B> <003F> +<5D> <5E> <005D> +<61> <7A> <0061> +<7B> <7C> <2013> +endbfrange +40 beginbfchar +<02> <0398> +<03> <039B> +<04> <039E> +<05> <03A0> +<06> <03A3> +<07> <03D2> +<08> <03A6> +<0B> <00660066> +<0C> <00660069> +<0D> <0066006C> +<0E> <006600660069> +<0F> <00660066006C> +<10> <0131> +<11> <0237> +<12> <0060> +<13> <00B4> +<14> <02C7> +<15> <02D8> +<16> <00AF> +<17> <02DA> +<18> <00B8> +<19> <00DF> +<1A> <00E6> +<1B> <0153> +<1C> <00F8> +<1D> <00C6> +<1E> <0152> +<1F> <00D8> +<21> <0021> +<22> <201D> +<27> <2019> +<3C> <00A1> +<3D> <003D> +<3E> <00BF> +<5C> <201C> +<5F> <02D9> +<60> <2018> +<7D> <02DD> +<7E> <007E> +<7F> <00A8> +endbfchar +endcmap +CMapName currentdict /CMap defineresource pop +end +end +%%EndResource +%%EOF + }\endgroup + \expandafter\edef\csname cmapOT1\endcsname#1{% + \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}% + }% +% +% \cmapOT1IT + \begingroup + \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char. + \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap +%%DocumentNeededResources: ProcSet (CIDInit) +%%IncludeResource: ProcSet (CIDInit) +%%BeginResource: CMap (TeX-OT1IT-0) +%%Title: (TeX-OT1IT-0 TeX OT1IT 0) +%%Version: 1.000 +%%EndComments +/CIDInit /ProcSet findresource begin +12 dict begin +begincmap +/CIDSystemInfo +<< /Registry (TeX) +/Ordering (OT1IT) +/Supplement 0 +>> def +/CMapName /TeX-OT1IT-0 def +/CMapType 2 def +1 begincodespacerange +<00> <7F> +endcodespacerange +8 beginbfrange +<00> <01> <0393> +<09> <0A> <03A8> +<25> <26> <0025> +<28> <3B> <0028> +<3F> <5B> <003F> +<5D> <5E> <005D> +<61> <7A> <0061> +<7B> <7C> <2013> +endbfrange +42 beginbfchar +<02> <0398> +<03> <039B> +<04> <039E> +<05> <03A0> +<06> <03A3> +<07> <03D2> +<08> <03A6> +<0B> <00660066> +<0C> <00660069> +<0D> <0066006C> +<0E> <006600660069> +<0F> <00660066006C> +<10> <0131> +<11> <0237> +<12> <0060> +<13> <00B4> +<14> <02C7> +<15> <02D8> +<16> <00AF> +<17> <02DA> +<18> <00B8> +<19> <00DF> +<1A> <00E6> +<1B> <0153> +<1C> <00F8> +<1D> <00C6> +<1E> <0152> +<1F> <00D8> +<21> <0021> +<22> <201D> +<23> <0023> +<24> <00A3> +<27> <2019> +<3C> <00A1> +<3D> <003D> +<3E> <00BF> +<5C> <201C> +<5F> <02D9> +<60> <2018> +<7D> <02DD> +<7E> <007E> +<7F> <00A8> +endbfchar +endcmap +CMapName currentdict /CMap defineresource pop +end +end +%%EndResource +%%EOF + }\endgroup + \expandafter\edef\csname cmapOT1IT\endcsname#1{% + \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}% + }% +% +% \cmapOT1TT + \begingroup + \catcode`\^^M=\active \def^^M{^^J}% Output line endings as the ^^J char. + \catcode`\%=12 \immediate\pdfobj stream {%!PS-Adobe-3.0 Resource-CMap +%%DocumentNeededResources: ProcSet (CIDInit) +%%IncludeResource: ProcSet (CIDInit) +%%BeginResource: CMap (TeX-OT1TT-0) +%%Title: (TeX-OT1TT-0 TeX OT1TT 0) +%%Version: 1.000 +%%EndComments +/CIDInit /ProcSet findresource begin +12 dict begin +begincmap +/CIDSystemInfo +<< /Registry (TeX) +/Ordering (OT1TT) +/Supplement 0 +>> def +/CMapName /TeX-OT1TT-0 def +/CMapType 2 def +1 begincodespacerange +<00> <7F> +endcodespacerange +5 beginbfrange +<00> <01> <0393> +<09> <0A> <03A8> +<21> <26> <0021> +<28> <5F> <0028> +<61> <7E> <0061> +endbfrange +32 beginbfchar +<02> <0398> +<03> <039B> +<04> <039E> +<05> <03A0> +<06> <03A3> +<07> <03D2> +<08> <03A6> +<0B> <2191> +<0C> <2193> +<0D> <0027> +<0E> <00A1> +<0F> <00BF> +<10> <0131> +<11> <0237> +<12> <0060> +<13> <00B4> +<14> <02C7> +<15> <02D8> +<16> <00AF> +<17> <02DA> +<18> <00B8> +<19> <00DF> +<1A> <00E6> +<1B> <0153> +<1C> <00F8> +<1D> <00C6> +<1E> <0152> +<1F> <00D8> +<20> <2423> +<27> <2019> +<60> <2018> +<7F> <00A8> +endbfchar +endcmap +CMapName currentdict /CMap defineresource pop +end +end +%%EndResource +%%EOF + }\endgroup + \expandafter\edef\csname cmapOT1TT\endcsname#1{% + \pdffontattr#1{/ToUnicode \the\pdflastobj\space 0 R}% + }% +\fi\fi + + +% Set the font macro #1 to the font named \fontprefix#2. +% #3 is the font's design size, #4 is a scale factor, #5 is the CMap +% encoding (only OT1, OT1IT and OT1TT are allowed, or empty to omit). +% Example: +% #1 = \textrm +% #2 = \rmshape +% #3 = 10 +% #4 = \mainmagstep +% #5 = OT1 +% +\def\setfont#1#2#3#4#5{% + \font#1=\fontprefix#2#3 scaled #4 + \csname cmap#5\endcsname#1% +} +% This is what gets called when #5 of \setfont is empty. +\let\cmap\gobble +% +% (end of cmaps) + +% Use cm as the default font prefix. +% To specify the font prefix, you must define \fontprefix +% before you read in texinfo.tex. +\ifx\fontprefix\thisisundefined +\def\fontprefix{cm} +\fi +% Support font families that don't use the same naming scheme as CM. +\def\rmshape{r} +\def\rmbshape{bx} % where the normal face is bold +\def\bfshape{b} +\def\bxshape{bx} +\def\ttshape{tt} +\def\ttbshape{tt} +\def\ttslshape{sltt} +\def\itshape{ti} +\def\itbshape{bxti} +\def\slshape{sl} +\def\slbshape{bxsl} +\def\sfshape{ss} +\def\sfbshape{ss} +\def\scshape{csc} +\def\scbshape{csc} + +% Definitions for a main text size of 11pt. (The default in Texinfo.) +% +\def\definetextfontsizexi{% +% Text fonts (11.2pt, magstep1). +\def\textnominalsize{11pt} +\edef\mainmagstep{\magstephalf} +\setfont\textrm\rmshape{10}{\mainmagstep}{OT1} +\setfont\texttt\ttshape{10}{\mainmagstep}{OT1TT} +\setfont\textbf\bfshape{10}{\mainmagstep}{OT1} +\setfont\textit\itshape{10}{\mainmagstep}{OT1IT} +\setfont\textsl\slshape{10}{\mainmagstep}{OT1} +\setfont\textsf\sfshape{10}{\mainmagstep}{OT1} +\setfont\textsc\scshape{10}{\mainmagstep}{OT1} +\setfont\textttsl\ttslshape{10}{\mainmagstep}{OT1TT} +\font\texti=cmmi10 scaled \mainmagstep +\font\textsy=cmsy10 scaled \mainmagstep +\def\textecsize{1095} + +% A few fonts for @defun names and args. +\setfont\defbf\bfshape{10}{\magstep1}{OT1} +\setfont\deftt\ttshape{10}{\magstep1}{OT1TT} +\setfont\defsl\slshape{10}{\magstep1}{OT1TT} +\setfont\defttsl\ttslshape{10}{\magstep1}{OT1TT} +\def\df{\let\ttfont=\deftt \let\bffont = \defbf +\let\ttslfont=\defttsl \let\slfont=\defsl \bf} + +% Fonts for indices, footnotes, small examples (9pt). +\def\smallnominalsize{9pt} +\setfont\smallrm\rmshape{9}{1000}{OT1} +\setfont\smalltt\ttshape{9}{1000}{OT1TT} +\setfont\smallbf\bfshape{10}{900}{OT1} +\setfont\smallit\itshape{9}{1000}{OT1IT} +\setfont\smallsl\slshape{9}{1000}{OT1} +\setfont\smallsf\sfshape{9}{1000}{OT1} +\setfont\smallsc\scshape{10}{900}{OT1} +\setfont\smallttsl\ttslshape{10}{900}{OT1TT} +\font\smalli=cmmi9 +\font\smallsy=cmsy9 +\def\smallecsize{0900} + +% Fonts for small examples (8pt). +\def\smallernominalsize{8pt} +\setfont\smallerrm\rmshape{8}{1000}{OT1} +\setfont\smallertt\ttshape{8}{1000}{OT1TT} +\setfont\smallerbf\bfshape{10}{800}{OT1} +\setfont\smallerit\itshape{8}{1000}{OT1IT} +\setfont\smallersl\slshape{8}{1000}{OT1} +\setfont\smallersf\sfshape{8}{1000}{OT1} +\setfont\smallersc\scshape{10}{800}{OT1} +\setfont\smallerttsl\ttslshape{10}{800}{OT1TT} +\font\smalleri=cmmi8 +\font\smallersy=cmsy8 +\def\smallerecsize{0800} + +% Fonts for math mode superscripts (7pt). +\def\sevennominalsize{7pt} +\setfont\sevenrm\rmshape{7}{1000}{OT1} +\setfont\seventt\ttshape{10}{700}{OT1TT} +\setfont\sevenbf\bfshape{10}{700}{OT1} +\setfont\sevenit\itshape{7}{1000}{OT1IT} +\setfont\sevensl\slshape{10}{700}{OT1} +\setfont\sevensf\sfshape{10}{700}{OT1} +\setfont\sevensc\scshape{10}{700}{OT1} +\setfont\seventtsl\ttslshape{10}{700}{OT1TT} +\font\seveni=cmmi7 +\font\sevensy=cmsy7 +\def\sevenecsize{0700} + +% Fonts for title page (20.4pt): +\def\titlenominalsize{20pt} +\setfont\titlerm\rmbshape{12}{\magstep3}{OT1} +\setfont\titleit\itbshape{10}{\magstep4}{OT1IT} +\setfont\titlesl\slbshape{10}{\magstep4}{OT1} +\setfont\titlett\ttbshape{12}{\magstep3}{OT1TT} +\setfont\titlettsl\ttslshape{10}{\magstep4}{OT1TT} +\setfont\titlesf\sfbshape{17}{\magstep1}{OT1} +\let\titlebf=\titlerm +\setfont\titlesc\scbshape{10}{\magstep4}{OT1} +\font\titlei=cmmi12 scaled \magstep3 +\font\titlesy=cmsy10 scaled \magstep4 +\def\titleecsize{2074} + +% Chapter (and unnumbered) fonts (17.28pt). +\def\chapnominalsize{17pt} +\setfont\chaprm\rmbshape{12}{\magstep2}{OT1} +\setfont\chapit\itbshape{10}{\magstep3}{OT1IT} +\setfont\chapsl\slbshape{10}{\magstep3}{OT1} +\setfont\chaptt\ttbshape{12}{\magstep2}{OT1TT} +\setfont\chapttsl\ttslshape{10}{\magstep3}{OT1TT} +\setfont\chapsf\sfbshape{17}{1000}{OT1} +\let\chapbf=\chaprm +\setfont\chapsc\scbshape{10}{\magstep3}{OT1} +\font\chapi=cmmi12 scaled \magstep2 +\font\chapsy=cmsy10 scaled \magstep3 +\def\chapecsize{1728} + +% Section fonts (14.4pt). +\def\secnominalsize{14pt} +\setfont\secrm\rmbshape{12}{\magstep1}{OT1} +\setfont\secrmnotbold\rmshape{12}{\magstep1}{OT1} +\setfont\secit\itbshape{10}{\magstep2}{OT1IT} +\setfont\secsl\slbshape{10}{\magstep2}{OT1} +\setfont\sectt\ttbshape{12}{\magstep1}{OT1TT} +\setfont\secttsl\ttslshape{10}{\magstep2}{OT1TT} +\setfont\secsf\sfbshape{12}{\magstep1}{OT1} +\let\secbf\secrm +\setfont\secsc\scbshape{10}{\magstep2}{OT1} +\font\seci=cmmi12 scaled \magstep1 +\font\secsy=cmsy10 scaled \magstep2 +\def\sececsize{1440} + +% Subsection fonts (13.15pt). +\def\ssecnominalsize{13pt} +\setfont\ssecrm\rmbshape{12}{\magstephalf}{OT1} +\setfont\ssecit\itbshape{10}{1315}{OT1IT} +\setfont\ssecsl\slbshape{10}{1315}{OT1} +\setfont\ssectt\ttbshape{12}{\magstephalf}{OT1TT} +\setfont\ssecttsl\ttslshape{10}{1315}{OT1TT} +\setfont\ssecsf\sfbshape{12}{\magstephalf}{OT1} +\let\ssecbf\ssecrm +\setfont\ssecsc\scbshape{10}{1315}{OT1} +\font\sseci=cmmi12 scaled \magstephalf +\font\ssecsy=cmsy10 scaled 1315 +\def\ssececsize{1200} + +% Reduced fonts for @acronym in text (10pt). +\def\reducednominalsize{10pt} +\setfont\reducedrm\rmshape{10}{1000}{OT1} +\setfont\reducedtt\ttshape{10}{1000}{OT1TT} +\setfont\reducedbf\bfshape{10}{1000}{OT1} +\setfont\reducedit\itshape{10}{1000}{OT1IT} +\setfont\reducedsl\slshape{10}{1000}{OT1} +\setfont\reducedsf\sfshape{10}{1000}{OT1} +\setfont\reducedsc\scshape{10}{1000}{OT1} +\setfont\reducedttsl\ttslshape{10}{1000}{OT1TT} +\font\reducedi=cmmi10 +\font\reducedsy=cmsy10 +\def\reducedecsize{1000} + +\textleading = 13.2pt % line spacing for 11pt CM +\textfonts % reset the current fonts +\rm +} % end of 11pt text font size definitions, \definetextfontsizexi + + +% Definitions to make the main text be 10pt Computer Modern, with +% section, chapter, etc., sizes following suit. This is for the GNU +% Press printing of the Emacs 22 manual. Maybe other manuals in the +% future. Used with @smallbook, which sets the leading to 12pt. +% +\def\definetextfontsizex{% +% Text fonts (10pt). +\def\textnominalsize{10pt} +\edef\mainmagstep{1000} +\setfont\textrm\rmshape{10}{\mainmagstep}{OT1} +\setfont\texttt\ttshape{10}{\mainmagstep}{OT1TT} +\setfont\textbf\bfshape{10}{\mainmagstep}{OT1} +\setfont\textit\itshape{10}{\mainmagstep}{OT1IT} +\setfont\textsl\slshape{10}{\mainmagstep}{OT1} +\setfont\textsf\sfshape{10}{\mainmagstep}{OT1} +\setfont\textsc\scshape{10}{\mainmagstep}{OT1} +\setfont\textttsl\ttslshape{10}{\mainmagstep}{OT1TT} +\font\texti=cmmi10 scaled \mainmagstep +\font\textsy=cmsy10 scaled \mainmagstep +\def\textecsize{1000} + +% A few fonts for @defun names and args. +\setfont\defbf\bfshape{10}{\magstephalf}{OT1} +\setfont\deftt\ttshape{10}{\magstephalf}{OT1TT} +\setfont\defsl\slshape{10}{\magstephalf}{OT1TT} +\setfont\defttsl\ttslshape{10}{\magstephalf}{OT1TT} +\def\df{\let\ttfont=\deftt \let\bffont = \defbf +\let\slfont=\defsl \let\ttslfont=\defttsl \bf} + +% Fonts for indices, footnotes, small examples (9pt). +\def\smallnominalsize{9pt} +\setfont\smallrm\rmshape{9}{1000}{OT1} +\setfont\smalltt\ttshape{9}{1000}{OT1TT} +\setfont\smallbf\bfshape{10}{900}{OT1} +\setfont\smallit\itshape{9}{1000}{OT1IT} +\setfont\smallsl\slshape{9}{1000}{OT1} +\setfont\smallsf\sfshape{9}{1000}{OT1} +\setfont\smallsc\scshape{10}{900}{OT1} +\setfont\smallttsl\ttslshape{10}{900}{OT1TT} +\font\smalli=cmmi9 +\font\smallsy=cmsy9 +\def\smallecsize{0900} + +% Fonts for small examples (8pt). +\def\smallernominalsize{8pt} +\setfont\smallerrm\rmshape{8}{1000}{OT1} +\setfont\smallertt\ttshape{8}{1000}{OT1TT} +\setfont\smallerbf\bfshape{10}{800}{OT1} +\setfont\smallerit\itshape{8}{1000}{OT1IT} +\setfont\smallersl\slshape{8}{1000}{OT1} +\setfont\smallersf\sfshape{8}{1000}{OT1} +\setfont\smallersc\scshape{10}{800}{OT1} +\setfont\smallerttsl\ttslshape{10}{800}{OT1TT} +\font\smalleri=cmmi8 +\font\smallersy=cmsy8 +\def\smallerecsize{0800} + +% Fonts for math mode superscripts (7pt). +\def\sevennominalsize{7pt} +\setfont\sevenrm\rmshape{7}{1000}{OT1} +\setfont\seventt\ttshape{10}{700}{OT1TT} +\setfont\sevenbf\bfshape{10}{700}{OT1} +\setfont\sevenit\itshape{7}{1000}{OT1IT} +\setfont\sevensl\slshape{10}{700}{OT1} +\setfont\sevensf\sfshape{10}{700}{OT1} +\setfont\sevensc\scshape{10}{700}{OT1} +\setfont\seventtsl\ttslshape{10}{700}{OT1TT} +\font\seveni=cmmi7 +\font\sevensy=cmsy7 +\def\sevenecsize{0700} + +% Fonts for title page (20.4pt): +\def\titlenominalsize{20pt} +\setfont\titlerm\rmbshape{12}{\magstep3}{OT1} +\setfont\titleit\itbshape{10}{\magstep4}{OT1IT} +\setfont\titlesl\slbshape{10}{\magstep4}{OT1} +\setfont\titlett\ttbshape{12}{\magstep3}{OT1TT} +\setfont\titlettsl\ttslshape{10}{\magstep4}{OT1TT} +\setfont\titlesf\sfbshape{17}{\magstep1}{OT1} +\let\titlebf=\titlerm +\setfont\titlesc\scbshape{10}{\magstep4}{OT1} +\font\titlei=cmmi12 scaled \magstep3 +\font\titlesy=cmsy10 scaled \magstep4 +\def\titleecsize{2074} + +% Chapter fonts (14.4pt). +\def\chapnominalsize{14pt} +\setfont\chaprm\rmbshape{12}{\magstep1}{OT1} +\setfont\chapit\itbshape{10}{\magstep2}{OT1IT} +\setfont\chapsl\slbshape{10}{\magstep2}{OT1} +\setfont\chaptt\ttbshape{12}{\magstep1}{OT1TT} +\setfont\chapttsl\ttslshape{10}{\magstep2}{OT1TT} +\setfont\chapsf\sfbshape{12}{\magstep1}{OT1} +\let\chapbf\chaprm +\setfont\chapsc\scbshape{10}{\magstep2}{OT1} +\font\chapi=cmmi12 scaled \magstep1 +\font\chapsy=cmsy10 scaled \magstep2 +\def\chapecsize{1440} + +% Section fonts (12pt). +\def\secnominalsize{12pt} +\setfont\secrm\rmbshape{12}{1000}{OT1} +\setfont\secit\itbshape{10}{\magstep1}{OT1IT} +\setfont\secsl\slbshape{10}{\magstep1}{OT1} +\setfont\sectt\ttbshape{12}{1000}{OT1TT} +\setfont\secttsl\ttslshape{10}{\magstep1}{OT1TT} +\setfont\secsf\sfbshape{12}{1000}{OT1} +\let\secbf\secrm +\setfont\secsc\scbshape{10}{\magstep1}{OT1} +\font\seci=cmmi12 +\font\secsy=cmsy10 scaled \magstep1 +\def\sececsize{1200} + +% Subsection fonts (10pt). +\def\ssecnominalsize{10pt} +\setfont\ssecrm\rmbshape{10}{1000}{OT1} +\setfont\ssecit\itbshape{10}{1000}{OT1IT} +\setfont\ssecsl\slbshape{10}{1000}{OT1} +\setfont\ssectt\ttbshape{10}{1000}{OT1TT} +\setfont\ssecttsl\ttslshape{10}{1000}{OT1TT} +\setfont\ssecsf\sfbshape{10}{1000}{OT1} +\let\ssecbf\ssecrm +\setfont\ssecsc\scbshape{10}{1000}{OT1} +\font\sseci=cmmi10 +\font\ssecsy=cmsy10 +\def\ssececsize{1000} + +% Reduced fonts for @acronym in text (9pt). +\def\reducednominalsize{9pt} +\setfont\reducedrm\rmshape{9}{1000}{OT1} +\setfont\reducedtt\ttshape{9}{1000}{OT1TT} +\setfont\reducedbf\bfshape{10}{900}{OT1} +\setfont\reducedit\itshape{9}{1000}{OT1IT} +\setfont\reducedsl\slshape{9}{1000}{OT1} +\setfont\reducedsf\sfshape{9}{1000}{OT1} +\setfont\reducedsc\scshape{10}{900}{OT1} +\setfont\reducedttsl\ttslshape{10}{900}{OT1TT} +\font\reducedi=cmmi9 +\font\reducedsy=cmsy9 +\def\reducedecsize{0900} + +\divide\parskip by 2 % reduce space between paragraphs +\textleading = 12pt % line spacing for 10pt CM +\textfonts % reset the current fonts +\rm +} % end of 10pt text font size definitions, \definetextfontsizex + +% Fonts for short table of contents. +\setfont\shortcontrm\rmshape{12}{1000}{OT1} +\setfont\shortcontbf\bfshape{10}{\magstep1}{OT1} % no cmb12 +\setfont\shortcontsl\slshape{12}{1000}{OT1} +\setfont\shortconttt\ttshape{12}{1000}{OT1TT} + + +% We provide the user-level command +% @fonttextsize 10 +% (or 11) to redefine the text font size. pt is assumed. +% +\def\xiword{11} +\def\xword{10} +\def\xwordpt{10pt} +% +\parseargdef\fonttextsize{% + \def\textsizearg{#1}% + %\wlog{doing @fonttextsize \textsizearg}% + % + % Set \globaldefs so that documents can use this inside @tex, since + % makeinfo 4.8 does not support it, but we need it nonetheless. + % + \begingroup \globaldefs=1 + \ifx\textsizearg\xword \definetextfontsizex + \else \ifx\textsizearg\xiword \definetextfontsizexi + \else + \errhelp=\EMsimple + \errmessage{@fonttextsize only supports `10' or `11', not `\textsizearg'} + \fi\fi + \endgroup +} + +% +% Change the current font style to #1, remembering it in \curfontstyle. +% For now, we do not accumulate font styles: @b{@i{foo}} prints foo in +% italics, not bold italics. +% +\def\setfontstyle#1{% + \def\curfontstyle{#1}% not as a control sequence, because we are \edef'd. + \csname #1font\endcsname % change the current font +} + +\def\rm{\fam=0 \setfontstyle{rm}} +\def\it{\fam=\itfam \setfontstyle{it}} +\def\sl{\fam=\slfam \setfontstyle{sl}} +\def\bf{\fam=\bffam \setfontstyle{bf}}\def\bfstylename{bf} +\def\tt{\fam=\ttfam \setfontstyle{tt}} + +% Texinfo sort of supports the sans serif font style, which plain TeX does not. +% So we set up a \sf. +\newfam\sffam +\def\sf{\fam=\sffam \setfontstyle{sf}} + +% We don't need math for this font style. +\def\ttsl{\setfontstyle{ttsl}} + + +% In order for the font changes to affect most math symbols and letters, +% we have to define the \textfont of the standard families. +% We don't bother to reset \scriptscriptfont; awaiting user need. +% +\def\resetmathfonts{% + \textfont0=\rmfont \textfont1=\ifont \textfont2=\syfont + \textfont\itfam=\itfont \textfont\slfam=\slfont \textfont\bffam=\bffont + \textfont\ttfam=\ttfont \textfont\sffam=\sffont + % + % Fonts for superscript. Note that the 7pt fonts are used regardless + % of the current font size. + \scriptfont0=\sevenrm \scriptfont1=\seveni \scriptfont2=\sevensy + \scriptfont\itfam=\sevenit \scriptfont\slfam=\sevensl + \scriptfont\bffam=\sevenbf \scriptfont\ttfam=\seventt + \scriptfont\sffam=\sevensf +} + +% + +% The font-changing commands (all called \...fonts) redefine the meanings +% of \STYLEfont, instead of just \STYLE. We do this because \STYLE needs +% to also set the current \fam for math mode. Our \STYLE (e.g., \rm) +% commands hardwire \STYLEfont to set the current font. +% +% The fonts used for \ifont are for "math italics" (\itfont is for italics +% in regular text). \syfont is also used in math mode only. +% +% Each font-changing command also sets the names \lsize (one size lower) +% and \lllsize (three sizes lower). These relative commands are used +% in, e.g., the LaTeX logo and acronyms. +% +% This all needs generalizing, badly. +% + +\def\assignfonts#1{% + \expandafter\let\expandafter\rmfont\csname #1rm\endcsname + \expandafter\let\expandafter\itfont\csname #1it\endcsname + \expandafter\let\expandafter\slfont\csname #1sl\endcsname + \expandafter\let\expandafter\bffont\csname #1bf\endcsname + \expandafter\let\expandafter\ttfont\csname #1tt\endcsname + \expandafter\let\expandafter\smallcaps\csname #1sc\endcsname + \expandafter\let\expandafter\sffont \csname #1sf\endcsname + \expandafter\let\expandafter\ifont \csname #1i\endcsname + \expandafter\let\expandafter\syfont \csname #1sy\endcsname + \expandafter\let\expandafter\ttslfont\csname #1ttsl\endcsname +} + +\newif\ifrmisbold + +% Select smaller font size with the current style. Used to change font size +% in, e.g., the LaTeX logo and acronyms. If we are using bold fonts for +% normal roman text, also use bold fonts for roman text in the smaller size. +\def\switchtolllsize{% + \expandafter\assignfonts\expandafter{\lllsize}% + \ifrmisbold + \let\rmfont\bffont + \fi + \csname\curfontstyle\endcsname +}% + +\def\switchtolsize{% + \expandafter\assignfonts\expandafter{\lsize}% + \ifrmisbold + \let\rmfont\bffont + \fi + \csname\curfontstyle\endcsname +}% + +\def\definefontsetatsize#1#2#3#4#5{% +\expandafter\def\csname #1fonts\endcsname{% + \def\curfontsize{#1}% + \def\lsize{#2}\def\lllsize{#3}% + \csname rmisbold#5\endcsname + \assignfonts{#1}% + \resetmathfonts + \setleading{#4}% +}} + +\definefontsetatsize{text} {reduced}{smaller}{\textleading}{false} +\definefontsetatsize{title} {chap} {subsec} {27pt} {true} +\definefontsetatsize{chap} {sec} {text} {19pt} {true} +\definefontsetatsize{sec} {subsec} {reduced}{17pt} {true} +\definefontsetatsize{ssec} {text} {small} {15pt} {true} +\definefontsetatsize{reduced}{small} {smaller}{10.5pt}{false} +\definefontsetatsize{small} {smaller}{smaller}{10.5pt}{false} +\definefontsetatsize{smaller}{smaller}{smaller}{9.5pt} {false} + +\def\titlefont#1{{\titlefonts\rm #1}} +\let\subsecfonts = \ssecfonts +\let\subsubsecfonts = \ssecfonts + +% Define these just so they can be easily changed for other fonts. +\def\angleleft{$\langle$} +\def\angleright{$\rangle$} + +% Set the fonts to use with the @small... environments. +\let\smallexamplefonts = \smallfonts + +% About \smallexamplefonts. If we use \smallfonts (9pt), @smallexample +% can fit this many characters: +% 8.5x11=86 smallbook=72 a4=90 a5=69 +% If we use \scriptfonts (8pt), then we can fit this many characters: +% 8.5x11=90+ smallbook=80 a4=90+ a5=77 +% For me, subjectively, the few extra characters that fit aren't worth +% the additional smallness of 8pt. So I'm making the default 9pt. +% +% By the way, for comparison, here's what fits with @example (10pt): +% 8.5x11=71 smallbook=60 a4=75 a5=58 +% --karl, 24jan03. + +% Set up the default fonts, so we can use them for creating boxes. +% +\definetextfontsizexi + + +\message{markup,} + +% Check if we are currently using a typewriter font. 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 property, we can check that font parameter. +% +\def\ifmonospace{\ifdim\fontdimen3\font=0pt } + +% Markup style infrastructure. \defmarkupstylesetup\INITMACRO will +% define and register \INITMACRO to be called on markup style changes. +% \INITMACRO can check \currentmarkupstyle for the innermost +% style. + +\let\currentmarkupstyle\empty + +\def\setupmarkupstyle#1{% + \def\currentmarkupstyle{#1}% + \markupstylesetup +} + +\let\markupstylesetup\empty + +\def\defmarkupstylesetup#1{% + \expandafter\def\expandafter\markupstylesetup + \expandafter{\markupstylesetup #1}% + \def#1% +} + +% Markup style setup for left and right quotes. +\defmarkupstylesetup\markupsetuplq{% + \expandafter\let\expandafter \temp + \csname markupsetuplq\currentmarkupstyle\endcsname + \ifx\temp\relax \markupsetuplqdefault \else \temp \fi +} + +\defmarkupstylesetup\markupsetuprq{% + \expandafter\let\expandafter \temp + \csname markupsetuprq\currentmarkupstyle\endcsname + \ifx\temp\relax \markupsetuprqdefault \else \temp \fi +} + +{ +\catcode`\'=\active +\catcode`\`=\active + +\gdef\markupsetuplqdefault{\let`\lq} +\gdef\markupsetuprqdefault{\let'\rq} + +\gdef\markupsetcodequoteleft{\let`\codequoteleft} +\gdef\markupsetcodequoteright{\let'\codequoteright} +} + +\let\markupsetuplqcode \markupsetcodequoteleft +\let\markupsetuprqcode \markupsetcodequoteright +% +\let\markupsetuplqexample \markupsetcodequoteleft +\let\markupsetuprqexample \markupsetcodequoteright +% +\let\markupsetuplqkbd \markupsetcodequoteleft +\let\markupsetuprqkbd \markupsetcodequoteright +% +\let\markupsetuplqsamp \markupsetcodequoteleft +\let\markupsetuprqsamp \markupsetcodequoteright +% +\let\markupsetuplqverb \markupsetcodequoteleft +\let\markupsetuprqverb \markupsetcodequoteright +% +\let\markupsetuplqverbatim \markupsetcodequoteleft +\let\markupsetuprqverbatim \markupsetcodequoteright + +% Allow an option to not use regular directed right quote/apostrophe +% (char 0x27), but instead the undirected quote from cmtt (char 0x0d). +% The undirected quote is ugly, so don't make it the default, but it +% works for pasting with more pdf viewers (at least evince), the +% lilypond developers report. xpdf does work with the regular 0x27. +% +\def\codequoteright{% + \ifmonospace + \expandafter\ifx\csname SETtxicodequoteundirected\endcsname\relax + \expandafter\ifx\csname SETcodequoteundirected\endcsname\relax + '% + \else \char'15 \fi + \else \char'15 \fi + \else + '% + \fi +} +% +% and a similar option for the left quote char vs. a grave accent. +% Modern fonts display ASCII 0x60 as a grave accent, so some people like +% the code environments to do likewise. +% +\def\codequoteleft{% + \ifmonospace + \expandafter\ifx\csname SETtxicodequotebacktick\endcsname\relax + \expandafter\ifx\csname SETcodequotebacktick\endcsname\relax + % [Knuth] pp. 380,381,391 + % \relax disables Spanish ligatures ?` and !` of \tt font. + \relax`% + \else \char'22 \fi + \else \char'22 \fi + \else + \relax`% + \fi +} + +% Commands to set the quote options. +% +\parseargdef\codequoteundirected{% + \def\temp{#1}% + \ifx\temp\onword + \expandafter\let\csname SETtxicodequoteundirected\endcsname + = t% + \else\ifx\temp\offword + \expandafter\let\csname SETtxicodequoteundirected\endcsname + = \relax + \else + \errhelp = \EMsimple + \errmessage{Unknown @codequoteundirected value `\temp', must be on|off}% + \fi\fi +} +% +\parseargdef\codequotebacktick{% + \def\temp{#1}% + \ifx\temp\onword + \expandafter\let\csname SETtxicodequotebacktick\endcsname + = t% + \else\ifx\temp\offword + \expandafter\let\csname SETtxicodequotebacktick\endcsname + = \relax + \else + \errhelp = \EMsimple + \errmessage{Unknown @codequotebacktick value `\temp', must be on|off}% + \fi\fi +} + +% [Knuth] pp. 380,381,391, disable Spanish ligatures ?` and !` of \tt font. +\def\noligaturesquoteleft{\relax\lq} + +% Count depth in font-changes, for error checks +\newcount\fontdepth \fontdepth=0 + +% Font commands. + +% #1 is the font command (\sl or \it), #2 is the text to slant. +% If we are in a monospaced environment, however, 1) always use \ttsl, +% and 2) do not add an italic correction. +\def\dosmartslant#1#2{% + \ifusingtt + {{\ttsl #2}\let\next=\relax}% + {\def\next{{#1#2}\futurelet\next\smartitaliccorrection}}% + \next +} +\def\smartslanted{\dosmartslant\sl} +\def\smartitalic{\dosmartslant\it} + +% Output an italic correction unless \next (presumed to be the following +% character) is such as not to need one. +\def\smartitaliccorrection{% + \ifx\next,% + \else\ifx\next-% + \else\ifx\next.% + \else\ifx\next\.% + \else\ifx\next\comma% + \else\ptexslash + \fi\fi\fi\fi\fi + \aftersmartic +} + +% Unconditional use \ttsl, and no ic. @var is set to this for defuns. +\def\ttslanted#1{{\ttsl #1}} + +% @cite is like \smartslanted except unconditionally use \sl. We never want +% ttsl for book titles, do we? +\def\cite#1{{\sl #1}\futurelet\next\smartitaliccorrection} + +\def\aftersmartic{} +\def\var#1{% + \let\saveaftersmartic = \aftersmartic + \def\aftersmartic{\null\let\aftersmartic=\saveaftersmartic}% + \smartslanted{#1}% +} + +\let\i=\smartitalic +\let\slanted=\smartslanted +\let\dfn=\smartslanted +\let\emph=\smartitalic + +% Explicit font changes: @r, @sc, undocumented @ii. +\def\r#1{{\rm #1}} % roman font +\def\sc#1{{\smallcaps#1}} % smallcaps font +\def\ii#1{{\it #1}} % italic font + +% @b, explicit bold. Also @strong. +\def\b#1{{\bf #1}} +\let\strong=\b + +% @sansserif, explicit sans. +\def\sansserif#1{{\sf #1}} + +% 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 = `- } + +% Set sfcode to normal for the chars that usually have another value. +% Can't use plain's \frenchspacing because it uses the `\x notation, and +% sometimes \x has an active definition that messes things up. +% +\catcode`@=11 + \def\plainfrenchspacing{% + \sfcode`\.=\@m \sfcode`\?=\@m \sfcode`\!=\@m + \sfcode`\:=\@m \sfcode`\;=\@m \sfcode`\,=\@m + \def\endofsentencespacefactor{1000}% for @. and friends + } + \def\plainnonfrenchspacing{% + \sfcode`\.3000\sfcode`\?3000\sfcode`\!3000 + \sfcode`\:2000\sfcode`\;1500\sfcode`\,1250 + \def\endofsentencespacefactor{3000}% for @. and friends + } +\catcode`@=\other +\def\endofsentencespacefactor{3000}% default + +% @t, explicit typewriter. +\def\t#1{% + {\tt \rawbackslash \plainfrenchspacing #1}% + \null +} + +% @samp. +\def\samp#1{{\setupmarkupstyle{samp}\lq\tclose{#1}\rq\null}} + +% @indicateurl is \samp, that is, with quotes. +\let\indicateurl=\samp + +% @code (and similar) prints in typewriter, but with spaces the same +% size as normal in the surrounding text, without hyphenation, etc. +% This is a subroutine for that. +\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 + \plainfrenchspacing + #1% + }% + \null % reset spacefactor to 1000 +} + +% We *must* turn on hyphenation at `-' and `_' in @code. +% (But see \codedashfinish below.) +% Otherwise, it is too hard to avoid overfull 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 at a dash. -- rms. +{ + \catcode`\-=\active \catcode`\_=\active + \catcode`\'=\active \catcode`\`=\active + \global\let'=\rq \global\let`=\lq % default definitions + % + \global\def\code{\begingroup + \setupmarkupstyle{code}% + % The following should really be moved into \setupmarkupstyle handlers. + \catcode\dashChar=\active \catcode\underChar=\active + \ifallowcodebreaks + \let-\codedash + \let_\codeunder + \else + \let-\normaldash + \let_\realunder + \fi + % Given -foo (with a single dash), we do not want to allow a break + % after the hyphen. + \global\let\codedashprev=\codedash + % + \codex + } + % + \gdef\codedash{\futurelet\next\codedashfinish} + \gdef\codedashfinish{% + \normaldash % always output the dash character itself. + % + % Now, output a discretionary to allow a line break, unless + % (a) the next character is a -, or + % (b) the preceding character is a -. + % E.g., given --posix, we do not want to allow a break after either -. + % Given --foo-bar, we do want to allow a break between the - and the b. + \ifx\next\codedash \else + \ifx\codedashprev\codedash + \else \discretionary{}{}{}\fi + \fi + % we need the space after the = for the case when \next itself is a + % space token; it would get swallowed otherwise. As in @code{- a}. + \global\let\codedashprev= \next + } +} +\def\normaldash{-} +% +\def\codex #1{\tclose{#1}\endgroup} + +\def\codeunder{% + % this is all so @math{@code{var_name}+1} can work. In math mode, _ + % is "active" (mathcode"8000) and \normalunderscore (or \char95, etc.) + % will therefore expand the active definition of _, which is us + % (inside @code that is), therefore an endless loop. + \ifusingtt{\ifmmode + \mathchar"075F % class 0=ordinary, family 7=ttfam, pos 0x5F=_. + \else\normalunderscore \fi + \discretionary{}{}{}}% + {\_}% +} + +% An additional complication: the above will allow breaks after, e.g., +% each of the four underscores in __typeof__. This is bad. +% @allowcodebreaks provides a document-level way to turn breaking at - +% and _ on and off. +% +\newif\ifallowcodebreaks \allowcodebreakstrue + +\def\keywordtrue{true} +\def\keywordfalse{false} + +\parseargdef\allowcodebreaks{% + \def\txiarg{#1}% + \ifx\txiarg\keywordtrue + \allowcodebreakstrue + \else\ifx\txiarg\keywordfalse + \allowcodebreaksfalse + \else + \errhelp = \EMsimple + \errmessage{Unknown @allowcodebreaks option `\txiarg', must be true|false}% + \fi\fi +} + +% For @command, @env, @file, @option quotes seem unnecessary, +% so use \code rather than \samp. +\let\command=\code +\let\env=\code +\let\file=\code +\let\option=\code + +% @uref (abbreviation for `urlref') aka @url takes an optional +% (comma-separated) second argument specifying the text to display and +% an optional third arg as text to display instead of (rather than in +% addition to) the url itself. First (mandatory) arg is the url. + +% TeX-only option to allow changing PDF output to show only the second +% arg (if given), and not the url (which is then just the link target). +\newif\ifurefurlonlylink + +% The main macro is \urefbreak, which allows breaking at expected +% places within the url. (There used to be another version, which +% didn't support automatic breaking.) +\def\urefbreak{\begingroup \urefcatcodes \dourefbreak} +\let\uref=\urefbreak +% +\def\dourefbreak#1{\urefbreakfinish #1,,,\finish} +\def\urefbreakfinish#1,#2,#3,#4\finish{% doesn't work in @example + \unsepspaces + \pdfurl{#1}% + \setbox0 = \hbox{\ignorespaces #3}% + \ifdim\wd0 > 0pt + \unhbox0 % third arg given, show only that + \else + \setbox0 = \hbox{\ignorespaces #2}% look for second arg + \ifdim\wd0 > 0pt + \ifpdf + % For pdfTeX and LuaTeX + \ifurefurlonlylink + % PDF plus option to not display url, show just arg + \unhbox0 + \else + % PDF, normally display both arg and url for consistency, + % visibility, if the pdf is eventually used to print, etc. + \unhbox0\ (\urefcode{#1})% + \fi + \else + \ifx\XeTeXrevision\thisisundefined + \unhbox0\ (\urefcode{#1})% DVI, always show arg and url + \else + % For XeTeX + \ifurefurlonlylink + % PDF plus option to not display url, show just arg + \unhbox0 + \else + % PDF, normally display both arg and url for consistency, + % visibility, if the pdf is eventually used to print, etc. + \unhbox0\ (\urefcode{#1})% + \fi + \fi + \fi + \else + \urefcode{#1}% only url given, so show it + \fi + \fi + \endlink +\endgroup} + +% Allow line breaks around only a few characters (only). +\def\urefcatcodes{% + \catcode`\&=\active \catcode`\.=\active + \catcode`\#=\active \catcode`\?=\active + \catcode`\/=\active +} +{ + \urefcatcodes + % + \global\def\urefcode{\begingroup + \setupmarkupstyle{code}% + \urefcatcodes + \let&\urefcodeamp + \let.\urefcodedot + \let#\urefcodehash + \let?\urefcodequest + \let/\urefcodeslash + \codex + } + % + % By default, they are just regular characters. + \global\def&{\normalamp} + \global\def.{\normaldot} + \global\def#{\normalhash} + \global\def?{\normalquest} + \global\def/{\normalslash} +} + +% we put a little stretch before and after the breakable chars, to help +% line breaking of long url's. The unequal skips make look better in +% cmtt at least, especially for dots. +\def\urefprestretchamount{.13em} +\def\urefpoststretchamount{.1em} +\def\urefprestretch{\urefprebreak \hskip0pt plus\urefprestretchamount\relax} +\def\urefpoststretch{\urefpostbreak \hskip0pt plus\urefprestretchamount\relax} +% +\def\urefcodeamp{\urefprestretch \&\urefpoststretch} +\def\urefcodedot{\urefprestretch .\urefpoststretch} +\def\urefcodehash{\urefprestretch \#\urefpoststretch} +\def\urefcodequest{\urefprestretch ?\urefpoststretch} +\def\urefcodeslash{\futurelet\next\urefcodeslashfinish} +{ + \catcode`\/=\active + \global\def\urefcodeslashfinish{% + \urefprestretch \slashChar + % Allow line break only after the final / in a sequence of + % slashes, to avoid line break between the slashes in http://. + \ifx\next/\else \urefpoststretch \fi + } +} + +% One more complication: by default we'll break after the special +% characters, but some people like to break before the special chars, so +% allow that. Also allow no breaking at all, for manual control. +% +\parseargdef\urefbreakstyle{% + \def\txiarg{#1}% + \ifx\txiarg\wordnone + \def\urefprebreak{\nobreak}\def\urefpostbreak{\nobreak} + \else\ifx\txiarg\wordbefore + \def\urefprebreak{\allowbreak}\def\urefpostbreak{\nobreak} + \else\ifx\txiarg\wordafter + \def\urefprebreak{\nobreak}\def\urefpostbreak{\allowbreak} + \else + \errhelp = \EMsimple + \errmessage{Unknown @urefbreakstyle setting `\txiarg'}% + \fi\fi\fi +} +\def\wordafter{after} +\def\wordbefore{before} +\def\wordnone{none} + +\urefbreakstyle after + +% @url synonym for @uref, since that's how everyone uses it. +% +\let\url=\uref + +% rms does not like angle brackets --karl, 17may97. +% So now @email is just like @uref, unless we are pdf. +% +%\def\email#1{\angleleft{\tt #1}\angleright} +\ifpdf + \def\email#1{\doemail#1,,\finish} + \def\doemail#1,#2,#3\finish{\begingroup + \unsepspaces + \pdfurl{mailto:#1}% + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi + \endlink + \endgroup} +\else + \ifx\XeTeXrevision\thisisundefined + \let\email=\uref + \else + \def\email#1{\doemail#1,,\finish} + \def\doemail#1,#2,#3\finish{\begingroup + \unsepspaces + \pdfurl{mailto:#1}% + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi + \endlink + \endgroup} + \fi +\fi + +% @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always), +% `example' (@kbd uses ttsl only inside of @example and friends), +% or `code' (@kbd uses normal tty font always). +\parseargdef\kbdinputstyle{% + \def\txiarg{#1}% + \ifx\txiarg\worddistinct + \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\ttsl}% + \else\ifx\txiarg\wordexample + \gdef\kbdexamplefont{\ttsl}\gdef\kbdfont{\tt}% + \else\ifx\txiarg\wordcode + \gdef\kbdexamplefont{\tt}\gdef\kbdfont{\tt}% + \else + \errhelp = \EMsimple + \errmessage{Unknown @kbdinputstyle setting `\txiarg'}% + \fi\fi\fi +} +\def\worddistinct{distinct} +\def\wordexample{example} +\def\wordcode{code} + +% Default is `distinct'. +\kbdinputstyle distinct + +% @kbd is like @code, except that if the argument is just one @key command, +% then @kbd has no effect. +\def\kbd#1{{\def\look{#1}\expandafter\kbdsub\look??\par}} + +\def\xkey{\key} +\def\kbdsub#1#2#3\par{% + \def\one{#1}\def\three{#3}\def\threex{??}% + \ifx\one\xkey\ifx\threex\three \key{#2}% + \else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi + \else{\tclose{\kbdfont\setupmarkupstyle{kbd}\look}}\fi +} + +% definition of @key that produces a lozenge. Doesn't adjust to text size. +%\setfont\keyrm\rmshape{8}{1000}{OT1} +%\font\keysy=cmsy9 +%\def\key#1{{\keyrm\textfont2=\keysy \leavevmode\hbox{% +% \raise0.4pt\hbox{\angleleft}\kern-.08em\vtop{% +% \vbox{\hrule\kern-0.4pt +% \hbox{\raise0.4pt\hbox{\vphantom{\angleleft}}#1}}% +% \kern-0.4pt\hrule}% +% \kern-.06em\raise0.4pt\hbox{\angleright}}}} + +% definition of @key with no lozenge. If the current font is already +% monospace, don't change it; that way, we respect @kbdinputstyle. But +% if it isn't monospace, then use \tt. +% +\def\key#1{{\setupmarkupstyle{key}% + \nohyphenation + \ifmonospace\else\tt\fi + #1}\null} + +% @clicksequence{File @click{} Open ...} +\def\clicksequence#1{\begingroup #1\endgroup} + +% @clickstyle @arrow (by default) +\parseargdef\clickstyle{\def\click{#1}} +\def\click{\arrow} + +% 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} + +% @acronym for "FBI", "NATO", and the like. +% We print this one point size smaller, since it's intended for +% all-uppercase. +% +\def\acronym#1{\doacronym #1,,\finish} +\def\doacronym#1,#2,#3\finish{% + {\switchtolsize #1}% + \def\temp{#2}% + \ifx\temp\empty \else + \space ({\unsepspaces \ignorespaces \temp \unskip})% + \fi + \null % reset \spacefactor=1000 +} + +% @abbr for "Comput. J." and the like. +% No font change, but don't do end-of-sentence spacing. +% +\def\abbr#1{\doabbr #1,,\finish} +\def\doabbr#1,#2,#3\finish{% + {\plainfrenchspacing #1}% + \def\temp{#2}% + \ifx\temp\empty \else + \space ({\unsepspaces \ignorespaces \temp \unskip})% + \fi + \null % reset \spacefactor=1000 +} + +% @asis just yields its argument. Used with @table, for example. +% +\def\asis#1{#1} + +% @math outputs its argument in math mode. +% +% One complication: _ usually means subscripts, but it could also mean +% an actual _ character, as in @math{@var{some_variable} + 1}. So make +% _ active, and distinguish by seeing if the current family is \slfam, +% which is what @var uses. +{ + \catcode`\_ = \active + \gdef\mathunderscore{% + \catcode`\_=\active + \def_{\ifnum\fam=\slfam \_\else\sb\fi}% + } +} +% Another complication: we want \\ (and @\) to output a math (or tt) \. +% FYI, plain.tex uses \\ as a temporary control sequence (for no +% particular reason), but this is not advertised and we don't care. +% +% The \mathchar is class=0=ordinary, family=7=ttfam, position=5C=\. +\def\mathbackslash{\ifnum\fam=\ttfam \mathchar"075C \else\backslash \fi} +% +\def\math{% + \ifmmode\else % only go into math if not in math mode already + \tex + \mathunderscore + \let\\ = \mathbackslash + \mathactive + % make the texinfo accent commands work in math mode + \let\"=\ddot + \let\'=\acute + \let\==\bar + \let\^=\hat + \let\`=\grave + \let\u=\breve + \let\v=\check + \let\~=\tilde + \let\dotaccent=\dot + % have to provide another name for sup operator + \let\mathopsup=\sup + $\expandafter\finishmath\fi +} +\def\finishmath#1{#1$\endgroup} % Close the group opened by \tex. + +% Some active characters (such as <) are spaced differently in math. +% We have to reset their definitions in case the @math was an argument +% to a command which sets the catcodes (such as @item or @section). +% +{ + \catcode`^ = \active + \catcode`< = \active + \catcode`> = \active + \catcode`+ = \active + \catcode`' = \active + \gdef\mathactive{% + \let^ = \ptexhat + \let< = \ptexless + \let> = \ptexgtr + \let+ = \ptexplus + \let' = \ptexquoteright + } +} + +% for @sub and @sup, if in math mode, just do a normal sub/superscript. +% If in text, use math to place as sub/superscript, but switch +% into text mode, with smaller fonts. This is a different font than the +% one used for real math sub/superscripts (8pt vs. 7pt), but let's not +% fix it (significant additions to font machinery) until someone notices. +% +\def\sub{\ifmmode \expandafter\sb \else \expandafter\finishsub\fi} +\def\finishsub#1{$\sb{\hbox{\switchtolllsize #1}}$}% +% +\def\sup{\ifmmode \expandafter\ptexsp \else \expandafter\finishsup\fi} +\def\finishsup#1{$\ptexsp{\hbox{\switchtolllsize #1}}$}% + +% @inlinefmt{FMTNAME,PROCESSED-TEXT} and @inlineraw{FMTNAME,RAW-TEXT}. +% Ignore unless FMTNAME == tex; then it is like @iftex and @tex, +% except specified as a normal braced arg, so no newlines to worry about. +% +\def\outfmtnametex{tex} +% +\long\def\inlinefmt#1{\doinlinefmt #1,\finish} +\long\def\doinlinefmt#1,#2,\finish{% + \def\inlinefmtname{#1}% + \ifx\inlinefmtname\outfmtnametex \ignorespaces #2\fi +} +% +% @inlinefmtifelse{FMTNAME,THEN-TEXT,ELSE-TEXT} expands THEN-TEXT if +% FMTNAME is tex, else ELSE-TEXT. +\long\def\inlinefmtifelse#1{\doinlinefmtifelse #1,,,\finish} +\long\def\doinlinefmtifelse#1,#2,#3,#4,\finish{% + \def\inlinefmtname{#1}% + \ifx\inlinefmtname\outfmtnametex \ignorespaces #2\else \ignorespaces #3\fi +} +% +% For raw, must switch into @tex before parsing the argument, to avoid +% setting catcodes prematurely. Doing it this way means that, for +% example, @inlineraw{html, foo{bar} gets a parse error instead of being +% ignored. But this isn't important because if people want a literal +% *right* brace they would have to use a command anyway, so they may as +% well use a command to get a left brace too. We could re-use the +% delimiter character idea from \verb, but it seems like overkill. +% +\long\def\inlineraw{\tex \doinlineraw} +\long\def\doinlineraw#1{\doinlinerawtwo #1,\finish} +\def\doinlinerawtwo#1,#2,\finish{% + \def\inlinerawname{#1}% + \ifx\inlinerawname\outfmtnametex \ignorespaces #2\fi + \endgroup % close group opened by \tex. +} + +% @inlineifset{VAR, TEXT} expands TEXT if VAR is @set. +% +\long\def\inlineifset#1{\doinlineifset #1,\finish} +\long\def\doinlineifset#1,#2,\finish{% + \def\inlinevarname{#1}% + \expandafter\ifx\csname SET\inlinevarname\endcsname\relax + \else\ignorespaces#2\fi +} + +% @inlineifclear{VAR, TEXT} expands TEXT if VAR is not @set. +% +\long\def\inlineifclear#1{\doinlineifclear #1,\finish} +\long\def\doinlineifclear#1,#2,\finish{% + \def\inlinevarname{#1}% + \expandafter\ifx\csname SET\inlinevarname\endcsname\relax \ignorespaces#2\fi +} + + +\message{glyphs,} +% and logos. + +% @@ prints an @, as does @atchar{}. +\def\@{\char64 } +\let\atchar=\@ + +% @{ @} @lbracechar{} @rbracechar{} all generate brace characters. +\def\lbracechar{{\ifmonospace\char123\else\ensuremath\lbrace\fi}} +\def\rbracechar{{\ifmonospace\char125\else\ensuremath\rbrace\fi}} +\let\{=\lbracechar +\let\}=\rbracechar + +% @comma{} to avoid , parsing problems. +\let\comma = , + +% Accents: @, @dotaccent @ringaccent @ubaraccent @udotaccent +% Others are defined by plain TeX: @` @' @" @^ @~ @= @u @v @H. +\let\, = \ptexc +\let\dotaccent = \ptexdot +\def\ringaccent#1{{\accent23 #1}} +\let\tieaccent = \ptext +\let\ubaraccent = \ptexb +\let\udotaccent = \d + +% Other special characters: @questiondown @exclamdown @ordf @ordm +% Plain TeX defines: @AA @AE @O @OE @L (plus lowercase versions) @ss. +\def\questiondown{?`} +\def\exclamdown{!`} +\def\ordf{\leavevmode\raise1ex\hbox{\switchtolllsize \underbar{a}}} +\def\ordm{\leavevmode\raise1ex\hbox{\switchtolllsize \underbar{o}}} + +% Dotless i and dotless j, used for accents. +\def\imacro{i} +\def\jmacro{j} +\def\dotless#1{% + \def\temp{#1}% + \ifx\temp\imacro \ifmmode\imath \else\ptexi \fi + \else\ifx\temp\jmacro \ifmmode\jmath \else\j \fi + \else \errmessage{@dotless can be used only with i or j}% + \fi\fi +} + +% The \TeX{} logo, as in plain, but resetting the spacing so that a +% period following counts as ending a sentence. (Idea found in latex.) +% +\edef\TeX{\TeX \spacefactor=1000 } + +% @LaTeX{} logo. Not quite the same results as the definition in +% latex.ltx, since we use a different font for the raised A; it's most +% convenient for us to use an explicitly smaller font, rather than using +% the \scriptstyle font (since we don't reset \scriptstyle and +% \scriptscriptstyle). +% +\def\LaTeX{% + L\kern-.36em + {\setbox0=\hbox{T}% + \vbox to \ht0{\hbox{% + \ifx\textnominalsize\xwordpt + % for 10pt running text, lllsize (8pt) is too small for the A in LaTeX. + % Revert to plain's \scriptsize, which is 7pt. + \count255=\the\fam $\fam\count255 \scriptstyle A$% + \else + % For 11pt, we can use our lllsize. + \switchtolllsize A% + \fi + }% + \vss + }}% + \kern-.15em + \TeX +} + +% Some math mode symbols. Define \ensuremath to switch into math mode +% unless we are already there. Expansion tricks may not be needed here, +% but safer, and can't hurt. +\def\ensuremath{\ifmmode \expandafter\asis \else\expandafter\ensuredmath \fi} +\def\ensuredmath#1{$\relax#1$} +% +\def\bullet{\ensuremath\ptexbullet} +\def\geq{\ensuremath\ge} +\def\leq{\ensuremath\le} +\def\minus{\ensuremath-} + +% @dots{} outputs an ellipsis using the current font. +% We do .5em per period so that it has the same spacing in the cm +% typewriter fonts as three actual period characters; on the other hand, +% in other typewriter fonts three periods are wider than 1.5em. So do +% whichever is larger. +% +\def\dots{% + \leavevmode + \setbox0=\hbox{...}% get width of three periods + \ifdim\wd0 > 1.5em + \dimen0 = \wd0 + \else + \dimen0 = 1.5em + \fi + \hbox to \dimen0{% + \hskip 0pt plus.25fil + .\hskip 0pt plus1fil + .\hskip 0pt plus1fil + .\hskip 0pt plus.5fil + }% +} + +% @enddots{} is an end-of-sentence ellipsis. +% +\def\enddots{% + \dots + \spacefactor=\endofsentencespacefactor +} + +% @point{}, @result{}, @expansion{}, @print{}, @equiv{}. +% +% Since these characters are used in examples, they should be an even number of +% \tt widths. Each \tt character is 1en, so two makes it 1em. +% +\def\point{$\star$} +\def\arrow{\leavevmode\raise.05ex\hbox to 1em{\hfil$\rightarrow$\hfil}} +\def\result{\leavevmode\raise.05ex\hbox to 1em{\hfil$\Rightarrow$\hfil}} +\def\expansion{\leavevmode\hbox to 1em{\hfil$\mapsto$\hfil}} +\def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}} +\def\equiv{\leavevmode\hbox to 1em{\hfil$\ptexequiv$\hfil}} + +% The @error{} command. +% Adapted from the TeXbook's \boxit. +% +\newbox\errorbox +% +{\ttfont \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 \reducedsf \putworderror\kern-1.5pt} +% +\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} +% +\def\error{\leavevmode\lower.7ex\copy\errorbox} + +% @pounds{} is a sterling sign, which Knuth put in the CM italic font. +% +\def\pounds{{\it\$}} + +% @euro{} comes from a separate font, depending on the current style. +% We use the free feym* fonts from the eurosym package by Henrik +% Theiling, which support regular, slanted, bold and bold slanted (and +% "outlined" (blackboard board, sort of) versions, which we don't need). +% It is available from http://www.ctan.org/tex-archive/fonts/eurosym. +% +% Although only regular is the truly official Euro symbol, we ignore +% that. The Euro is designed to be slightly taller than the regular +% font height. +% +% feymr - regular +% feymo - slanted +% feybr - bold +% feybo - bold slanted +% +% There is no good (free) typewriter version, to my knowledge. +% A feymr10 euro is ~7.3pt wide, while a normal cmtt10 char is ~5.25pt wide. +% Hmm. +% +% Also doesn't work in math. Do we need to do math with euro symbols? +% Hope not. +% +% +\def\euro{{\eurofont e}} +\def\eurofont{% + % We set the font at each command, rather than predefining it in + % \textfonts and the other font-switching commands, so that + % installations which never need the symbol don't have to have the + % font installed. + % + % There is only one designed size (nominal 10pt), so we always scale + % that to the current nominal size. + % + % By the way, simply using "at 1em" works for cmr10 and the like, but + % does not work for cmbx10 and other extended/shrunken fonts. + % + \def\eurosize{\csname\curfontsize nominalsize\endcsname}% + % + \ifx\curfontstyle\bfstylename + % bold: + \font\thiseurofont = \ifusingit{feybo10}{feybr10} at \eurosize + \else + % regular: + \font\thiseurofont = \ifusingit{feymo10}{feymr10} at \eurosize + \fi + \thiseurofont +} + +% Glyphs from the EC fonts. We don't use \let for the aliases, because +% sometimes we redefine the original macro, and the alias should reflect +% the redefinition. +% +% Use LaTeX names for the Icelandic letters. +\def\DH{{\ecfont \char"D0}} % Eth +\def\dh{{\ecfont \char"F0}} % eth +\def\TH{{\ecfont \char"DE}} % Thorn +\def\th{{\ecfont \char"FE}} % thorn +% +\def\guillemetleft{{\ecfont \char"13}} +\def\guillemotleft{\guillemetleft} +\def\guillemetright{{\ecfont \char"14}} +\def\guillemotright{\guillemetright} +\def\guilsinglleft{{\ecfont \char"0E}} +\def\guilsinglright{{\ecfont \char"0F}} +\def\quotedblbase{{\ecfont \char"12}} +\def\quotesinglbase{{\ecfont \char"0D}} +% +% This positioning is not perfect (see the ogonek LaTeX package), but +% we have the precomposed glyphs for the most common cases. We put the +% tests to use those glyphs in the single \ogonek macro so we have fewer +% dummy definitions to worry about for index entries, etc. +% +% ogonek is also used with other letters in Lithuanian (IOU), but using +% the precomposed glyphs for those is not so easy since they aren't in +% the same EC font. +\def\ogonek#1{{% + \def\temp{#1}% + \ifx\temp\macrocharA\Aogonek + \else\ifx\temp\macrochara\aogonek + \else\ifx\temp\macrocharE\Eogonek + \else\ifx\temp\macrochare\eogonek + \else + \ecfont \setbox0=\hbox{#1}% + \ifdim\ht0=1ex\accent"0C #1% + \else\ooalign{\unhbox0\crcr\hidewidth\char"0C \hidewidth}% + \fi + \fi\fi\fi\fi + }% +} +\def\Aogonek{{\ecfont \char"81}}\def\macrocharA{A} +\def\aogonek{{\ecfont \char"A1}}\def\macrochara{a} +\def\Eogonek{{\ecfont \char"86}}\def\macrocharE{E} +\def\eogonek{{\ecfont \char"A6}}\def\macrochare{e} +% +% Use the European Computer Modern fonts (cm-super in outline format) +% for non-CM glyphs. That is ec* for regular text and tc* for the text +% companion symbols (LaTeX TS1 encoding). Both are part of the ec +% package and follow the same conventions. +% +\def\ecfont{\etcfont{e}} +\def\tcfont{\etcfont{t}} +% +\def\etcfont#1{% + % We can't distinguish serif/sans and italic/slanted, but this + % is used for crude hacks anyway (like adding French and German + % quotes to documents typeset with CM, where we lose kerning), so + % hopefully nobody will notice/care. + \edef\ecsize{\csname\curfontsize ecsize\endcsname}% + \edef\nominalsize{\csname\curfontsize nominalsize\endcsname}% + \ifmonospace + % typewriter: + \font\thisecfont = #1ctt\ecsize \space at \nominalsize + \else + \ifx\curfontstyle\bfstylename + % bold: + \font\thisecfont = #1cb\ifusingit{i}{x}\ecsize \space at \nominalsize + \else + % regular: + \font\thisecfont = #1c\ifusingit{ti}{rm}\ecsize \space at \nominalsize + \fi + \fi + \thisecfont +} + +% @registeredsymbol - R in a circle. The font for the R should really +% be smaller yet, but lllsize is the best we can do for now. +% Adapted from the plain.tex definition of \copyright. +% +\def\registeredsymbol{% + $^{{\ooalign{\hfil\raise.07ex\hbox{\switchtolllsize R}% + \hfil\crcr\Orb}}% + }$% +} + +% @textdegree - the normal degrees sign. +% +\def\textdegree{$^\circ$} + +% Laurent Siebenmann reports \Orb undefined with: +% Textures 1.7.7 (preloaded format=plain 93.10.14) (68K) 16 APR 2004 02:38 +% so we'll define it if necessary. +% +\ifx\Orb\thisisundefined +\def\Orb{\mathhexbox20D} +\fi + +% Quotes. +\chardef\quotedblleft="5C +\chardef\quotedblright=`\" +\chardef\quoteleft=`\` +\chardef\quoteright=`\' + + +\message{page headings,} + +\newskip\titlepagetopglue \titlepagetopglue = 1.5in +\newskip\titlepagebottomglue \titlepagebottomglue = 2pc + +% First the title page. Must do @settitle before @titlepage. +\newif\ifseenauthor +\newif\iffinishedtitlepage + +% @setcontentsaftertitlepage used to do an implicit @contents or +% @shortcontents after @end titlepage, but it is now obsolete. +\def\setcontentsaftertitlepage{% + \errmessage{@setcontentsaftertitlepage has been removed as a Texinfo + command; move your @contents command if you want the contents + after the title page.}}% +\def\setshortcontentsaftertitlepage{% + \errmessage{@setshortcontentsaftertitlepage has been removed as a Texinfo + command; move your @shortcontents and @contents commands if you + want the contents after the title page.}}% + +\parseargdef\shorttitlepage{% + \begingroup \hbox{}\vskip 1.5in \chaprm \centerline{#1}% + \endgroup\page\hbox{}\page} + +\envdef\titlepage{% + % Open one extra group, as we want to close it in the middle of \Etitlepage. + \begingroup + \parindent=0pt \textfonts + % Leave some space at the very top of the page. + \vglue\titlepagetopglue + % No rule at page bottom unless we print one at the top with @title. + \finishedtitlepagetrue + % + % 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 + \let\page = \oldpage + \page + \null + }% +} + +\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 + % + % Need this before the \...aftertitlepage checks so that if they are + % in effect the toc pages will come out with page numbers. + \HEADINGSon +} + +\def\finishtitlepage{% + \vskip4pt \hrule height 2pt width \hsize + \vskip\titlepagebottomglue + \finishedtitlepagetrue +} + +% Settings used for typesetting titles: no hyphenation, no indentation, +% don't worry much about spacing, ragged right. This should be used +% inside a \vbox, and fonts need to be set appropriately first. \par should +% be specified before the end of the \vbox, since a vbox is a group. +% +\def\raggedtitlesettings{% + \rm + \hyphenpenalty=10000 + \parindent=0pt + \tolerance=5000 + \ptexraggedright +} + +% Macros to be used within @titlepage: + +\let\subtitlerm=\rmfont +\def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines} + +\parseargdef\title{% + \checkenv\titlepage + \vbox{\titlefonts \raggedtitlesettings #1\par}% + % print a rule at the page bottom also. + \finishedtitlepagefalse + \vskip4pt \hrule height 4pt width \hsize \vskip4pt +} + +\parseargdef\subtitle{% + \checkenv\titlepage + {\subtitlefont \rightline{#1}}% +} + +% @author should come last, but may come many times. +% It can also be used inside @quotation. +% +\parseargdef\author{% + \def\temp{\quotation}% + \ifx\thisenv\temp + \def\quotationauthor{#1}% printed in \Equotation. + \else + \checkenv\titlepage + \ifseenauthor\else \vskip 0pt plus 1filll \seenauthortrue \fi + {\secfonts\rm \leftline{#1}}% + \fi +} + + +% Set up page headings and footings. + +\let\thispage=\folio + +\newtoks\evenheadline % headline on even pages +\newtoks\oddheadline % headline on odd pages +\newtoks\evenfootline % footline on even pages +\newtoks\oddfootline % footline on odd pages + +% Now make \makeheadline and \makefootline in Plain 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\evenheadingxxx #1{\evenheadingyyy #1\|\|\|\|\finish} +\def\evenheadingyyy #1\|#2\|#3\|#4\finish{% +\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + +\def\oddheading{\parsearg\oddheadingxxx} +\def\oddheadingxxx #1{\oddheadingyyy #1\|\|\|\|\finish} +\def\oddheadingyyy #1\|#2\|#3\|#4\finish{% +\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + +\parseargdef\everyheading{\oddheadingxxx{#1}\evenheadingxxx{#1}}% + +\def\evenfooting{\parsearg\evenfootingxxx} +\def\evenfootingxxx #1{\evenfootingyyy #1\|\|\|\|\finish} +\def\evenfootingyyy #1\|#2\|#3\|#4\finish{% +\global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}} + +\def\oddfooting{\parsearg\oddfootingxxx} +\def\oddfootingxxx #1{\oddfootingyyy #1\|\|\|\|\finish} +\def\oddfootingyyy #1\|#2\|#3\|#4\finish{% + \global\oddfootline = {\rlap{\centerline{#2}}\line{#1\hfil#3}}% + % + % Leave some space for the footline. Hopefully ok to assume + % @evenfooting will not be used by itself. + \global\advance\txipageheight by -12pt + \global\advance\vsize by -12pt +} + +\parseargdef\everyfooting{\oddfootingxxx{#1}\evenfootingxxx{#1}} + +% @evenheadingmarks top \thischapter <- chapter at the top of a page +% @evenheadingmarks bottom \thischapter <- chapter at the bottom of a page +% +% The same set of arguments for: +% +% @oddheadingmarks +% @evenfootingmarks +% @oddfootingmarks +% @everyheadingmarks +% @everyfootingmarks + +% These define \getoddheadingmarks, \getevenheadingmarks, +% \getoddfootingmarks, and \getevenfootingmarks, each to one of +% \gettopheadingmarks, \getbottomheadingmarks. +% +\def\evenheadingmarks{\headingmarks{even}{heading}} +\def\oddheadingmarks{\headingmarks{odd}{heading}} +\def\evenfootingmarks{\headingmarks{even}{footing}} +\def\oddfootingmarks{\headingmarks{odd}{footing}} +\parseargdef\everyheadingmarks{\headingmarks{even}{heading}{#1} + \headingmarks{odd}{heading}{#1} } +\parseargdef\everyfootingmarks{\headingmarks{even}{footing}{#1} + \headingmarks{odd}{footing}{#1} } +% #1 = even/odd, #2 = heading/footing, #3 = top/bottom. +\def\headingmarks#1#2#3 {% + \expandafter\let\expandafter\temp \csname get#3headingmarks\endcsname + \global\expandafter\let\csname get#1#2marks\endcsname \temp +} + +\everyheadingmarks bottom +\everyfootingmarks bottom + +% @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 at the start of a document, +% and turned `on' after @end titlepage. + +\parseargdef\headings{\csname HEADINGS#1\endcsname} + +\def\headingsoff{% non-global headings elimination + \evenheadline={\hfil}\evenfootline={\hfil}% + \oddheadline={\hfil}\oddfootline={\hfil}% +} + +\def\HEADINGSoff{{\globaldefs=1 \headingsoff}} % global setting +\HEADINGSoff % it's the default + +% 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{% +\global\pageno=1 +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\folio\hfil\thistitle}} +\global\oddheadline={\line{\thischapterheading\hfil\folio}} +\global\let\contentsalignmacro = \chapoddpage +} +\let\contentsalignmacro = \chappager + +% For single-sided printing, chapter title goes across top left of page, +% page number on top right. +\def\HEADINGSsingle{% +\global\pageno=1 +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\thischapterheading\hfil\folio}} +\global\oddheadline={\line{\thischapterheading\hfil\folio}} +\global\let\contentsalignmacro = \chappager +} +\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{\thischapterheading\hfil\folio}} +\global\let\contentsalignmacro = \chapoddpage +} + +\def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex} +\def\HEADINGSsinglex{% +\global\evenfootline={\hfil} +\global\oddfootline={\hfil} +\global\evenheadline={\line{\thischapterheading\hfil\folio}} +\global\oddheadline={\line{\thischapterheading\hfil\folio}} +\global\let\contentsalignmacro = \chappager +} + +% Subroutines used in generating headings +% This produces Day Month Year style of output. +% Only define if not already defined, in case a txi-??.tex file has set +% up a different format (e.g., txi-cs.tex does this). +\ifx\today\thisisundefined +\def\today{% + \number\day\space + \ifcase\month + \or\putwordMJan\or\putwordMFeb\or\putwordMMar\or\putwordMApr + \or\putwordMMay\or\putwordMJun\or\putwordMJul\or\putwordMAug + \or\putwordMSep\or\putwordMOct\or\putwordMNov\or\putwordMDec + \fi + \space\number\year} +\fi + +% @settitle line... specifies the title of the document, for headings. +% It generates no output of its own. +\def\thistitle{\putwordNoTitle} +\def\settitle{\parsearg{\gdef\thistitle}} + + +\message{tables,} +% Tables -- @table, @ftable, @vtable, @item(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, @ftable, 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\nobreak\vskip-\parskip\nobreak\fi} + +\def\internalBitem{\smallbreak \parsearg\itemzzz} +\def\internalBitemx{\itemxpar \parsearg\itemzzz} + +\def\itemzzz #1{\begingroup % + \advance\hsize by -\rightskip + \advance\hsize by -\tableindent + \setbox0=\hbox{\itemindicate{#1}}% + \itemindex{#1}% + \nobreak % This prevents a break before @itemx. + % + % 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\relax + \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. However, if + % what follows is an environment such as @example, there will be no + % \parskip glue; then the negative vskip we just inserted would + % cause the example and the item to crash together. So we use this + % bizarre value of 10001 as a signal to \aboveenvbreak to insert + % \parskip glue after all. Section titles are handled this way also. + % + \penalty 10001 + \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. + \noindent + % Do this with kerns and \unhbox so that if there is a footnote in + % the item text, it can migrate to the main vertical list and + % eventually be printed. + \nobreak\kern-\tableindent + \dimen0 = \itemmax \advance\dimen0 by \itemmargin \advance\dimen0 by -\wd0 + \unhbox0 + \nobreak\kern\dimen0 + \endgroup + \itemxneedsnegativevskiptrue + \fi +} + +\def\item{\errmessage{@item while not in a list environment}} +\def\itemx{\errmessage{@itemx while not in a list environment}} + +% @table, @ftable, @vtable. +\envdef\table{% + \let\itemindex\gobble + \tablecheck{table}% +} +\envdef\ftable{% + \def\itemindex ##1{\doind {fn}{\code{##1}}}% + \tablecheck{ftable}% +} +\envdef\vtable{% + \def\itemindex ##1{\doind {vr}{\code{##1}}}% + \tablecheck{vtable}% +} +\def\tablecheck#1{% + \ifnum \the\catcode`\^^M=\active + \endgroup + \errmessage{This command won't work in this context; perhaps the problem is + that we are \inenvironment\thisenv}% + \def\next{\doignore{#1}}% + \else + \let\next\tablex + \fi + \next +} +\def\tablex#1{% + \def\itemindicate{#1}% + \parsearg\tabley +} +\def\tabley#1{% + {% + \makevalueexpandable + \edef\temp{\noexpand\tablez #1\space\space\space}% + \expandafter + }\temp \endtablez +} +\def\tablez #1 #2 #3 #4\endtablez{% + \aboveenvbreak + \ifnum 0#1>0 \advance \leftskip by #1\mil \fi + \ifnum 0#2>0 \tableindent=#2\mil \fi + \ifnum 0#3>0 \advance \rightskip by #3\mil \fi + \itemmax=\tableindent + \advance \itemmax by -\itemmargin + \advance \leftskip by \tableindent + \exdentamount=\tableindent + \parindent = 0pt + \parskip = \smallskipamount + \ifdim \parskip=0pt \parskip=2pt \fi + \let\item = \internalBitem + \let\itemx = \internalBitemx +} +\def\Etable{\endgraf\afterenvbreak} +\let\Eftable\Etable +\let\Evtable\Etable +\let\Eitemize\Etable +\let\Eenumerate\Etable + +% This is the counter used by @enumerate, which is really @itemize + +\newcount \itemno + +\envdef\itemize{\parsearg\doitemize} + +\def\doitemize#1{% + \aboveenvbreak + \itemmax=\itemindent + \advance\itemmax by -\itemmargin + \advance\leftskip by \itemindent + \exdentamount=\itemindent + \parindent=0pt + \parskip=\smallskipamount + \ifdim\parskip=0pt \parskip=2pt \fi + % + % Try typesetting the item mark so that if the document erroneously says + % something like @itemize @samp (intending @table), there's an error + % right away at the @itemize. It's not the best error message in the + % world, but it's better than leaving it to the @item. This means if + % the user wants an empty mark, they have to say @w{} not just @w. + \def\itemcontents{#1}% + \setbox0 = \hbox{\itemcontents}% + % + % @itemize with no arg is equivalent to @itemize @bullet. + \ifx\itemcontents\empty\def\itemcontents{\bullet}\fi + % + \let\item=\itemizeitem +} + +% Definition of @item while inside @itemize and @enumerate. +% +\def\itemizeitem{% + \advance\itemno by 1 % for enumerations + {\let\par=\endgraf \smallbreak}% reasonable place to break + {% + % If the document has an @itemize directly after a section title, a + % \nobreak will be last on the list, and \sectionheading will have + % done a \vskip-\parskip. In that case, we don't want to zero + % parskip, or the item text will crash with the heading. On the + % other hand, when there is normal text preceding the item (as there + % usually is), we do want to zero parskip, or there would be too much + % space. In that case, we won't have a \nobreak before. At least + % that's the theory. + \ifnum\lastpenalty<10000 \parskip=0in \fi + \noindent + \hbox to 0pt{\hss \itemcontents \kern\itemmargin}% + % + \ifinner\else + \vadjust{\penalty 1200}% not good to break after first line of item. + \fi + % We can be in inner vertical mode in a footnote, although an + % @itemize looks awful there. + }% + \flushcr +} + +% \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'. +% +\envparseargdef\enumerate{\enumeratey #1 \endenumeratey} +\def\enumeratey #1 #2\endenumeratey{% + % 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 \doitemize, 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 + \doitemize{#1.}\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} + + +% @multitable macros +% Amy Hendrickson, 8/18/94, 3/6/96 +% +% @multitable ... @end multitable 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 @columnfractions .25 .3 .45 +% @item ... +% +% Numbers following @columnfractions 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 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. +% @end multitable + +% Default dimensions may be reset by user. +% @multitableparskip is vertical space between paragraphs in table. +% @multitableparindent is paragraph indent in table. +% @multitablecolmargin is horizontal space to be left between columns. +% @multitablelinespace is space to leave between table items, baseline +% to baseline. +% 0pt means it depends on current normal line spacing. +% +\newskip\multitableparskip +\newskip\multitableparindent +\newdimen\multitablecolspace +\newskip\multitablelinespace +\multitableparskip=0pt +\multitableparindent=6pt +\multitablecolspace=12pt +\multitablelinespace=0pt + +% Macros used to set up halign preamble: +% +\let\endsetuptable\relax +\def\xendsetuptable{\endsetuptable} +\let\columnfractions\relax +\def\xcolumnfractions{\columnfractions} +\newif\ifsetpercent + +% #1 is the @columnfraction, usually a decimal number like .5, but might +% be just 1. We just use it, whatever it is. +% +\def\pickupwholefraction#1 {% + \global\advance\colcount by 1 + \expandafter\xdef\csname col\the\colcount\endcsname{#1\hsize}% + \setuptable +} + +\newcount\colcount +\def\setuptable#1{% + \def\firstarg{#1}% + \ifx\firstarg\xendsetuptable + \let\go = \relax + \else + \ifx\firstarg\xcolumnfractions + \global\setpercenttrue + \else + \ifsetpercent + \let\go\pickupwholefraction + \else + \global\advance\colcount by 1 + \setbox0=\hbox{#1\unskip\space}% Add a normal word space as a + % separator; typically that is always in the input, anyway. + \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}% + \fi + \fi + \ifx\go\pickupwholefraction + % Put the argument back for the \pickupwholefraction call, so + % we'll always have a period there to be parsed. + \def\go{\pickupwholefraction#1}% + \else + \let\go = \setuptable + \fi% + \fi + \go +} + +% multitable-only commands. +% +% @headitem starts a heading row, which we typeset in bold. Assignments +% have to be global since we are inside the implicit group of an +% alignment entry. \everycr below resets \everytab so we don't have to +% undo it ourselves. +\def\headitemfont{\b}% for people to use in the template row; not changeable +\def\headitem{% + \checkenv\multitable + \crcr + \gdef\headitemcrhook{\nobreak}% attempt to avoid page break after headings + \global\everytab={\bf}% can't use \headitemfont since the parsing differs + \the\everytab % for the first item +}% +% +% default for tables with no headings. +\let\headitemcrhook=\relax +% +% A \tab used to include \hskip1sp. But then the space in a template +% line is not enough. That is bad. So let's go back to just `&' until +% we again encounter the problem the 1sp was intended to solve. +% --karl, nathan@acm.org, 20apr99. +\def\tab{\checkenv\multitable &\the\everytab}% + +% @multitable ... @end multitable definitions: +% +\newtoks\everytab % insert after every tab. +% +\envdef\multitable{% + \vskip\parskip + \startsavinginserts + % + % @item within a multitable starts a normal row. + % We use \def instead of \let so that if one of the multitable entries + % contains an @itemize, we don't choke on the \item (seen as \crcr aka + % \endtemplate) expanding \doitemize. + \def\item{\crcr}% + % + \tolerance=9500 + \hbadness=9500 + \setmultitablespacing + \parskip=\multitableparskip + \parindent=\multitableparindent + \overfullrule=0pt + \global\colcount=0 + % + \everycr = {% + \noalign{% + \global\everytab={}% Reset from possible headitem. + \global\colcount=0 % Reset the column counter. + % + % Check for saved footnotes, etc.: + \checkinserts + % + % Perhaps a \nobreak, then reset: + \headitemcrhook + \global\let\headitemcrhook=\relax + }% + }% + % + \parsearg\domultitable +} +\def\domultitable#1{% + % To parse everything between @multitable and @item: + \setuptable#1 \endsetuptable + % + % 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 + \multistrut + \vtop{% + % Use the current \colcount to find the correct column width: + \hsize=\expandafter\csname col\the\colcount\endcsname + % + % In order to keep entries from bumping into each other + % we will add a \leftskip of \multitablecolspace to all columns after + % the first one. + % + % If a template has been used, we will add \multitablecolspace + % to the width of each template entry. + % + % If the 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. + % + % Make sure we don't inherit \rightskip from the outer environment. + \rightskip=0pt + \ifnum\colcount=1 + % The first column will be indented with the surrounding text. + \advance\hsize by\leftskip + \else + \ifsetpercent \else + % If user has not set preamble in terms of percent of \hsize + % we will advance \hsize by \multitablecolspace. + \advance\hsize by \multitablecolspace + \fi + % In either case we will make \leftskip=\multitablecolspace: + \leftskip=\multitablecolspace + \fi + % Ignoring space at the beginning and end avoids an occasional spurious + % blank line, when TeX decides to break the line at the space before the + % box from the multistrut, so the strut ends up on a line by itself. + % For example: + % @multitable @columnfractions .11 .89 + % @item @code{#} + % @tab Legal holiday which is valid in major parts of the whole country. + % Is automatically provided with highlighting sequences respectively + % marking characters. + \noindent\ignorespaces##\unskip\multistrut + }\cr +} +\def\Emultitable{% + \crcr + \egroup % end the \halign + \global\setpercentfalse +} + +\def\setmultitablespacing{% + \def\multistrut{\strut}% just use the standard line spacing + % + % Compute \multitablelinespace (if not defined by user) for use in + % \multitableparskip calculation. We used define \multistrut based on + % this, but (ironically) that caused the spacing to be off. + % See bug-texinfo report from Werner Lemberg, 31 Oct 2004 12:52:20 +0100. +\ifdim\multitablelinespace=0pt +\setbox0=\vbox{X}\global\multitablelinespace=\the\baselineskip +\global\advance\multitablelinespace by-\ht0 +\fi +% Test to see if parskip is larger than space between lines of +% table. If not, do nothing. +% If so, set to same dimension as multitablelinespace. +\ifdim\multitableparskip>\multitablelinespace +\global\multitableparskip=\multitablelinespace +\global\advance\multitableparskip-7pt % to keep parskip somewhat smaller + % than skip between lines in the table. +\fi% +\ifdim\multitableparskip=0pt +\global\multitableparskip=\multitablelinespace +\global\advance\multitableparskip-7pt % to keep parskip somewhat smaller + % than skip between lines in the table. +\fi} + + +\message{conditionals,} + +% @iftex, @ifnotdocbook, @ifnothtml, @ifnotinfo, @ifnotplaintext, +% @ifnotxml always succeed. They currently do nothing; we don't +% attempt to check whether the conditionals are properly nested. But we +% have to remember that they are conditionals, so that @end doesn't +% attempt to close an environment group. +% +\def\makecond#1{% + \expandafter\let\csname #1\endcsname = \relax + \expandafter\let\csname iscond.#1\endcsname = 1 +} +\makecond{iftex} +\makecond{ifnotdocbook} +\makecond{ifnothtml} +\makecond{ifnotinfo} +\makecond{ifnotplaintext} +\makecond{ifnotxml} + +% Ignore @ignore, @ifhtml, @ifinfo, and the like. +% +\def\direntry{\doignore{direntry}} +\def\documentdescription{\doignore{documentdescription}} +\def\docbook{\doignore{docbook}} +\def\html{\doignore{html}} +\def\ifdocbook{\doignore{ifdocbook}} +\def\ifhtml{\doignore{ifhtml}} +\def\ifinfo{\doignore{ifinfo}} +\def\ifnottex{\doignore{ifnottex}} +\def\ifplaintext{\doignore{ifplaintext}} +\def\ifxml{\doignore{ifxml}} +\def\ignore{\doignore{ignore}} +\def\menu{\doignore{menu}} +\def\xml{\doignore{xml}} + +% Ignore text until a line `@end #1', keeping track of nested conditionals. +% +% A count to remember the depth of nesting. +\newcount\doignorecount + +\def\doignore#1{\begingroup + % Scan in ``verbatim'' mode: + \obeylines + \catcode`\@ = \other + \catcode`\{ = \other + \catcode`\} = \other + % + % Make sure that spaces turn into tokens that match what \doignoretext wants. + \spaceisspace + % + % Count number of #1's that we've seen. + \doignorecount = 0 + % + % Swallow text until we reach the matching `@end #1'. + \dodoignore{#1}% +} + +{ \catcode`_=11 % We want to use \_STOP_ which cannot appear in texinfo source. + \obeylines % + % + \gdef\dodoignore#1{% + % #1 contains the command name as a string, e.g., `ifinfo'. + % + % Define a command to find the next `@end #1'. + \long\def\doignoretext##1^^M@end #1{% + \doignoretextyyy##1^^M@#1\_STOP_}% + % + % And this command to find another #1 command, at the beginning of a + % line. (Otherwise, we would consider a line `@c @ifset', for + % example, to count as an @ifset for nesting.) + \long\def\doignoretextyyy##1^^M@#1##2\_STOP_{\doignoreyyy{##2}\_STOP_}% + % + % And now expand that command. + \doignoretext ^^M% + }% +} + +\def\doignoreyyy#1{% + \def\temp{#1}% + \ifx\temp\empty % Nothing found. + \let\next\doignoretextzzz + \else % Found a nested condition, ... + \advance\doignorecount by 1 + \let\next\doignoretextyyy % ..., look for another. + % If we're here, #1 ends with ^^M\ifinfo (for example). + \fi + \next #1% the token \_STOP_ is present just after this macro. +} + +% We have to swallow the remaining "\_STOP_". +% +\def\doignoretextzzz#1{% + \ifnum\doignorecount = 0 % We have just found the outermost @end. + \let\next\enddoignore + \else % Still inside a nested condition. + \advance\doignorecount by -1 + \let\next\doignoretext % Look for the next @end. + \fi + \next +} + +% Finish off ignored text. +{ \obeylines% + % Ignore anything after the last `@end #1'; this matters in verbatim + % environments, where otherwise the newline after an ignored conditional + % would result in a blank line in the output. + \gdef\enddoignore#1^^M{\endgroup\ignorespaces}% +} + + +% @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. +% We rely on the fact that \parsearg sets \catcode`\ =10. +% +\parseargdef\set{\setyyy#1 \endsetyyy} +\def\setyyy#1 #2\endsetyyy{% + {% + \makevalueexpandable + \def\temp{#2}% + \edef\next{\gdef\makecsname{SET#1}}% + \ifx\temp\empty + \next{}% + \else + \setzzz#2\endsetzzz + \fi + }% +} +% Remove the trailing space \setxxx inserted. +\def\setzzz#1 \endsetzzz{\next{#1}} + +% @clear VAR clears (i.e., unsets) the variable VAR. +% +\parseargdef\clear{% + {% + \makevalueexpandable + \global\expandafter\let\csname SET#1\endcsname=\relax + }% +} + +% @value{foo} gets the text saved in variable foo. +\def\value{\begingroup\makevalueexpandable\valuexxx} +\def\valuexxx#1{\expandablevalue{#1}\endgroup} +{ + \catcode`\-=\active \catcode`\_=\active + % + \gdef\makevalueexpandable{% + \let\value = \expandablevalue + % We don't want these characters active, ... + \catcode`\-=\other \catcode`\_=\other + % ..., but we might end up with active ones in the argument if + % we're called from @code, as @code{@value{foo-bar_}}, though. + % So \let them to their normal equivalents. + \let-\normaldash \let_\normalunderscore + } +} + +% We have this subroutine so that we can handle at least some @value's +% properly in indexes (we call \makevalueexpandable in \indexdummies). +% The command has to be fully expandable (if the variable is set), since +% the result winds up in the index file. This means that if the +% variable's value contains other Texinfo commands, it's almost certain +% it will fail (although perhaps we could fix that with sufficient work +% to do a one-level expansion on the result, instead of complete). +% +% Unfortunately, this has the consequence that when _ is in the *value* +% of an @set, it does not print properly in the roman fonts (get the cmr +% dot accent at position 126 instead). No fix comes to mind, and it's +% been this way since 2003 or earlier, so just ignore it. +% +\def\expandablevalue#1{% + \expandafter\ifx\csname SET#1\endcsname\relax + {[No value for ``#1'']}% + \message{Variable `#1', used in @value, is not set.}% + \else + \csname SET#1\endcsname + \fi +} + +% Like \expandablevalue, but completely expandable (the \message in the +% definition above operates at the execution level of TeX). Used when +% writing to auxiliary files, due to the expansion that \write does. +% If flag is undefined, pass through an unexpanded @value command: maybe it +% will be set by the time it is read back in. +% +% NB flag names containing - or _ may not work here. +\def\dummyvalue#1{% + \expandafter\ifx\csname SET#1\endcsname\relax + \noexpand\value{#1}% + \else + \csname SET#1\endcsname + \fi +} + +% Used for @value's in index entries to form the sort key: expand the @value +% if possible, otherwise sort late. +\def\indexnofontsvalue#1{% + \expandafter\ifx\csname SET#1\endcsname\relax + ZZZZZZZ + \else + \csname SET#1\endcsname + \fi +} + +% @ifset VAR ... @end ifset reads the `...' iff VAR has been defined +% with @set. +% +% To get the special treatment we need for `@end ifset,' we call +% \makecond and then redefine. +% +\makecond{ifset} +\def\ifset{\parsearg{\doifset{\let\next=\ifsetfail}}} +\def\doifset#1#2{% + {% + \makevalueexpandable + \let\next=\empty + \expandafter\ifx\csname SET#2\endcsname\relax + #1% If not set, redefine \next. + \fi + \expandafter + }\next +} +\def\ifsetfail{\doignore{ifset}} + +% @ifclear VAR ... @end executes the `...' iff VAR has never been +% defined with @set, or has been undefined with @clear. +% +% The `\else' inside the `\doifset' parameter is a trick to reuse the +% above code: if the variable is not set, do nothing, if it is set, +% then redefine \next to \ifclearfail. +% +\makecond{ifclear} +\def\ifclear{\parsearg{\doifset{\else \let\next=\ifclearfail}}} +\def\ifclearfail{\doignore{ifclear}} + +% @ifcommandisdefined CMD ... @end executes the `...' if CMD (written +% without the @) is in fact defined. We can only feasibly check at the +% TeX level, so something like `mathcode' is going to considered +% defined even though it is not a Texinfo command. +% +\makecond{ifcommanddefined} +\def\ifcommanddefined{\parsearg{\doifcmddefined{\let\next=\ifcmddefinedfail}}} +% +\def\doifcmddefined#1#2{{% + \makevalueexpandable + \let\next=\empty + \expandafter\ifx\csname #2\endcsname\relax + #1% If not defined, \let\next as above. + \fi + \expandafter + }\next +} +\def\ifcmddefinedfail{\doignore{ifcommanddefined}} + +% @ifcommandnotdefined CMD ... handled similar to @ifclear above. +\makecond{ifcommandnotdefined} +\def\ifcommandnotdefined{% + \parsearg{\doifcmddefined{\else \let\next=\ifcmdnotdefinedfail}}} +\def\ifcmdnotdefinedfail{\doignore{ifcommandnotdefined}} + +% Set the `txicommandconditionals' variable, so documents have a way to +% test if the @ifcommand...defined conditionals are available. +\set txicommandconditionals + +% @dircategory CATEGORY -- specify a category of the dir file +% which this file should belong to. Ignore this in TeX. +\let\dircategory=\comment + +% @defininfoenclose. +\let\definfoenclose=\comment + + +\message{indexing,} +% Index generation facilities + +% Define \newwrite to be identical to plain tex's \newwrite +% except not \outer, so it can be used within macros and \if's. +\edef\newwrite{\makecsname{ptexnewwrite}} + +% \newindex {foo} defines an index named IX. +% It automatically defines \IXindex such that +% \IXindex ...rest of line... puts an entry in the index IX. +% It also defines \IXindfile to be the number of the output channel for +% the file that accumulates this index. The file's extension is IX. +% The name of an index should be no more than 2 characters long +% for the sake of vms. +% +\def\newindex#1{% + \expandafter\chardef\csname#1indfile\endcsname=0 + \expandafter\xdef\csname#1index\endcsname{% % Define @#1index + \noexpand\doindex{#1}} +} + +% @defindex foo == \newindex{foo} +% +\def\defindex{\parsearg\newindex} + +% Define @defcodeindex, like @defindex except put all entries in @code. +% +\def\defcodeindex{\parsearg\newcodeindex} +% +\def\newcodeindex#1{% + \expandafter\chardef\csname#1indfile\endcsname=0 + \expandafter\xdef\csname#1index\endcsname{% + \noexpand\docodeindex{#1}}% +} + +% The default indices: +\newindex{cp}% concepts, +\newcodeindex{fn}% functions, +\newcodeindex{vr}% variables, +\newcodeindex{tp}% types, +\newcodeindex{ky}% keys +\newcodeindex{pg}% and programs. + + +% @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. +% +% @syncodeindex foo bar similar, but put all entries made for index foo +% inside @code. +% +\def\synindex#1 #2 {\dosynindex\doindex{#1}{#2}} +\def\syncodeindex#1 #2 {\dosynindex\docodeindex{#1}{#2}} + +% #1 is \doindex or \docodeindex, #2 the index getting redefined (foo), +% #3 the target index (bar). +\def\dosynindex#1#2#3{% + \requireopenindexfile{#3}% + % redefine \fooindfile: + \expandafter\let\expandafter\temp\expandafter=\csname#3indfile\endcsname + \expandafter\let\csname#2indfile\endcsname=\temp + % redefine \fooindex: + \expandafter\xdef\csname#2index\endcsname{\noexpand#1{#3}}% +} + +% Define \doindex, the driver for all index macros. +% Argument #1 is generated by the calling \fooindex macro, +% and it is the two-letter name of the index. + +\def\doindex#1{\edef\indexname{#1}\parsearg\doindexxxx} +\def\doindexxxx #1{\doind{\indexname}{#1}} + +% like the previous two, but they put @code around the argument. +\def\docodeindex#1{\edef\indexname{#1}\parsearg\docodeindexxxx} +\def\docodeindexxxx #1{\doind{\indexname}{\code{#1}}} + + +% Used when writing an index entry out to an index file to prevent +% expansion of Texinfo commands that can appear in an index entry. +% +\def\indexdummies{% + \escapechar = `\\ % use backslash in output files. + \definedummyletter\@% + \definedummyletter\ % + % + % For texindex which always views { and } as separators. + \def\{{\lbracechar{}}% + \def\}{\rbracechar{}}% + % + % Do the redefinitions. + \definedummies +} + +% Used for the aux and toc files, where @ is the escape character. +% +\def\atdummies{% + \definedummyletter\@% + \definedummyletter\ % + \definedummyletter\{% + \definedummyletter\}% + % + % Do the redefinitions. + \definedummies + \otherbackslash +} + +% \definedummyword defines \#1 as \string\#1\space, thus effectively +% preventing its expansion. This is used only for control words, +% not control letters, because the \space would be incorrect for +% control characters, but is needed to separate the control word +% from whatever follows. +% +% These can be used both for control words that take an argument and +% those that do not. If it is followed by {arg} in the input, then +% that will dutifully get written to the index (or wherever). +% +% For control letters, we have \definedummyletter, which omits the +% space. +% +\def\definedummyword #1{\def#1{\string#1\space}}% +\def\definedummyletter#1{\def#1{\string#1}}% +\let\definedummyaccent\definedummyletter + +% Called from \indexdummies and \atdummies, to effectively prevent +% the expansion of commands. +% +\def\definedummies{% + % + \let\commondummyword\definedummyword + \let\commondummyletter\definedummyletter + \let\commondummyaccent\definedummyaccent + \commondummiesnofonts + % + \definedummyletter\_% + \definedummyletter\-% + % + % Non-English letters. + \definedummyword\AA + \definedummyword\AE + \definedummyword\DH + \definedummyword\L + \definedummyword\O + \definedummyword\OE + \definedummyword\TH + \definedummyword\aa + \definedummyword\ae + \definedummyword\dh + \definedummyword\exclamdown + \definedummyword\l + \definedummyword\o + \definedummyword\oe + \definedummyword\ordf + \definedummyword\ordm + \definedummyword\questiondown + \definedummyword\ss + \definedummyword\th + % + % Although these internal commands shouldn't show up, sometimes they do. + \definedummyword\bf + \definedummyword\gtr + \definedummyword\hat + \definedummyword\less + \definedummyword\sf + \definedummyword\sl + \definedummyword\tclose + \definedummyword\tt + % + \definedummyword\LaTeX + \definedummyword\TeX + % + % Assorted special characters. + \definedummyword\atchar + \definedummyword\arrow + \definedummyword\bullet + \definedummyword\comma + \definedummyword\copyright + \definedummyword\registeredsymbol + \definedummyword\dots + \definedummyword\enddots + \definedummyword\entrybreak + \definedummyword\equiv + \definedummyword\error + \definedummyword\euro + \definedummyword\expansion + \definedummyword\geq + \definedummyword\guillemetleft + \definedummyword\guillemetright + \definedummyword\guilsinglleft + \definedummyword\guilsinglright + \definedummyword\lbracechar + \definedummyword\leq + \definedummyword\mathopsup + \definedummyword\minus + \definedummyword\ogonek + \definedummyword\pounds + \definedummyword\point + \definedummyword\print + \definedummyword\quotedblbase + \definedummyword\quotedblleft + \definedummyword\quotedblright + \definedummyword\quoteleft + \definedummyword\quoteright + \definedummyword\quotesinglbase + \definedummyword\rbracechar + \definedummyword\result + \definedummyword\sub + \definedummyword\sup + \definedummyword\textdegree + % + % We want to disable all macros so that they are not expanded by \write. + \macrolist + \let\value\dummyvalue + % + \normalturnoffactive +} + +% \commondummiesnofonts: common to \definedummies and \indexnofonts. +% Define \commondummyletter, \commondummyaccent and \commondummyword before +% using. Used for accents, font commands, and various control letters. +% +\def\commondummiesnofonts{% + % Control letters and accents. + \commondummyletter\!% + \commondummyaccent\"% + \commondummyaccent\'% + \commondummyletter\*% + \commondummyaccent\,% + \commondummyletter\.% + \commondummyletter\/% + \commondummyletter\:% + \commondummyaccent\=% + \commondummyletter\?% + \commondummyaccent\^% + \commondummyaccent\`% + \commondummyaccent\~% + \commondummyword\u + \commondummyword\v + \commondummyword\H + \commondummyword\dotaccent + \commondummyword\ogonek + \commondummyword\ringaccent + \commondummyword\tieaccent + \commondummyword\ubaraccent + \commondummyword\udotaccent + \commondummyword\dotless + % + % Texinfo font commands. + \commondummyword\b + \commondummyword\i + \commondummyword\r + \commondummyword\sansserif + \commondummyword\sc + \commondummyword\slanted + \commondummyword\t + % + % Commands that take arguments. + \commondummyword\abbr + \commondummyword\acronym + \commondummyword\anchor + \commondummyword\cite + \commondummyword\code + \commondummyword\command + \commondummyword\dfn + \commondummyword\dmn + \commondummyword\email + \commondummyword\emph + \commondummyword\env + \commondummyword\file + \commondummyword\image + \commondummyword\indicateurl + \commondummyword\inforef + \commondummyword\kbd + \commondummyword\key + \commondummyword\math + \commondummyword\option + \commondummyword\pxref + \commondummyword\ref + \commondummyword\samp + \commondummyword\strong + \commondummyword\tie + \commondummyword\U + \commondummyword\uref + \commondummyword\url + \commondummyword\var + \commondummyword\verb + \commondummyword\w + \commondummyword\xref +} + +% For testing: output @{ and @} in index sort strings as \{ and \}. +\newif\ifusebracesinindexes + +\let\indexlbrace\relax +\let\indexrbrace\relax + +{\catcode`\@=0 +\catcode`\\=13 + @gdef@backslashdisappear{@def\{}} +} + +{ +\catcode`\<=13 +\catcode`\-=13 +\catcode`\`=13 + \gdef\indexnonalnumdisappear{% + \expandafter\ifx\csname SETtxiindexlquoteignore\endcsname\relax\else + % @set txiindexlquoteignore makes us ignore left quotes in the sort term. + % (Introduced for FSFS 2nd ed.) + \let`=\empty + \fi + % + \expandafter\ifx\csname SETtxiindexbackslashignore\endcsname\relax\else + \backslashdisappear + \fi + % + \expandafter\ifx\csname SETtxiindexhyphenignore\endcsname\relax\else + \def-{}% + \fi + \expandafter\ifx\csname SETtxiindexlessthanignore\endcsname\relax\else + \def<{}% + \fi + \expandafter\ifx\csname SETtxiindexatsignignore\endcsname\relax\else + \def\@{}% + \fi + } + + \gdef\indexnonalnumreappear{% + \useindexbackslash + \let-\normaldash + \let<\normalless + \def\@{@}% + } +} + + +% \indexnofonts is used when outputting the strings to sort the index +% by, and when constructing control sequence names. It eliminates all +% control sequences and just writes whatever the best ASCII sort string +% would be for a given command (usually its argument). +% +\def\indexnofonts{% + % Accent commands should become @asis. + \def\commondummyaccent##1{\let##1\asis}% + % We can just ignore other control letters. + \def\commondummyletter##1{\let##1\empty}% + % All control words become @asis by default; overrides below. + \let\commondummyword\commondummyaccent + \commondummiesnofonts + % + % Don't no-op \tt, since it isn't a user-level command + % and is used in the definitions of the active chars like <, >, |, etc. + % Likewise with the other plain tex font commands. + %\let\tt=\asis + % + \def\ { }% + \def\@{@}% + \def\_{\normalunderscore}% + \def\-{}% @- shouldn't affect sorting + % + \uccode`\1=`\{ \uppercase{\def\{{1}}% + \uccode`\1=`\} \uppercase{\def\}{1}}% + \let\lbracechar\{% + \let\rbracechar\}% + % + % Non-English letters. + \def\AA{AA}% + \def\AE{AE}% + \def\DH{DZZ}% + \def\L{L}% + \def\OE{OE}% + \def\O{O}% + \def\TH{TH}% + \def\aa{aa}% + \def\ae{ae}% + \def\dh{dzz}% + \def\exclamdown{!}% + \def\l{l}% + \def\oe{oe}% + \def\ordf{a}% + \def\ordm{o}% + \def\o{o}% + \def\questiondown{?}% + \def\ss{ss}% + \def\th{th}% + % + \def\LaTeX{LaTeX}% + \def\TeX{TeX}% + % + % Assorted special characters. \defglyph gives the control sequence a + % definition that removes the {} that follows its use. + \defglyph\atchar{@}% + \defglyph\arrow{->}% + \defglyph\bullet{bullet}% + \defglyph\comma{,}% + \defglyph\copyright{copyright}% + \defglyph\dots{...}% + \defglyph\enddots{...}% + \defglyph\equiv{==}% + \defglyph\error{error}% + \defglyph\euro{euro}% + \defglyph\expansion{==>}% + \defglyph\geq{>=}% + \defglyph\guillemetleft{<<}% + \defglyph\guillemetright{>>}% + \defglyph\guilsinglleft{<}% + \defglyph\guilsinglright{>}% + \defglyph\leq{<=}% + \defglyph\lbracechar{\{}% + \defglyph\minus{-}% + \defglyph\point{.}% + \defglyph\pounds{pounds}% + \defglyph\print{-|}% + \defglyph\quotedblbase{"}% + \defglyph\quotedblleft{"}% + \defglyph\quotedblright{"}% + \defglyph\quoteleft{`}% + \defglyph\quoteright{'}% + \defglyph\quotesinglbase{,}% + \defglyph\rbracechar{\}}% + \defglyph\registeredsymbol{R}% + \defglyph\result{=>}% + \defglyph\textdegree{o}% + % + % We need to get rid of all macros, leaving only the arguments (if present). + % Of course this is not nearly correct, but it is the best we can do for now. + % makeinfo does not expand macros in the argument to @deffn, which ends up + % writing an index entry, and texindex isn't prepared for an index sort entry + % that starts with \. + % + % Since macro invocations are followed by braces, we can just redefine them + % to take a single TeX argument. The case of a macro invocation that + % goes to end-of-line is not handled. + % + \macrolist + \let\value\indexnofontsvalue +} +\def\defglyph#1#2{\def#1##1{#2}} % see above + + + + +\let\SETmarginindex=\relax % put index entries in margin (undocumented)? + +% Most index entries go through here, but \dosubind is the general case. +% #1 is the index name, #2 is the entry text. +\def\doind#1#2{\dosubind{#1}{#2}{}} + +% There is also \dosubind {index}{topic}{subtopic} +% which makes an entry in a two-level index such as the operation index. +% TODO: Two-level index? Operation index? + +% Workhorse for all indexes. +% #1 is name of index, #2 is stuff to put there, #3 is subentry -- +% empty if called from \doind, as we usually are (the main exception +% is with most defuns, which call us directly). +% +\def\dosubind#1#2#3{% + \iflinks + {% + \requireopenindexfile{#1}% + % Store the main index entry text (including the third arg). + \toks0 = {#2}% + % If third arg is present, precede it with a space. + \def\thirdarg{#3}% + \ifx\thirdarg\empty \else + \toks0 = \expandafter{\the\toks0 \space #3}% + \fi + % + \edef\writeto{\csname#1indfile\endcsname}% + % + \safewhatsit\dosubindwrite + }% + \fi +} + +% Check if an index file has been opened, and if not, open it. +\def\requireopenindexfile#1{% +\ifnum\csname #1indfile\endcsname=0 + \expandafter\newwrite \csname#1indfile\endcsname + \edef\suffix{#1}% + % A .fls suffix would conflict with the file extension for the output + % of -recorder, so use .f1s instead. + \ifx\suffix\indexisfl\def\suffix{f1}\fi + % Open the file + \immediate\openout\csname#1indfile\endcsname \jobname.\suffix + % Using \immediate above here prevents an object entering into the current + % box, which could confound checks such as those in \safewhatsit for + % preceding skips. + \typeout{Writing index file \jobname.\suffix}% +\fi} +\def\indexisfl{fl} + +% Output \ as {\indexbackslash}, because \ is an escape character in +% the index files. +\let\indexbackslash=\relax +{\catcode`\@=0 \catcode`\\=\active + @gdef@useindexbackslash{@def\{{@indexbackslash}}} +} + +% Definition for writing index entry text. +\def\sortas#1{\ignorespaces}% + +% Definition for writing index entry sort key. Should occur at the at +% the beginning of the index entry, like +% @cindex @sortas{september} \september +% The \ignorespaces takes care of following space, but there's no way +% to remove space before it. +{ +\catcode`\-=13 +\gdef\indexwritesortas{% + \begingroup + \indexnonalnumreappear + \indexwritesortasxxx} +\gdef\indexwritesortasxxx#1{% + \xdef\indexsortkey{#1}\endgroup} +} + + +% Write the entry in \toks0 to the index file. +% +\def\dosubindwrite{% + % Put the index entry in the margin if desired. + \ifx\SETmarginindex\relax\else + \insert\margin{\hbox{\vrule height8pt depth3pt width0pt \the\toks0}}% + \fi + % + % Remember, we are within a group. + \indexdummies % Must do this here, since \bf, etc expand at this stage + \useindexbackslash % \indexbackslash isn't defined now so it will be output + % as is; and it will print as backslash. + % The braces around \indexbrace are recognized by texindex. + % + % Get the string to sort by, by processing the index entry with all + % font commands turned off. + {\indexnofonts + \def\lbracechar{{\indexlbrace}}% + \def\rbracechar{{\indexrbrace}}% + \let\{=\lbracechar + \let\}=\rbracechar + \indexnonalnumdisappear + \xdef\indexsortkey{}% + \let\sortas=\indexwritesortas + \edef\temp{\the\toks0}% + \setbox\dummybox = \hbox{\temp}% Make sure to execute any \sortas + \ifx\indexsortkey\empty + \xdef\indexsortkey{\temp}% + \ifx\indexsortkey\empty\xdef\indexsortkey{ }\fi + \fi + }% + % + % Set up the complete index entry, with both the sort key and + % the original text, including any font commands. We write + % three arguments to \entry to the .?? file (four in the + % subentry case), texindex reduces to two when writing the .??s + % sorted result. + \edef\temp{% + \write\writeto{% + \string\entry{\indexsortkey}{\noexpand\folio}{\the\toks0}}% + }% + \temp +} +\newbox\dummybox % used above + +% Take care of unwanted page breaks/skips around a whatsit: +% +% If a skip is the last thing on the list now, preserve it +% by backing up by \lastskip, doing the \write, then inserting +% the skip again. Otherwise, the whatsit generated by the +% \write or \pdfdest will make \lastskip zero. The result is that +% sequences like this: +% @end defun +% @tindex whatever +% @defun ... +% will have extra space inserted, because the \medbreak in the +% start of the @defun won't see the skip inserted by the @end of +% the previous defun. +% +% But don't do any of this if we're not in vertical mode. We +% don't want to do a \vskip and prematurely end a paragraph. +% +% Avoid page breaks due to these extra skips, too. +% +% But wait, there is a catch there: +% We'll have to check whether \lastskip is zero skip. \ifdim is not +% sufficient for this purpose, as it ignores stretch and shrink parts +% of the skip. The only way seems to be to check the textual +% representation of the skip. +% +% The following is almost like \def\zeroskipmacro{0.0pt} except that +% the ``p'' and ``t'' characters have catcode \other, not 11 (letter). +% +\edef\zeroskipmacro{\expandafter\the\csname z@skip\endcsname} +% +\newskip\whatsitskip +\newcount\whatsitpenalty +% +% ..., ready, GO: +% +\def\safewhatsit#1{\ifhmode + #1% + \else + % \lastskip and \lastpenalty cannot both be nonzero simultaneously. + \whatsitskip = \lastskip + \edef\lastskipmacro{\the\lastskip}% + \whatsitpenalty = \lastpenalty + % + % If \lastskip is nonzero, that means the last item was a + % skip. And since a skip is discardable, that means this + % -\whatsitskip glue we're inserting is preceded by a + % non-discardable item, therefore it is not a potential + % breakpoint, therefore no \nobreak needed. + \ifx\lastskipmacro\zeroskipmacro + \else + \vskip-\whatsitskip + \fi + % + #1% + % + \ifx\lastskipmacro\zeroskipmacro + % If \lastskip was zero, perhaps the last item was a penalty, and + % perhaps it was >=10000, e.g., a \nobreak. In that case, we want + % to re-insert the same penalty (values >10000 are used for various + % signals); since we just inserted a non-discardable item, any + % following glue (such as a \parskip) would be a breakpoint. For example: + % @deffn deffn-whatever + % @vindex index-whatever + % Description. + % would allow a break between the index-whatever whatsit + % and the "Description." paragraph. + \ifnum\whatsitpenalty>9999 \penalty\whatsitpenalty \fi + \else + % On the other hand, if we had a nonzero \lastskip, + % this make-up glue would be preceded by a non-discardable item + % (the whatsit from the \write), so we must insert a \nobreak. + \nobreak\vskip\whatsitskip + \fi +\fi} + +% 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. + +% @printindex causes a particular index (the ??s file) to get printed. +% It does not print any chapter heading (usually an @unnumbered). +% +\parseargdef\printindex{\begingroup + \dobreak \chapheadingskip{10000}% + % + \smallfonts \rm + \tolerance = 9500 + \plainfrenchspacing + \everypar = {}% don't want the \kern\-parindent from indentation suppression. + % + % See if the index file exists and is nonempty. + % Change catcode of @ here so that if the index file contains + % \initial {@} + % as its first line, TeX doesn't complain about mismatched braces + % (because it thinks @} is a control sequence). + \catcode`\@ = 12 + % See comment in \requireopenindexfile. + \def\indexname{#1}\ifx\indexname\indexisfl\def\indexname{f1}\fi + \openin 1 \jobname.\indexname s + \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. + \putwordIndexNonexistent + \typeout{No file \jobname.\indexname s.}% + \else + \catcode`\\ = 0 + % + % 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 \thisline + \ifeof 1 + \putwordIndexIsEmpty + \else + % Index files are almost Texinfo source, but we use \ as the escape + % character. It would be better to use @, but that's too big a change + % to make right now. + \def\indexbackslash{\ttbackslash}% + \let\indexlbrace\{ % Likewise, set these sequences for braces + \let\indexrbrace\} % used in the sort key. + \begindoublecolumns + \let\dotheinsertentrybox\dotheinsertentryboxwithpenalty + % + % Read input from the index file line by line. + \loopdo + \ifeof1 \else + \read 1 to \nextline + \fi + % + \indexinputprocessing + \thisline + % + \ifeof1\else + \let\thisline\nextline + \repeat + %% + \enddoublecolumns + \fi + \fi + \closein 1 +\endgroup} +\def\loopdo#1\repeat{\def\body{#1}\loopdoxxx} +\def\loopdoxxx{\let\next=\relax\body\let\next=\loopdoxxx\fi\next} + +\def\indexinputprocessing{% + \ifeof1 + \let\firsttoken\relax + \else + \edef\act{\gdef\noexpand\firsttoken{\getfirsttoken\nextline}}% + \act + \fi +} +\def\getfirsttoken#1{\expandafter\getfirsttokenx#1\endfirsttoken} +\long\def\getfirsttokenx#1#2\endfirsttoken{\noexpand#1} + + +% These macros are used by the sorted index file itself. +% Change them to control the appearance of the index. + +{\catcode`\/=13 \catcode`\-=13 \catcode`\^=13 \catcode`\~=13 \catcode`\_=13 +\catcode`\|=13 \catcode`\<=13 \catcode`\>=13 \catcode`\+=13 \catcode`\"=13 +\catcode`\$=3 +\gdef\initialglyphs{% + % Some changes for non-alphabetic characters. Using the glyphs from the + % math fonts looks more consistent than the typewriter font used elsewhere + % for these characters. + \def\indexbackslash{\math{\backslash}}% + \let\\=\indexbackslash + % + % Can't get bold backslash so don't use bold forward slash + \catcode`\/=13 + \def/{{\secrmnotbold \normalslash}}% + \def-{{\normaldash\normaldash}}% en dash `--' + \def^{{\chapbf \normalcaret}}% + \def~{{\chapbf \normaltilde}}% + \def\_{% + \leavevmode \kern.07em \vbox{\hrule width.3em height.1ex}\kern .07em }% + \def|{$\vert$}% + \def<{$\less$}% + \def>{$\gtr$}% + \def+{$\normalplus$}% +}} + +\def\initial{% + \bgroup + \initialglyphs + \initialx +} + +\def\initialx#1{% + % Remove any glue we may have, we'll be inserting our own. + \removelastskip + % + % We like breaks before the index initials, so insert a bonus. + % The glue before the bonus allows a little bit of space at the + % bottom of a column to reduce an increase in inter-line spacing. + \nobreak + \vskip 0pt plus 5\baselineskip + \penalty -300 + \vskip 0pt plus -5\baselineskip + % + % Typeset the initial. Making this add up to a whole number of + % baselineskips increases the chance of the dots lining up from column + % to column. It still won't often be perfect, because of the stretch + % we need before each entry, but it's better. + % + % No shrink because it confuses \balancecolumns. + \vskip 1.67\baselineskip plus 1\baselineskip + \leftline{\secfonts \kern-0.05em \secbf #1}% + % \secfonts is inside the argument of \leftline so that the change of + % \baselineskip will not affect any glue inserted before the vbox that + % \leftline creates. + % Do our best not to break after the initial. + \nobreak + \vskip .33\baselineskip plus .1\baselineskip + \egroup % \initialglyphs +} + +\newdimen\entryrightmargin +\entryrightmargin=0pt + +% \entry typesets a paragraph consisting of the text (#1), dot leaders, and +% then page number (#2) flushed to the right margin. It is used for index +% and table of contents entries. The paragraph is indented by \leftskip. +% +\def\entry{% + \begingroup + % + % For pdfTeX and XeTeX. + % The redefinition of \domark stops marks being added in \pdflink to + % preserve coloured links across page boundaries. Otherwise the marks + % would get in the way of \lastbox in \insertentrybox. + \let\domark\relax + % + % Start a new paragraph if necessary, so our assignments below can't + % affect previous text. + \par + % + % No extra space above this paragraph. + \parskip = 0in + % + % When reading the text of entry, convert explicit line breaks + % from @* into spaces. The user might give these in long section + % titles, for instance. + \def\*{\unskip\space\ignorespaces}% + \def\entrybreak{\hfil\break}% An undocumented command + % + % Swallow the left brace of the text (first parameter): + \afterassignment\doentry + \let\temp = +} +\def\entrybreak{\unskip\space\ignorespaces}% +\def\doentry{% + % Save the text of the entry + \global\setbox\boxA=\hbox\bgroup + \bgroup % Instead of the swallowed brace. + \noindent + \aftergroup\finishentry + % And now comes the text of the entry. + % Not absorbing as a macro argument reduces the chance of problems + % with catcodes occurring. +} +{\catcode`\@=11 +\gdef\finishentry#1{% + \egroup % end box A + \dimen@ = \wd\boxA % Length of text of entry + \global\setbox\boxA=\hbox\bgroup\unhbox\boxA + % #1 is the page number. + % + % Get the width of the page numbers, and only use + % leaders if they are present. + \global\setbox\boxB = \hbox{#1}% + \ifdim\wd\boxB = 0pt + \null\nobreak\hfill\ % + \else + % + \null\nobreak\indexdotfill % Have leaders before the page number. + % + \ifpdf + \pdfgettoks#1.% + \hskip\skip\thinshrinkable\the\toksA + \else + \ifx\XeTeXrevision\thisisundefined + \hskip\skip\thinshrinkable #1% + \else + \pdfgettoks#1.% + \hskip\skip\thinshrinkable\the\toksA + \fi + \fi + \fi + \egroup % end \boxA + \ifdim\wd\boxB = 0pt + \global\setbox\entrybox=\vbox{\unhbox\boxA}% + \else + \global\setbox\entrybox=\vbox\bgroup + % We want the text of the entries to be aligned to the left, and the + % page numbers to be aligned to the right. + % + \parindent = 0pt + \advance\leftskip by 0pt plus 1fil + \advance\leftskip by 0pt plus -1fill + \rightskip = 0pt plus -1fil + \advance\rightskip by 0pt plus 1fill + % Cause last line, which could consist of page numbers on their own + % if the list of page numbers is long, to be aligned to the right. + \parfillskip=0pt plus -1fill + % + \advance\rightskip by \entryrightmargin + % Determine how far we can stretch into the margin. + % This allows, e.g., "Appendix H GNU Free Documentation License" to + % fit on one line in @letterpaper format. + \ifdim\entryrightmargin>2.1em + \dimen@i=2.1em + \else + \dimen@i=0em + \fi + \advance \parfillskip by 0pt minus 1\dimen@i + % + \dimen@ii = \hsize + \advance\dimen@ii by -1\leftskip + \advance\dimen@ii by -1\entryrightmargin + \advance\dimen@ii by 1\dimen@i + \ifdim\wd\boxA > \dimen@ii % If the entry doesn't fit in one line + \ifdim\dimen@ > 0.8\dimen@ii % due to long index text + % Try to split the text roughly evenly. \dimen@ will be the length of + % the first line. + \dimen@ = 0.7\dimen@ + \dimen@ii = \hsize + \ifnum\dimen@>\dimen@ii + % If the entry is too long (for example, if it needs more than + % two lines), use all the space in the first line. + \dimen@ = \dimen@ii + \fi + \advance\leftskip by 0pt plus 1fill % ragged right + \advance \dimen@ by 1\rightskip + \parshape = 2 0pt \dimen@ 0em \dimen@ii + % Ideally we'd add a finite glue at the end of the first line only, + % instead of using \parshape with explicit line lengths, but TeX + % doesn't seem to provide a way to do such a thing. + % + % Indent all lines but the first one. + \advance\leftskip by 1em + \advance\parindent by -1em + \fi\fi + \indent % start paragraph + \unhbox\boxA + % + % Do not prefer a separate line ending with a hyphen to fewer lines. + \finalhyphendemerits = 0 + % + % Word spacing - no stretch + \spaceskip=\fontdimen2\font minus \fontdimen4\font + % + \linepenalty=1000 % Discourage line breaks. + \hyphenpenalty=5000 % Discourage hyphenation. + % + \par % format the paragraph + \egroup % The \vbox + \fi + \endgroup + \dotheinsertentrybox +}} + +\newskip\thinshrinkable +\skip\thinshrinkable=.15em minus .15em + +\newbox\entrybox +\def\insertentrybox{% + \ourunvbox\entrybox +} + +% default definition +\let\dotheinsertentrybox\insertentrybox + +% Use \lastbox to take apart vbox box by box, and add each sub-box +% to the current vertical list. +\def\ourunvbox#1{% +\bgroup % for local binding of \delayedbox + % Remove the last box from box #1 + \global\setbox#1=\vbox{% + \unvbox#1% + \unskip % remove any glue + \unpenalty + \global\setbox\interbox=\lastbox + }% + \setbox\delayedbox=\box\interbox + \ifdim\ht#1=0pt\else + \ourunvbox#1 % Repeat on what's left of the box + \nobreak + \fi + \box\delayedbox +\egroup +} +\newbox\delayedbox +\newbox\interbox + +% Used from \printindex. \firsttoken should be the first token +% after the \entry. If it's not another \entry, we are at the last +% line of a group of index entries, so insert a penalty to discourage +% widowed index entries. +\def\dotheinsertentryboxwithpenalty{% + \ifx\firsttoken\isentry + \else + \penalty 9000 + \fi + \insertentrybox +} +\def\isentry{\entry}% + +% Like plain.tex's \dotfill, except uses up at least 1 em. +% The filll stretch here overpowers both the fil and fill stretch to push +% the page number to the right. +\def\indexdotfill{\cleaders + \hbox{$\mathsurround=0pt \mkern1.5mu.\mkern1.5mu$}\hskip 1em plus 1filll} + + +\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 + \ifpdf + \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph. + \else + \ifx\XeTeXrevision\thisisundefined + #2 + \else + \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph. + \fi + \fi + \par +}} + +% Define two-column mode, which we use to typeset indexes. +% Adapted from the TeXbook, page 416, which is to say, +% the manmac.tex format used to print the TeXbook itself. +\catcode`\@=11 % private names + +\newbox\partialpage +\newdimen\doublecolumnhsize + +% Use inside an output routine to save \topmark and \firstmark +\def\savemarks{% + \global\savedtopmark=\expandafter{\topmark }% + \global\savedfirstmark=\expandafter{\firstmark }% +} +\newtoks\savedtopmark +\newtoks\savedfirstmark + +% Set \topmark and \firstmark for next time \output runs. +% Can't be run from withinside \output (because any material +% added while an output routine is active, including +% penalties, is saved for after it finishes). The page so far +% should be empty, otherwise what's on it will be thrown away. +\def\restoremarks{% + \mark{\the\savedtopmark}% + \bgroup\output = {% + \setbox\dummybox=\box\PAGE + }abc\eject\egroup + % "abc" because output routine doesn't fire for a completely empty page. + \mark{\the\savedfirstmark}% +} + +\def\begindoublecolumns{\begingroup % ended by \enddoublecolumns + % If not much space left on page, start a new page. + \ifdim\pagetotal>0.8\vsize\vfill\eject\fi + % + % Grab any single-column material above us. + \output = {% + % + % Here is a possibility not foreseen in manmac: if we accumulate a + % whole lot of material, we might end up calling this \output + % routine twice in a row (see the doublecol-lose test, which is + % essentially a couple of indexes with @setchapternewpage off). In + % that case we just ship out what is in \partialpage with the normal + % output routine. Generally, \partialpage will be empty when this + % runs and this will be a no-op. See the indexspread.tex test case. + \ifvoid\partialpage \else + \onepageout{\pagecontents\partialpage}% + \fi + % + \global\setbox\partialpage = \vbox{% + % Unvbox the main output page. + \unvbox\PAGE + \kern-\topskip \kern\baselineskip + }% + \savemarks + }% + \eject % run that output routine to set \partialpage + \restoremarks + % + % We recover the two marks that the last output routine saved in order + % to propagate the information in marks added around a chapter heading, + % which could be otherwise be lost by the time the final page is output. + % + % + % Use the double-column output routine for subsequent pages. + \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 in one place. + % + % 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. + \advance\vsize by -\ht\partialpage + \vsize = 2\vsize + % + % For the benefit of balancing columns + \advance\baselineskip by 0pt plus 0.5pt +} + +% The double-column output routine for all double-column pages except +% the last, which is done by \balancecolumns. +% +\def\doublecolumnout{% + % + \splittopskip=\topskip \splitmaxdepth=\maxdepth + % Get the available space for the double columns -- the normal + % (undoubled) page height minus any material left over from the + % previous page. + \dimen@ = \vsize + \divide\dimen@ by 2 + % + % box0 will be the left-hand column, box2 the right. + \setbox0=\vsplit\PAGE to\dimen@ \setbox2=\vsplit\PAGE to\dimen@ + \global\advance\vsize by 2\ht\partialpage + \onepageout\pagesofar + \unvbox\PAGE + \penalty\outputpenalty +} +% +% Re-output the contents of the output page -- any previous material, +% followed by the two boxes we just split, in box0 and box2. +\def\pagesofar{% + \unvbox\partialpage + % + \hsize = \doublecolumnhsize + \wd0=\hsize \wd2=\hsize + \hbox to\txipagewidth{\box0\hfil\box2}% +} + + +% Finished with with double columns. +\def\enddoublecolumns{% + % The following penalty ensures that the page builder is exercised + % _before_ we change the output routine. This is necessary in the + % following situation: + % + % The last section of the index consists only of a single entry. + % Before this section, \pagetotal is less than \pagegoal, so no + % break occurs before the last section starts. However, the last + % section, consisting of \initial and the single \entry, does not + % fit on the page and has to be broken off. Without the following + % penalty the page builder will not be exercised until \eject + % below, and by that time we'll already have changed the output + % routine to the \balancecolumns version, so the next-to-last + % double-column page will be processed with \balancecolumns, which + % is wrong: The two columns will go to the main vertical list, with + % the broken-off section in the recent contributions. As soon as + % the output routine finishes, TeX starts reconsidering the page + % break. The two columns and the broken-off section both fit on the + % page, because the two columns now take up only half of the page + % goal. When TeX sees \eject from below which follows the final + % section, it invokes the new output routine that we've set after + % \balancecolumns below; \onepageout will try to fit the two columns + % and the final section into the vbox of \txipageheight (see + % \pagebody), causing an overfull box. + % + % Note that glue won't work here, because glue does not exercise the + % page builder, unlike penalties (see The TeXbook, pp. 280-281). + \penalty0 + % + \output = {% + % Split the last of the double-column material. + \savemarks + \balancecolumns + }% + \eject % call the \output just set + \ifdim\pagetotal=0pt + % Having called \balancecolumns once, we do not + % want to call it again. Therefore, reset \output to its normal + % definition right away. + \global\output = {\onepageout{\pagecontents\PAGE}}% + % + \endgroup % started in \begindoublecolumns + \restoremarks + % Leave the double-column material on the current page, no automatic + % page break. + \box\balancedcolumns + % + % \pagegoal was set to the doubled \vsize above, since we restarted + % the current page. We're now back to normal single-column + % typesetting, so reset \pagegoal to the normal \vsize. + \global\vsize = \txipageheight % + \pagegoal = \txipageheight % + \else + % We had some left-over material. This might happen when \doublecolumnout + % is called in \balancecolumns. Try again. + \expandafter\enddoublecolumns + \fi +} +\newbox\balancedcolumns +\setbox\balancedcolumns=\vbox{shouldnt see this}% +% +% Only called for the last of the double column material. \doublecolumnout +% does the others. +\def\balancecolumns{% + \setbox0 = \vbox{\unvbox\PAGE}% like \box255 but more efficient, see p.120. + \dimen@ = \ht0 + \advance\dimen@ by \topskip + \advance\dimen@ by-\baselineskip + \ifdim\dimen@<5\baselineskip + % Don't split a short final column in two. + \setbox2=\vbox{}% + \global\setbox\balancedcolumns=\vbox{\pagesofar}% + \else + \divide\dimen@ by 2 % target to split to + \dimen@ii = \dimen@ + \splittopskip = \topskip + % Loop until left column is at least as high as the right column. + {% + \vbadness = 10000 + \loop + \global\setbox3 = \copy0 + \global\setbox1 = \vsplit3 to \dimen@ + \ifdim\ht1<\ht3 + \global\advance\dimen@ by 1pt + \repeat + }% + % Now the left column is in box 1, and the right column in box 3. + % + % Check whether the left column has come out higher than the page itself. + % (Note that we have doubled \vsize for the double columns, so + % the actual height of the page is 0.5\vsize). + \ifdim2\ht1>\vsize + % It appears that we have been called upon to balance too much material. + % Output some of it with \doublecolumnout, leaving the rest on the page. + \setbox\PAGE=\box0 + \doublecolumnout + \else + % Compare the heights of the two columns. + \ifdim4\ht1>5\ht3 + % Column heights are too different, so don't make their bottoms + % flush with each other. + \setbox2=\vbox to \ht1 {\unvbox3\vfill}% + \setbox0=\vbox to \ht1 {\unvbox1\vfill}% + \else + % Make column bottoms flush with each other. + \setbox2=\vbox to\ht1{\unvbox3\unskip}% + \setbox0=\vbox to\ht1{\unvbox1\unskip}% + \fi + \global\setbox\balancedcolumns=\vbox{\pagesofar}% + \fi + \fi + % +} +\catcode`\@ = \other + + +\message{sectioning,} +% Chapters, sections, etc. + +% Let's start with @part. +\outer\parseargdef\part{\partzzz{#1}} +\def\partzzz#1{% + \chapoddpage + \null + \vskip.3\vsize % move it down on the page a bit + \begingroup + \noindent \titlefonts\rm #1\par % the text + \let\lastnode=\empty % no node to associate with + \writetocentry{part}{#1}{}% but put it in the toc + \headingsoff % no headline or footline on the part page + % This outputs a mark at the end of the page that clears \thischapter + % and \thissection, as is done in \startcontents. + \let\pchapsepmacro\relax + \chapmacro{}{Yomitfromtoc}{}% + \chapoddpage + \endgroup +} + +% \unnumberedno is an oxymoron. But we count the unnumbered +% sections so that we can refer to them unambiguously in the pdf +% outlines by their "section number". We avoid collisions with chapter +% numbers by starting them at 10000. (If a document ever has 10000 +% chapters, we're in trouble anyway, I'm sure.) +\newcount\unnumberedno \unnumberedno = 10000 +\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} +% We do the following ugly conditional instead of the above simple +% construct for the sake of pdftex, which needs the actual +% letter in the expansion, not just typeset. +% +\def\appendixletter{% + \ifnum\appendixno=`A A% + \else\ifnum\appendixno=`B B% + \else\ifnum\appendixno=`C C% + \else\ifnum\appendixno=`D D% + \else\ifnum\appendixno=`E E% + \else\ifnum\appendixno=`F F% + \else\ifnum\appendixno=`G G% + \else\ifnum\appendixno=`H H% + \else\ifnum\appendixno=`I I% + \else\ifnum\appendixno=`J J% + \else\ifnum\appendixno=`K K% + \else\ifnum\appendixno=`L L% + \else\ifnum\appendixno=`M M% + \else\ifnum\appendixno=`N N% + \else\ifnum\appendixno=`O O% + \else\ifnum\appendixno=`P P% + \else\ifnum\appendixno=`Q Q% + \else\ifnum\appendixno=`R R% + \else\ifnum\appendixno=`S S% + \else\ifnum\appendixno=`T T% + \else\ifnum\appendixno=`U U% + \else\ifnum\appendixno=`V V% + \else\ifnum\appendixno=`W W% + \else\ifnum\appendixno=`X X% + \else\ifnum\appendixno=`Y Y% + \else\ifnum\appendixno=`Z Z% + % The \the is necessary, despite appearances, because \appendixletter is + % expanded while writing the .toc file. \char\appendixno is not + % expandable, thus it is written literally, thus all appendixes come out + % with the same letter (or @) in the toc without it. + \else\char\the\appendixno + \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi + \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi} + +% Each @chapter defines these (using marks) as the number+name, number +% and name of the chapter. Page headings and footings can use +% these. @section does likewise. +\def\thischapter{} +\def\thischapternum{} +\def\thischaptername{} +\def\thissection{} +\def\thissectionnum{} +\def\thissectionname{} + +\newcount\absseclevel % used to calculate proper heading level +\newcount\secbase\secbase=0 % @raisesections/@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 + +% we only have subsub. +\chardef\maxseclevel = 3 +% +% A numbered section within an unnumbered changes to unnumbered too. +% To achieve this, remember the "biggest" unnum. sec. we are currently in: +\chardef\unnlevel = \maxseclevel +% +% Trace whether the current chapter is an appendix or not: +% \chapheadtype is "N" or "A", unnumbered chapters are ignored. +\def\chapheadtype{N} + +% Choose a heading macro +% #1 is heading type +% #2 is heading level +% #3 is text for heading +\def\genhead#1#2#3{% + % Compute the abs. sec. level: + \absseclevel=#2 + \advance\absseclevel by \secbase + % Make sure \absseclevel doesn't fall outside the range: + \ifnum \absseclevel < 0 + \absseclevel = 0 + \else + \ifnum \absseclevel > 3 + \absseclevel = 3 + \fi + \fi + % The heading type: + \def\headtype{#1}% + \if \headtype U% + \ifnum \absseclevel < \unnlevel + \chardef\unnlevel = \absseclevel + \fi + \else + % Check for appendix sections: + \ifnum \absseclevel = 0 + \edef\chapheadtype{\headtype}% + \else + \if \headtype A\if \chapheadtype N% + \errmessage{@appendix... within a non-appendix chapter}% + \fi\fi + \fi + % Check for numbered within unnumbered: + \ifnum \absseclevel > \unnlevel + \def\headtype{U}% + \else + \chardef\unnlevel = 3 + \fi + \fi + % Now print the heading: + \if \headtype U% + \ifcase\absseclevel + \unnumberedzzz{#3}% + \or \unnumberedseczzz{#3}% + \or \unnumberedsubseczzz{#3}% + \or \unnumberedsubsubseczzz{#3}% + \fi + \else + \if \headtype A% + \ifcase\absseclevel + \appendixzzz{#3}% + \or \appendixsectionzzz{#3}% + \or \appendixsubseczzz{#3}% + \or \appendixsubsubseczzz{#3}% + \fi + \else + \ifcase\absseclevel + \chapterzzz{#3}% + \or \seczzz{#3}% + \or \numberedsubseczzz{#3}% + \or \numberedsubsubseczzz{#3}% + \fi + \fi + \fi + \suppressfirstparagraphindent +} + +% an interface: +\def\numhead{\genhead N} +\def\apphead{\genhead A} +\def\unnmhead{\genhead U} + +% @chapter, @appendix, @unnumbered. Increment top-level counter, reset +% all lower-level sectioning counters to zero. +% +% Also set \chaplevelprefix, which we prepend to @float sequence numbers +% (e.g., figures), q.v. By default (before any chapter), that is empty. +\let\chaplevelprefix = \empty +% +\outer\parseargdef\chapter{\numhead0{#1}} % normally numhead0 calls chapterzzz +\def\chapterzzz#1{% + % section resetting is \global in case the chapter is in a group, such + % as an @include file. + \global\secno=0 \global\subsecno=0 \global\subsubsecno=0 + \global\advance\chapno by 1 + % + % Used for \float. + \gdef\chaplevelprefix{\the\chapno.}% + \resetallfloatnos + % + % \putwordChapter can contain complex things in translations. + \toks0=\expandafter{\putwordChapter}% + \message{\the\toks0 \space \the\chapno}% + % + % Write the actual heading. + \chapmacro{#1}{Ynumbered}{\the\chapno}% + % + % So @section and the like are numbered underneath this chapter. + \global\let\section = \numberedsec + \global\let\subsection = \numberedsubsec + \global\let\subsubsection = \numberedsubsubsec +} + +\outer\parseargdef\appendix{\apphead0{#1}} % normally calls appendixzzz +% +\def\appendixzzz#1{% + \global\secno=0 \global\subsecno=0 \global\subsubsecno=0 + \global\advance\appendixno by 1 + \gdef\chaplevelprefix{\appendixletter.}% + \resetallfloatnos + % + % \putwordAppendix can contain complex things in translations. + \toks0=\expandafter{\putwordAppendix}% + \message{\the\toks0 \space \appendixletter}% + % + \chapmacro{#1}{Yappendix}{\appendixletter}% + % + \global\let\section = \appendixsec + \global\let\subsection = \appendixsubsec + \global\let\subsubsection = \appendixsubsubsec +} + +% normally unnmhead0 calls unnumberedzzz: +\outer\parseargdef\unnumbered{\unnmhead0{#1}} +\def\unnumberedzzz#1{% + \global\secno=0 \global\subsecno=0 \global\subsubsecno=0 + \global\advance\unnumberedno by 1 + % + % Since an unnumbered has no number, no prefix for figures. + \global\let\chaplevelprefix = \empty + \resetallfloatnos + % + % 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 <toks register>. (We also do this for + % the toc entries.) + \toks0 = {#1}% + \message{(\the\toks0)}% + % + \chapmacro{#1}{Ynothing}{\the\unnumberedno}% + % + \global\let\section = \unnumberedsec + \global\let\subsection = \unnumberedsubsec + \global\let\subsubsection = \unnumberedsubsubsec +} + +% @centerchap is like @unnumbered, but the heading is centered. +\outer\parseargdef\centerchap{% + \let\centerparametersmaybe = \centerparameters + \unnmhead0{#1}% + \let\centerparametersmaybe = \relax +} + +% @top is like @unnumbered. +\let\top\unnumbered + +% Sections. +% +\outer\parseargdef\numberedsec{\numhead1{#1}} % normally calls seczzz +\def\seczzz#1{% + \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1 + \sectionheading{#1}{sec}{Ynumbered}{\the\chapno.\the\secno}% +} + +% normally calls appendixsectionzzz: +\outer\parseargdef\appendixsection{\apphead1{#1}} +\def\appendixsectionzzz#1{% + \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1 + \sectionheading{#1}{sec}{Yappendix}{\appendixletter.\the\secno}% +} +\let\appendixsec\appendixsection + +% normally calls unnumberedseczzz: +\outer\parseargdef\unnumberedsec{\unnmhead1{#1}} +\def\unnumberedseczzz#1{% + \global\subsecno=0 \global\subsubsecno=0 \global\advance\secno by 1 + \sectionheading{#1}{sec}{Ynothing}{\the\unnumberedno.\the\secno}% +} + +% Subsections. +% +% normally calls numberedsubseczzz: +\outer\parseargdef\numberedsubsec{\numhead2{#1}} +\def\numberedsubseczzz#1{% + \global\subsubsecno=0 \global\advance\subsecno by 1 + \sectionheading{#1}{subsec}{Ynumbered}{\the\chapno.\the\secno.\the\subsecno}% +} + +% normally calls appendixsubseczzz: +\outer\parseargdef\appendixsubsec{\apphead2{#1}} +\def\appendixsubseczzz#1{% + \global\subsubsecno=0 \global\advance\subsecno by 1 + \sectionheading{#1}{subsec}{Yappendix}% + {\appendixletter.\the\secno.\the\subsecno}% +} + +% normally calls unnumberedsubseczzz: +\outer\parseargdef\unnumberedsubsec{\unnmhead2{#1}} +\def\unnumberedsubseczzz#1{% + \global\subsubsecno=0 \global\advance\subsecno by 1 + \sectionheading{#1}{subsec}{Ynothing}% + {\the\unnumberedno.\the\secno.\the\subsecno}% +} + +% Subsubsections. +% +% normally numberedsubsubseczzz: +\outer\parseargdef\numberedsubsubsec{\numhead3{#1}} +\def\numberedsubsubseczzz#1{% + \global\advance\subsubsecno by 1 + \sectionheading{#1}{subsubsec}{Ynumbered}% + {\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno}% +} + +% normally appendixsubsubseczzz: +\outer\parseargdef\appendixsubsubsec{\apphead3{#1}} +\def\appendixsubsubseczzz#1{% + \global\advance\subsubsecno by 1 + \sectionheading{#1}{subsubsec}{Yappendix}% + {\appendixletter.\the\secno.\the\subsecno.\the\subsubsecno}% +} + +% normally unnumberedsubsubseczzz: +\outer\parseargdef\unnumberedsubsubsec{\unnmhead3{#1}} +\def\unnumberedsubsubseczzz#1{% + \global\advance\subsubsecno by 1 + \sectionheading{#1}{subsubsec}{Ynothing}% + {\the\unnumberedno.\the\secno.\the\subsecno.\the\subsubsecno}% +} + +% 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. +\let\section = \numberedsec +\let\subsection = \numberedsubsec +\let\subsubsection = \numberedsubsubsec + +% Define @majorheading, @heading and @subheading + +\def\majorheading{% + {\advance\chapheadingskip by 10pt \chapbreak }% + \parsearg\chapheadingzzz +} + +\def\chapheading{\chapbreak \parsearg\chapheadingzzz} +\def\chapheadingzzz#1{% + \vbox{\chapfonts \raggedtitlesettings #1\par}% + \nobreak\bigskip \nobreak + \suppressfirstparagraphindent +} + +% @heading, @subheading, @subsubheading. +\parseargdef\heading{\sectionheading{#1}{sec}{Yomitfromtoc}{} + \suppressfirstparagraphindent} +\parseargdef\subheading{\sectionheading{#1}{subsec}{Yomitfromtoc}{} + \suppressfirstparagraphindent} +\parseargdef\subsubheading{\sectionheading{#1}{subsubsec}{Yomitfromtoc}{} + \suppressfirstparagraphindent} + +% 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} + +% Parameter controlling skip before chapter headings (if needed) +\newskip\chapheadingskip + +% Define plain chapter starts, and page on/off switching for it. +\def\chapbreak{\dobreak \chapheadingskip {-4000}} + +% Start a new page +\def\chappager{\par\vfill\supereject} + +% \chapoddpage - start on an odd page for a new chapter +% Because \domark is called before \chapoddpage, the filler page will +% get the headings for the next chapter, which is wrong. But we don't +% care -- we just disable all headings on the filler page. +\def\chapoddpage{% + \chappager + \ifodd\pageno \else + \begingroup + \headingsoff + \null + \chappager + \endgroup + \fi +} + +\parseargdef\setchapternewpage{\csname CHAPPAG#1\endcsname} + +\def\CHAPPAGoff{% +\global\let\contentsalignmacro = \chappager +\global\let\pchapsepmacro=\chapbreak +\global\let\pagealignmacro=\chappager} + +\def\CHAPPAGon{% +\global\let\contentsalignmacro = \chappager +\global\let\pchapsepmacro=\chappager +\global\let\pagealignmacro=\chappager +\global\def\HEADINGSon{\HEADINGSsingle}} + +\def\CHAPPAGodd{% +\global\let\contentsalignmacro = \chapoddpage +\global\let\pchapsepmacro=\chapoddpage +\global\let\pagealignmacro=\chapoddpage +\global\def\HEADINGSon{\HEADINGSdouble}} + +\CHAPPAGon + +% \chapmacro - Chapter opening. +% +% #1 is the text, #2 is the section type (Ynumbered, Ynothing, +% Yappendix, Yomitfromtoc), #3 the chapter number. +% Not used for @heading series. +% +% To test against our argument. +\def\Ynothingkeyword{Ynothing} +\def\Yappendixkeyword{Yappendix} +\def\Yomitfromtockeyword{Yomitfromtoc} +% +\def\chapmacro#1#2#3{% + \expandafter\ifx\thisenv\titlepage\else + \checkenv{}% chapters, etc., should not start inside an environment. + \fi + % FIXME: \chapmacro is currently called from inside \titlepage when + % \setcontentsaftertitlepage to print the "Table of Contents" heading, but + % this should probably be done by \sectionheading with an option to print + % in chapter size. + % + % Insert the first mark before the heading break (see notes for \domark). + \let\prevchapterdefs=\lastchapterdefs + \let\prevsectiondefs=\lastsectiondefs + \gdef\lastsectiondefs{\gdef\thissectionname{}\gdef\thissectionnum{}% + \gdef\thissection{}}% + % + \def\temptype{#2}% + \ifx\temptype\Ynothingkeyword + \gdef\lastchapterdefs{\gdef\thischaptername{#1}\gdef\thischapternum{}% + \gdef\thischapter{\thischaptername}}% + \else\ifx\temptype\Yomitfromtockeyword + \gdef\lastchapterdefs{\gdef\thischaptername{#1}\gdef\thischapternum{}% + \gdef\thischapter{}}% + \else\ifx\temptype\Yappendixkeyword + \toks0={#1}% + \xdef\lastchapterdefs{% + \gdef\noexpand\thischaptername{\the\toks0}% + \gdef\noexpand\thischapternum{\appendixletter}% + % \noexpand\putwordAppendix avoids expanding indigestible + % commands in some of the translations. + \gdef\noexpand\thischapter{\noexpand\putwordAppendix{} + \noexpand\thischapternum: + \noexpand\thischaptername}% + }% + \else + \toks0={#1}% + \xdef\lastchapterdefs{% + \gdef\noexpand\thischaptername{\the\toks0}% + \gdef\noexpand\thischapternum{\the\chapno}% + % \noexpand\putwordChapter avoids expanding indigestible + % commands in some of the translations. + \gdef\noexpand\thischapter{\noexpand\putwordChapter{} + \noexpand\thischapternum: + \noexpand\thischaptername}% + }% + \fi\fi\fi + % + % Output the mark. Pass it through \safewhatsit, to take care of + % the preceding space. + \safewhatsit\domark + % + % Insert the chapter heading break. + \pchapsepmacro + % + % Now the second mark, after the heading break. No break points + % between here and the heading. + \let\prevchapterdefs=\lastchapterdefs + \let\prevsectiondefs=\lastsectiondefs + \domark + % + {% + \chapfonts \rm + \let\footnote=\errfootnoteheading % give better error message + % + % Have to define \lastsection before calling \donoderef, because the + % xref code eventually uses it. On the other hand, it has to be called + % after \pchapsepmacro, or the headline will change too soon. + \gdef\lastsection{#1}% + % + % Only insert the separating space if we have a chapter/appendix + % number, and don't print the unnumbered ``number''. + \ifx\temptype\Ynothingkeyword + \setbox0 = \hbox{}% + \def\toctype{unnchap}% + \else\ifx\temptype\Yomitfromtockeyword + \setbox0 = \hbox{}% contents like unnumbered, but no toc entry + \def\toctype{omit}% + \else\ifx\temptype\Yappendixkeyword + \setbox0 = \hbox{\putwordAppendix{} #3\enspace}% + \def\toctype{app}% + \else + \setbox0 = \hbox{#3\enspace}% + \def\toctype{numchap}% + \fi\fi\fi + % + % Write the toc entry for this chapter. Must come before the + % \donoderef, because we include the current node name in the toc + % entry, and \donoderef resets it to empty. + \writetocentry{\toctype}{#1}{#3}% + % + % For pdftex, we have to write out the node definition (aka, make + % the pdfdest) after any page break, but before the actual text has + % been typeset. If the destination for the pdf outline is after the + % text, then jumping from the outline may wind up with the text not + % being visible, for instance under high magnification. + \donoderef{#2}% + % + % Typeset the actual heading. + \nobreak % Avoid page breaks at the interline glue. + \vbox{\raggedtitlesettings \hangindent=\wd0 \centerparametersmaybe + \unhbox0 #1\par}% + }% + \nobreak\bigskip % no page break after a chapter title + \nobreak +} + +% @centerchap -- centered and unnumbered. +\let\centerparametersmaybe = \relax +\def\centerparameters{% + \advance\rightskip by 3\rightskip + \leftskip = \rightskip + \parfillskip = 0pt +} + + +% Section titles. These macros combine the section number parts and +% call the generic \sectionheading to do the printing. +% +\newskip\secheadingskip +\def\secheadingbreak{\dobreak \secheadingskip{-1000}} + +% Subsection titles. +\newskip\subsecheadingskip +\def\subsecheadingbreak{\dobreak \subsecheadingskip{-500}} + +% Subsubsection titles. +\def\subsubsecheadingskip{\subsecheadingskip} +\def\subsubsecheadingbreak{\subsecheadingbreak} + + +% Print any size, any type, section title. +% +% #1 is the text of the title, +% #2 is the section level (sec/subsec/subsubsec), +% #3 is the section type (Ynumbered, Ynothing, Yappendix, Yomitfromtoc), +% #4 is the section number. +% +\def\seckeyword{sec} +% +\def\sectionheading#1#2#3#4{% + {% + \def\sectionlevel{#2}% + \def\temptype{#3}% + % + % It is ok for the @heading series commands to appear inside an + % environment (it's been historically allowed, though the logic is + % dubious), but not the others. + \ifx\temptype\Yomitfromtockeyword\else + \checkenv{}% non-@*heading should not be in an environment. + \fi + \let\footnote=\errfootnoteheading + % + % Switch to the right set of fonts. + \csname #2fonts\endcsname \rm + % + % Insert first mark before the heading break (see notes for \domark). + \let\prevsectiondefs=\lastsectiondefs + \ifx\temptype\Ynothingkeyword + \ifx\sectionlevel\seckeyword + \gdef\lastsectiondefs{\gdef\thissectionname{#1}\gdef\thissectionnum{}% + \gdef\thissection{\thissectionname}}% + \fi + \else\ifx\temptype\Yomitfromtockeyword + % Don't redefine \thissection. + \else\ifx\temptype\Yappendixkeyword + \ifx\sectionlevel\seckeyword + \toks0={#1}% + \xdef\lastsectiondefs{% + \gdef\noexpand\thissectionname{\the\toks0}% + \gdef\noexpand\thissectionnum{#4}% + % \noexpand\putwordSection avoids expanding indigestible + % commands in some of the translations. + \gdef\noexpand\thissection{\noexpand\putwordSection{} + \noexpand\thissectionnum: + \noexpand\thissectionname}% + }% + \fi + \else + \ifx\sectionlevel\seckeyword + \toks0={#1}% + \xdef\lastsectiondefs{% + \gdef\noexpand\thissectionname{\the\toks0}% + \gdef\noexpand\thissectionnum{#4}% + % \noexpand\putwordSection avoids expanding indigestible + % commands in some of the translations. + \gdef\noexpand\thissection{\noexpand\putwordSection{} + \noexpand\thissectionnum: + \noexpand\thissectionname}% + }% + \fi + \fi\fi\fi + % + % Go into vertical mode. Usually we'll already be there, but we + % don't want the following whatsit to end up in a preceding paragraph + % if the document didn't happen to have a blank line. + \par + % + % Output the mark. Pass it through \safewhatsit, to take care of + % the preceding space. + \safewhatsit\domark + % + % Insert space above the heading. + \csname #2headingbreak\endcsname + % + % Now the second mark, after the heading break. No break points + % between here and the heading. + \global\let\prevsectiondefs=\lastsectiondefs + \domark + % + % Only insert the space after the number if we have a section number. + \ifx\temptype\Ynothingkeyword + \setbox0 = \hbox{}% + \def\toctype{unn}% + \gdef\lastsection{#1}% + \else\ifx\temptype\Yomitfromtockeyword + % for @headings -- no section number, don't include in toc, + % and don't redefine \lastsection. + \setbox0 = \hbox{}% + \def\toctype{omit}% + \let\sectionlevel=\empty + \else\ifx\temptype\Yappendixkeyword + \setbox0 = \hbox{#4\enspace}% + \def\toctype{app}% + \gdef\lastsection{#1}% + \else + \setbox0 = \hbox{#4\enspace}% + \def\toctype{num}% + \gdef\lastsection{#1}% + \fi\fi\fi + % + % Write the toc entry (before \donoderef). See comments in \chapmacro. + \writetocentry{\toctype\sectionlevel}{#1}{#4}% + % + % Write the node reference (= pdf destination for pdftex). + % Again, see comments in \chapmacro. + \donoderef{#3}% + % + % Interline glue will be inserted when the vbox is completed. + % That glue will be a valid breakpoint for the page, since it'll be + % preceded by a whatsit (usually from the \donoderef, or from the + % \writetocentry if there was no node). We don't want to allow that + % break, since then the whatsits could end up on page n while the + % section is on page n+1, thus toc/etc. are wrong. Debian bug 276000. + \nobreak + % + % Output the actual section heading. + \vbox{\hyphenpenalty=10000 \tolerance=5000 \parindent=0pt \ptexraggedright + \hangindent=\wd0 % zero if no section number + \unhbox0 #1}% + }% + % Add extra space after the heading -- half of whatever came above it. + % Don't allow stretch, though. + \kern .5 \csname #2headingskip\endcsname + % + % Do not let the kern be a potential breakpoint, as it would be if it + % was followed by glue. + \nobreak + % + % We'll almost certainly start a paragraph next, so don't let that + % glue accumulate. (Not a breakpoint because it's preceded by a + % discardable item.) However, when a paragraph is not started next + % (\startdefun, \cartouche, \center, etc.), this needs to be wiped out + % or the negative glue will cause weirdly wrong output, typically + % obscuring the section heading with something else. + \vskip-\parskip + % + % This is so the last item on the main vertical list is a known + % \penalty > 10000, so \startdefun, etc., can recognize the situation + % and do the needful. + \penalty 10001 +} + + +\message{toc,} +% Table of contents. +\newwrite\tocfile + +% Write an entry to the toc file, opening it if necessary. +% Called from @chapter, etc. +% +% Example usage: \writetocentry{sec}{Section Name}{\the\chapno.\the\secno} +% We append the current node name (if any) and page number as additional +% arguments for the \{chap,sec,...}entry macros which will eventually +% read this. The node name is used in the pdf outlines as the +% destination to jump to. +% +% We open the .toc file for writing here instead of at @setfilename (or +% any other fixed time) so that @contents can be anywhere in the document. +% But if #1 is `omit', then we don't do anything. This is used for the +% table of contents chapter openings themselves. +% +\newif\iftocfileopened +\def\omitkeyword{omit}% +% +\def\writetocentry#1#2#3{% + \edef\writetoctype{#1}% + \ifx\writetoctype\omitkeyword \else + \iftocfileopened\else + \immediate\openout\tocfile = \jobname.toc + \global\tocfileopenedtrue + \fi + % + \iflinks + {\atdummies + \edef\temp{% + \write\tocfile{@#1entry{#2}{#3}{\lastnode}{\noexpand\folio}}}% + \temp + }% + \fi + \fi + % + % Tell \shipout to create a pdf destination on each page, if we're + % writing pdf. These are used in the table of contents. We can't + % just write one on every page because the title pages are numbered + % 1 and 2 (the page numbers aren't printed), and so are the first + % two pages of the document. Thus, we'd have two destinations named + % `1', and two named `2'. + \ifpdf + \global\pdfmakepagedesttrue + \else + \ifx\XeTeXrevision\thisisundefined + \else + \global\pdfmakepagedesttrue + \fi + \fi +} + + +% These characters do not print properly in the Computer Modern roman +% fonts, so we must take special care. This is more or less redundant +% with the Texinfo input format setup at the end of this file. +% +\def\activecatcodes{% + \catcode`\"=\active + \catcode`\$=\active + \catcode`\<=\active + \catcode`\>=\active + \catcode`\\=\active + \catcode`\^=\active + \catcode`\_=\active + \catcode`\|=\active + \catcode`\~=\active +} + + +% Read the toc file, which is essentially Texinfo input. +\def\readtocfile{% + \setupdatafile + \activecatcodes + \input \tocreadfilename +} + +\newskip\contentsrightmargin \contentsrightmargin=1in +\newcount\savepageno +\newcount\lastnegativepageno \lastnegativepageno = -1 + +% Prepare to read what we've written to \tocfile. +% +\def\startcontents#1{% + % If @setchapternewpage on, and @headings double, the contents should + % start on an odd page, unlike chapters. Thus, we maintain + % \contentsalignmacro in parallel with \pagealignmacro. + % From: Torbjorn Granlund <tege@matematik.su.se> + \contentsalignmacro + \immediate\closeout\tocfile + % + % Don't need to put `Contents' or `Short Contents' in the headline. + % It is abundantly clear what they are. + \chapmacro{#1}{Yomitfromtoc}{}% + % + \savepageno = \pageno + \begingroup % Set up to handle contents files properly. + \raggedbottom % Worry more about breakpoints than the bottom. + \entryrightmargin=\contentsrightmargin % Don't use the full line length. + % + % Roman numerals for page numbers. + \ifnum \pageno>0 \global\pageno = \lastnegativepageno \fi +} + +% redefined for the two-volume lispref. We always output on +% \jobname.toc even if this is redefined. +% +\def\tocreadfilename{\jobname.toc} + +% Normal (long) toc. +% +\def\contents{% + \startcontents{\putwordTOC}% + \openin 1 \tocreadfilename\space + \ifeof 1 \else + \readtocfile + \fi + \vfill \eject + \contentsalignmacro % in case @setchapternewpage odd is in effect + \ifeof 1 \else + \pdfmakeoutlines + \fi + \closein 1 + \endgroup + \lastnegativepageno = \pageno + \global\pageno = \savepageno +} + +% And just the chapters. +\def\summarycontents{% + \startcontents{\putwordShortTOC}% + % + \let\partentry = \shortpartentry + \let\numchapentry = \shortchapentry + \let\appentry = \shortchapentry + \let\unnchapentry = \shortunnchapentry + % We want a true roman here for the page numbers. + \secfonts + \let\rm=\shortcontrm \let\bf=\shortcontbf + \let\sl=\shortcontsl \let\tt=\shortconttt + \rm + \hyphenpenalty = 10000 + \advance\baselineskip by 1pt % Open it up a little. + \def\numsecentry##1##2##3##4{} + \let\appsecentry = \numsecentry + \let\unnsecentry = \numsecentry + \let\numsubsecentry = \numsecentry + \let\appsubsecentry = \numsecentry + \let\unnsubsecentry = \numsecentry + \let\numsubsubsecentry = \numsecentry + \let\appsubsubsecentry = \numsecentry + \let\unnsubsubsecentry = \numsecentry + \openin 1 \tocreadfilename\space + \ifeof 1 \else + \readtocfile + \fi + \closein 1 + \vfill \eject + \contentsalignmacro % in case @setchapternewpage odd is in effect + \endgroup + \lastnegativepageno = \pageno + \global\pageno = \savepageno +} +\let\shortcontents = \summarycontents + +% Typeset the label for a chapter or appendix for the short contents. +% The arg is, e.g., `A' for an appendix, or `3' for a chapter. +% +\def\shortchaplabel#1{% + % This space should be enough, since a single number is .5em, and the + % widest letter (M) is 1em, at least in the Computer Modern fonts. + % But use \hss just in case. + % (This space doesn't include the extra space that gets added after + % the label; that gets put in by \shortchapentry above.) + % + % We'd like to right-justify chapter numbers, but that looks strange + % with appendix letters. And right-justifying numbers and + % left-justifying letters looks strange when there is less than 10 + % chapters. Have to read the whole toc once to know how many chapters + % there are before deciding ... + \hbox to 1em{#1\hss}% +} + +% 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, ... + +% Parts, in the main contents. Replace the part number, which doesn't +% exist, with an empty box. Let's hope all the numbers have the same width. +% Also ignore the page number, which is conventionally not printed. +\def\numeralbox{\setbox0=\hbox{8}\hbox to \wd0{\hfil}} +\def\partentry#1#2#3#4{% + % Add stretch and a bonus for breaking the page before the part heading. + % This reduces the chance of the page being broken immediately after the + % part heading, before a following chapter heading. + \vskip 0pt plus 5\baselineskip + \penalty-300 + \vskip 0pt plus -5\baselineskip + \dochapentry{\numeralbox\labelspace#1}{}% +} +% +% Parts, in the short toc. +\def\shortpartentry#1#2#3#4{% + \penalty-300 + \vskip.5\baselineskip plus.15\baselineskip minus.1\baselineskip + \shortchapentry{{\bf #1}}{\numeralbox}{}{}% +} + +% Chapters, in the main contents. +\def\numchapentry#1#2#3#4{\dochapentry{#2\labelspace#1}{#4}} + +% Chapters, in the short toc. +% See comments in \dochapentry re vbox and related settings. +\def\shortchapentry#1#2#3#4{% + \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno\bgroup#4\egroup}% +} + +% Appendices, in the main contents. +% Need the word Appendix, and a fixed-size box. +% +\def\appendixbox#1{% + % We use M since it's probably the widest letter. + \setbox0 = \hbox{\putwordAppendix{} M}% + \hbox to \wd0{\putwordAppendix{} #1\hss}} +% +\def\appentry#1#2#3#4{\dochapentry{\appendixbox{#2}\hskip.7em#1}{#4}} + +% Unnumbered chapters. +\def\unnchapentry#1#2#3#4{\dochapentry{#1}{#4}} +\def\shortunnchapentry#1#2#3#4{\tocentry{#1}{\doshortpageno\bgroup#4\egroup}} + +% Sections. +\def\numsecentry#1#2#3#4{\dosecentry{#2\labelspace#1}{#4}} +\let\appsecentry=\numsecentry +\def\unnsecentry#1#2#3#4{\dosecentry{#1}{#4}} + +% Subsections. +\def\numsubsecentry#1#2#3#4{\dosubsecentry{#2\labelspace#1}{#4}} +\let\appsubsecentry=\numsubsecentry +\def\unnsubsecentry#1#2#3#4{\dosubsecentry{#1}{#4}} + +% And subsubsections. +\def\numsubsubsecentry#1#2#3#4{\dosubsubsecentry{#2\labelspace#1}{#4}} +\let\appsubsubsecentry=\numsubsubsecentry +\def\unnsubsubsecentry#1#2#3#4{\dosubsubsecentry{#1}{#4}} + +% This parameter controls the indentation of the various levels. +% Same as \defaultparindent. +\newdimen\tocindent \tocindent = 15pt + +% 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 want it to be at chapters +% if at all possible; hence the \penalty. +\def\dochapentry#1#2{% + \penalty-300 \vskip1\baselineskip plus.33\baselineskip minus.25\baselineskip + \begingroup + % Move the page numbers slightly to the right + \advance\entryrightmargin by -0.05em + \chapentryfonts + \tocentry{#1}{\dopageno\bgroup#2\egroup}% + \endgroup + \nobreak\vskip .25\baselineskip plus.1\baselineskip +} + +\def\dosecentry#1#2{\begingroup + \secentryfonts \leftskip=\tocindent + \tocentry{#1}{\dopageno\bgroup#2\egroup}% +\endgroup} + +\def\dosubsecentry#1#2{\begingroup + \subsecentryfonts \leftskip=2\tocindent + \tocentry{#1}{\dopageno\bgroup#2\egroup}% +\endgroup} + +\def\dosubsubsecentry#1#2{\begingroup + \subsubsecentryfonts \leftskip=3\tocindent + \tocentry{#1}{\dopageno\bgroup#2\egroup}% +\endgroup} + +% We use the same \entry macro as for the index entries. +\let\tocentry = \entry + +% 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} +\def\subsecentryfonts{\textfonts} +\def\subsubsecentryfonts{\textfonts} + + +\message{environments,} +% @foo ... @end foo. + +% @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 @ character. + +\envdef\tex{% + \setupmarkupstyle{tex}% + \catcode `\\=0 \catcode `\{=1 \catcode `\}=2 + \catcode `\$=3 \catcode `\&=4 \catcode `\#=6 + \catcode `\^=7 \catcode `\_=8 \catcode `\~=\active \let~=\tie + \catcode `\%=14 + \catcode `\+=\other + \catcode `\"=\other + \catcode `\|=\other + \catcode `\<=\other + \catcode `\>=\other + \catcode `\`=\other + \catcode `\'=\other + % + % ' is active in math mode (mathcode"8000). So reset it, and all our + % other math active characters (just in case), to plain's definitions. + \mathactive + % + % Inverse of the list at the beginning of the file. + \let\b=\ptexb + \let\bullet=\ptexbullet + \let\c=\ptexc + \let\,=\ptexcomma + \let\.=\ptexdot + \let\dots=\ptexdots + \let\equiv=\ptexequiv + \let\!=\ptexexclam + \let\i=\ptexi + \let\indent=\ptexindent + \let\noindent=\ptexnoindent + \let\{=\ptexlbrace + \let\+=\tabalign + \let\}=\ptexrbrace + \let\/=\ptexslash + \let\sp=\ptexsp + \let\*=\ptexstar + %\let\sup=\ptexsup % do not redefine, we want @sup to work in math mode + \let\t=\ptext + \expandafter \let\csname top\endcsname=\ptextop % we've made it outer + \let\frenchspacing=\plainfrenchspacing + % + \def\endldots{\mathinner{\ldots\ldots\ldots\ldots}}% + \def\enddots{\relax\ifmmode\endldots\else$\mathsurround=0pt \endldots\,$\fi}% + \def\@{@}% +} +% There is no need to define \Etex. + +% Define @lisp ... @end lisp. +% @lisp environment forms a group so it can rebind things, +% including the definition of @end lisp (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} + +% 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{{% + % =10000 instead of <10000 because of a special case in \itemzzz and + % \sectionheading, q.v. + \ifnum \lastpenalty=10000 \else + \advance\envskipamount by \parskip + \endgraf + \ifdim\lastskip<\envskipamount + \removelastskip + \ifnum\lastpenalty<10000 + % Penalize breaking before the environment, because preceding text + % often leads into it. + \penalty100 + \fi + \vskip\envskipamount + \fi + \fi +}} + +\def\afterenvbreak{{% + % =10000 instead of <10000 because of a special case in \itemzzz and + % \sectionheading, q.v. + \ifnum \lastpenalty=10000 \else + \advance\envskipamount by \parskip + \endgraf + \ifdim\lastskip<\envskipamount + \removelastskip + % it's not a good place to break if the last penalty was \nobreak + % or better ... + \ifnum\lastpenalty<10000 \penalty-50 \fi + \vskip\envskipamount + \fi + \fi +}} + +% \nonarrowing is a flag. If "set", @lisp etc don't narrow margins; it will +% also clear it, so that its embedded environments do the narrowing again. +\let\nonarrowing=\relax + +% @cartouche ... @end cartouche: draw rectangle w/rounded corners around +% environment contents. +\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 + +\envdef\cartouche{% + \ifhmode\par\fi % can't be in the midst of a paragraph. + \startsavinginserts + \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 18.4pt % allow for 3pt kerns on either + % side, and for 6pt waste from + % each corner char, and rule thickness + \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip + % + % If this cartouche directly follows a sectioning command, we need the + % \parskip glue (backspaced over by default) or the cartouche can + % collide with the section heading. + \ifnum\lastpenalty>10000 \vskip\parskip \penalty\lastpenalty \fi + % + \setbox\groupbox=\vbox\bgroup + \baselineskip=0pt\parskip=0pt\lineskip=0pt + \carttop + \hbox\bgroup + \hskip\lskip + \vrule\kern3pt + \vbox\bgroup + \kern3pt + \hsize=\cartinner + \baselineskip=\normbskip + \lineskip=\normlskip + \parskip=\normpskip + \vskip -\parskip + \comment % For explanation, see the end of def\group. +} +\def\Ecartouche{% + \ifhmode\par\fi + \kern3pt + \egroup + \kern3pt\vrule + \hskip\rskip + \egroup + \cartbot + \egroup + \addgroupbox + \checkinserts +} + + +% This macro is called at the beginning of all the @example variants, +% inside a group. +\newdimen\nonfillparindent +\def\nonfillstart{% + \aboveenvbreak + \ifdim\hfuzz < 12pt \hfuzz = 12pt \fi % Don't be fussy + \sepspaces % Make spaces be word-separators rather than space tokens. + \let\par = \lisppar % don't ignore blank lines + \obeylines % each line of input is a line of output + \parskip = 0pt + % Turn off paragraph indentation but redefine \indent to emulate + % the normal \indent. + \nonfillparindent=\parindent + \parindent = 0pt + \let\indent\nonfillindent + % + \emergencystretch = 0pt % don't try to avoid overfull boxes + \ifx\nonarrowing\relax + \advance \leftskip by \lispnarrowing + \exdentamount=\lispnarrowing + \else + \let\nonarrowing = \relax + \fi + \let\exdent=\nofillexdent +} + +\begingroup +\obeyspaces +% We want to swallow spaces (but not other tokens) after the fake +% @indent in our nonfill-environments, where spaces are normally +% active and set to @tie, resulting in them not being ignored after +% @indent. +\gdef\nonfillindent{\futurelet\temp\nonfillindentcheck}% +\gdef\nonfillindentcheck{% +\ifx\temp % +\expandafter\nonfillindentgobble% +\else% +\leavevmode\nonfillindentbox% +\fi% +}% +\endgroup +\def\nonfillindentgobble#1{\nonfillindent} +\def\nonfillindentbox{\hbox to \nonfillparindent{\hss}} + +% If you want all examples etc. small: @set dispenvsize small. +% If you want even small examples the full size: @set dispenvsize nosmall. +% This affects the following displayed environments: +% @example, @display, @format, @lisp +% +\def\smallword{small} +\def\nosmallword{nosmall} +\let\SETdispenvsize\relax +\def\setnormaldispenv{% + \ifx\SETdispenvsize\smallword + % end paragraph for sake of leading, in case document has no blank + % line. This is redundant with what happens in \aboveenvbreak, but + % we need to do it before changing the fonts, and it's inconvenient + % to change the fonts afterward. + \ifnum \lastpenalty=10000 \else \endgraf \fi + \smallexamplefonts \rm + \fi +} +\def\setsmalldispenv{% + \ifx\SETdispenvsize\nosmallword + \else + \ifnum \lastpenalty=10000 \else \endgraf \fi + \smallexamplefonts \rm + \fi +} + +% We often define two environments, @foo and @smallfoo. +% Let's do it in one command. #1 is the env name, #2 the definition. +\def\makedispenvdef#1#2{% + \expandafter\envdef\csname#1\endcsname {\setnormaldispenv #2}% + \expandafter\envdef\csname small#1\endcsname {\setsmalldispenv #2}% + \expandafter\let\csname E#1\endcsname \afterenvbreak + \expandafter\let\csname Esmall#1\endcsname \afterenvbreak +} + +% Define two environment synonyms (#1 and #2) for an environment. +\def\maketwodispenvdef#1#2#3{% + \makedispenvdef{#1}{#3}% + \makedispenvdef{#2}{#3}% +} +% +% @lisp: indented, narrowed, typewriter font; +% @example: same as @lisp. +% +% @smallexample and @smalllisp: use smaller fonts. +% Originally contributed by Pavel@xerox. +% +\maketwodispenvdef{lisp}{example}{% + \nonfillstart + \tt\setupmarkupstyle{example}% + \let\kbdfont = \kbdexamplefont % Allow @kbd to do something special. + \gobble % eat return +} +% @display/@smalldisplay: same as @lisp except keep current font. +% +\makedispenvdef{display}{% + \nonfillstart + \gobble +} + +% @format/@smallformat: same as @display except don't narrow margins. +% +\makedispenvdef{format}{% + \let\nonarrowing = t% + \nonfillstart + \gobble +} + +% @flushleft: same as @format, but doesn't obey \SETdispenvsize. +\envdef\flushleft{% + \let\nonarrowing = t% + \nonfillstart + \gobble +} +\let\Eflushleft = \afterenvbreak + +% @flushright. +% +\envdef\flushright{% + \let\nonarrowing = t% + \nonfillstart + \advance\leftskip by 0pt plus 1fill\relax + \gobble +} +\let\Eflushright = \afterenvbreak + + +% @raggedright does more-or-less normal line breaking but no right +% justification. From plain.tex. Don't stretch around special +% characters in urls in this environment, since the stretch at the right +% should be enough. +\envdef\raggedright{% + \rightskip0pt plus2.4em \spaceskip.3333em \xspaceskip.5em\relax + \def\urefprestretchamount{0pt}% + \def\urefpoststretchamount{0pt}% +} +\let\Eraggedright\par + +\envdef\raggedleft{% + \parindent=0pt \leftskip0pt plus2em + \spaceskip.3333em \xspaceskip.5em \parfillskip=0pt + \hbadness=10000 % Last line will usually be underfull, so turn off + % badness reporting. +} +\let\Eraggedleft\par + +\envdef\raggedcenter{% + \parindent=0pt \rightskip0pt plus1em \leftskip0pt plus1em + \spaceskip.3333em \xspaceskip.5em \parfillskip=0pt + \hbadness=10000 % Last line will usually be underfull, so turn off + % badness reporting. +} +\let\Eraggedcenter\par + + +% @quotation does normal linebreaking (hence we can't use \nonfillstart) +% and narrows the margins. We keep \parskip nonzero in general, since +% we're doing normal filling. So, when using \aboveenvbreak and +% \afterenvbreak, temporarily make \parskip 0. +% +\makedispenvdef{quotation}{\quotationstart} +% +\def\quotationstart{% + \indentedblockstart % same as \indentedblock, but increase right margin too. + \ifx\nonarrowing\relax + \advance\rightskip by \lispnarrowing + \fi + \parsearg\quotationlabel +} + +% We have retained a nonzero parskip for the environment, since we're +% doing normal filling. +% +\def\Equotation{% + \par + \ifx\quotationauthor\thisisundefined\else + % indent a bit. + \leftline{\kern 2\leftskip \sl ---\quotationauthor}% + \fi + {\parskip=0pt \afterenvbreak}% +} +\def\Esmallquotation{\Equotation} + +% If we're given an argument, typeset it in bold with a colon after. +\def\quotationlabel#1{% + \def\temp{#1}% + \ifx\temp\empty \else + {\bf #1: }% + \fi +} + +% @indentedblock is like @quotation, but indents only on the left and +% has no optional argument. +% +\makedispenvdef{indentedblock}{\indentedblockstart} +% +\def\indentedblockstart{% + {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip + \parindent=0pt + % + % @cartouche defines \nonarrowing to inhibit narrowing at next level down. + \ifx\nonarrowing\relax + \advance\leftskip by \lispnarrowing + \exdentamount = \lispnarrowing + \else + \let\nonarrowing = \relax + \fi +} + +% Keep a nonzero parskip for the environment, since we're doing normal filling. +% +\def\Eindentedblock{% + \par + {\parskip=0pt \afterenvbreak}% +} +\def\Esmallindentedblock{\Eindentedblock} + + +% LaTeX-like @verbatim...@end verbatim and @verb{<char>...<char>} +% If we want to allow any <char> as delimiter, +% we need the curly braces so that makeinfo sees the @verb command, eg: +% `@verbx...x' would look like the '@verbx' command. --janneke@gnu.org +% +% [Knuth]: Donald Ervin Knuth, 1996. The TeXbook. +% +% [Knuth] p.344; only we need to do the other characters Texinfo sets +% active too. Otherwise, they get lost as the first character on a +% verbatim line. +\def\dospecials{% + \do\ \do\\\do\{\do\}\do\$\do\&% + \do\#\do\^\do\^^K\do\_\do\^^A\do\%\do\~% + \do\<\do\>\do\|\do\@\do+\do\"% + % Don't do the quotes -- if we do, @set txicodequoteundirected and + % @set txicodequotebacktick will not have effect on @verb and + % @verbatim, and ?` and !` ligatures won't get disabled. + %\do\`\do\'% +} +% +% [Knuth] p. 380 +\def\uncatcodespecials{% + \def\do##1{\catcode`##1=\other}\dospecials} +% +% Setup for the @verb command. +% +% Eight spaces for a tab +\begingroup + \catcode`\^^I=\active + \gdef\tabeightspaces{\catcode`\^^I=\active\def^^I{\ \ \ \ \ \ \ \ }} +\endgroup +% +\def\setupverb{% + \tt % easiest (and conventionally used) font for verbatim + \def\par{\leavevmode\endgraf}% + \setupmarkupstyle{verb}% + \tabeightspaces + % Respect line breaks, + % print special symbols as themselves, and + % make each space count + % must do in this order: + \obeylines \uncatcodespecials \sepspaces +} + +% Setup for the @verbatim environment +% +% Real tab expansion. +\newdimen\tabw \setbox0=\hbox{\tt\space} \tabw=8\wd0 % tab amount +% +% We typeset each line of the verbatim in an \hbox, so we can handle +% tabs. The \global is in case the verbatim line starts with an accent, +% or some other command that starts with a begin-group. Otherwise, the +% entire \verbbox would disappear at the corresponding end-group, before +% it is typeset. Meanwhile, we can't have nested verbatim commands +% (can we?), so the \global won't be overwriting itself. +\newbox\verbbox +\def\starttabbox{\global\setbox\verbbox=\hbox\bgroup} +% +\begingroup + \catcode`\^^I=\active + \gdef\tabexpand{% + \catcode`\^^I=\active + \def^^I{\leavevmode\egroup + \dimen\verbbox=\wd\verbbox % the width so far, or since the previous tab + \divide\dimen\verbbox by\tabw + \multiply\dimen\verbbox by\tabw % compute previous multiple of \tabw + \advance\dimen\verbbox by\tabw % advance to next multiple of \tabw + \wd\verbbox=\dimen\verbbox \box\verbbox \starttabbox + }% + } +\endgroup + +% start the verbatim environment. +\def\setupverbatim{% + \let\nonarrowing = t% + \nonfillstart + \tt % easiest (and conventionally used) font for verbatim + % The \leavevmode here is for blank lines. Otherwise, we would + % never \starttabox and the \egroup would end verbatim mode. + \def\par{\leavevmode\egroup\box\verbbox\endgraf}% + \tabexpand + \setupmarkupstyle{verbatim}% + % Respect line breaks, + % print special symbols as themselves, and + % make each space count. + % Must do in this order: + \obeylines \uncatcodespecials \sepspaces + \everypar{\starttabbox}% +} + +% Do the @verb magic: verbatim text is quoted by unique +% delimiter characters. Before first delimiter expect a +% right brace, after last delimiter expect closing brace: +% +% \def\doverb'{'<char>#1<char>'}'{#1} +% +% [Knuth] p. 382; only eat outer {} +\begingroup + \catcode`[=1\catcode`]=2\catcode`\{=\other\catcode`\}=\other + \gdef\doverb{#1[\def\next##1#1}[##1\endgroup]\next] +\endgroup +% +\def\verb{\begingroup\setupverb\doverb} +% +% +% Do the @verbatim magic: define the macro \doverbatim so that +% the (first) argument ends when '@end verbatim' is reached, ie: +% +% \def\doverbatim#1@end verbatim{#1} +% +% For Texinfo it's a lot easier than for LaTeX, +% because texinfo's \verbatim doesn't stop at '\end{verbatim}': +% we need not redefine '\', '{' and '}'. +% +% Inspired by LaTeX's verbatim command set [latex.ltx] +% +\begingroup + \catcode`\ =\active + \obeylines % + % ignore everything up to the first ^^M, that's the newline at the end + % of the @verbatim input line itself. Otherwise we get an extra blank + % line in the output. + \xdef\doverbatim#1^^M#2@end verbatim{#2\noexpand\end\gobble verbatim}% + % We really want {...\end verbatim} in the body of the macro, but + % without the active space; thus we have to use \xdef and \gobble. +\endgroup +% +\envdef\verbatim{% + \setupverbatim\doverbatim +} +\let\Everbatim = \afterenvbreak + + +% @verbatiminclude FILE - insert text of file in verbatim environment. +% +\def\verbatiminclude{\parseargusing\filenamecatcodes\doverbatiminclude} +% +\def\doverbatiminclude#1{% + {% + \makevalueexpandable + \setupverbatim + \indexnofonts % Allow `@@' and other weird things in file names. + \wlog{texinfo.tex: doing @verbatiminclude of #1^^J}% + \input #1 + \afterenvbreak + }% +} + +% @copying ... @end copying. +% Save the text away for @insertcopying later. +% +% We save the uninterpreted tokens, rather than creating a box. +% Saving the text in a box would be much easier, but then all the +% typesetting commands (@smallbook, font changes, etc.) have to be done +% beforehand -- and a) we want @copying to be done first in the source +% file; b) letting users define the frontmatter in as flexible order as +% possible is desirable. +% +\def\copying{\checkenv{}\begingroup\scanargctxt\docopying} +\def\docopying#1@end copying{\endgroup\def\copyingtext{#1}} +% +\def\insertcopying{% + \begingroup + \parindent = 0pt % paragraph indentation looks wrong on title page + \scanexp\copyingtext + \endgroup +} + + +\message{defuns,} +% @defun etc. + +\newskip\defbodyindent \defbodyindent=.4in +\newskip\defargsindent \defargsindent=50pt +\newskip\deflastargmargin \deflastargmargin=18pt +\newcount\defunpenalty + +% Start the processing of @deffn: +\def\startdefun{% + \ifnum\lastpenalty<10000 + \medbreak + \defunpenalty=10003 % Will keep this @deffn together with the + % following @def command, see below. + \else + % If there are two @def commands in a row, we'll have a \nobreak, + % which is there to keep the function description together with its + % header. But if there's nothing but headers, we need to allow a + % break somewhere. Check specifically for penalty 10002, inserted + % by \printdefunline, instead of 10000, since the sectioning + % commands also insert a nobreak penalty, and we don't want to allow + % a break between a section heading and a defun. + % + % As a further refinement, we avoid "club" headers by signalling + % with penalty of 10003 after the very first @deffn in the + % sequence (see above), and penalty of 10002 after any following + % @def command. + \ifnum\lastpenalty=10002 \penalty2000 \else \defunpenalty=10002 \fi + % + % Similarly, after a section heading, do not allow a break. + % But do insert the glue. + \medskip % preceded by discardable penalty, so not a breakpoint + \fi + % + \parindent=0in + \advance\leftskip by \defbodyindent + \exdentamount=\defbodyindent +} + +\def\dodefunx#1{% + % First, check whether we are in the right environment: + \checkenv#1% + % + % As above, allow line break if we have multiple x headers in a row. + % It's not a great place, though. + \ifnum\lastpenalty=10002 \penalty3000 \else \defunpenalty=10002 \fi + % + % And now, it's time to reuse the body of the original defun: + \expandafter\gobbledefun#1% +} +\def\gobbledefun#1\startdefun{} + +% \printdefunline \deffnheader{text} +% +\def\printdefunline#1#2{% + \begingroup + % call \deffnheader: + #1#2 \endheader + % common ending: + \interlinepenalty = 10000 + \advance\rightskip by 0pt plus 1fil\relax + \endgraf + \nobreak\vskip -\parskip + \penalty\defunpenalty % signal to \startdefun and \dodefunx + % Some of the @defun-type tags do not enable magic parentheses, + % rendering the following check redundant. But we don't optimize. + \checkparencounts + \endgroup +} + +\def\Edefun{\endgraf\medbreak} + +% \makedefun{deffn} creates \deffn, \deffnx and \Edeffn; +% the only thing remaining is to define \deffnheader. +% +\def\makedefun#1{% + \expandafter\let\csname E#1\endcsname = \Edefun + \edef\temp{\noexpand\domakedefun + \makecsname{#1}\makecsname{#1x}\makecsname{#1header}}% + \temp +} + +% \domakedefun \deffn \deffnx \deffnheader { (defn. of \deffnheader) } +% +% Define \deffn and \deffnx, without parameters. +% \deffnheader has to be defined explicitly. +% +\def\domakedefun#1#2#3{% + \envdef#1{% + \startdefun + \doingtypefnfalse % distinguish typed functions from all else + \parseargusing\activeparens{\printdefunline#3}% + }% + \def#2{\dodefunx#1}% + \def#3% +} + +\newif\ifdoingtypefn % doing typed function? +\newif\ifrettypeownline % typeset return type on its own line? + +% @deftypefnnewline on|off says whether the return type of typed functions +% are printed on their own line. This affects @deftypefn, @deftypefun, +% @deftypeop, and @deftypemethod. +% +\parseargdef\deftypefnnewline{% + \def\temp{#1}% + \ifx\temp\onword + \expandafter\let\csname SETtxideftypefnnl\endcsname + = \empty + \else\ifx\temp\offword + \expandafter\let\csname SETtxideftypefnnl\endcsname + = \relax + \else + \errhelp = \EMsimple + \errmessage{Unknown @txideftypefnnl value `\temp', + must be on|off}% + \fi\fi +} + +% Untyped functions: + +% @deffn category name args +\makedefun{deffn}{\deffngeneral{}} + +% @deffn category class name args +\makedefun{defop}#1 {\defopon{#1\ \putwordon}} + +% \defopon {category on}class name args +\def\defopon#1#2 {\deffngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} } + +% \deffngeneral {subind}category name args +% +\def\deffngeneral#1#2 #3 #4\endheader{% + % Remember that \dosubind{fn}{foo}{} is equivalent to \doind{fn}{foo}. + \dosubind{fn}{\code{#3}}{#1}% + \defname{#2}{}{#3}\magicamp\defunargs{#4\unskip}% +} + +% Typed functions: + +% @deftypefn category type name args +\makedefun{deftypefn}{\deftypefngeneral{}} + +% @deftypeop category class type name args +\makedefun{deftypeop}#1 {\deftypeopon{#1\ \putwordon}} + +% \deftypeopon {category on}class type name args +\def\deftypeopon#1#2 {\deftypefngeneral{\putwordon\ \code{#2}}{#1\ \code{#2}} } + +% \deftypefngeneral {subind}category type name args +% +\def\deftypefngeneral#1#2 #3 #4 #5\endheader{% + \dosubind{fn}{\code{#4}}{#1}% + \doingtypefntrue + \defname{#2}{#3}{#4}\defunargs{#5\unskip}% +} + +% Typed variables: + +% @deftypevr category type var args +\makedefun{deftypevr}{\deftypecvgeneral{}} + +% @deftypecv category class type var args +\makedefun{deftypecv}#1 {\deftypecvof{#1\ \putwordof}} + +% \deftypecvof {category of}class type var args +\def\deftypecvof#1#2 {\deftypecvgeneral{\putwordof\ \code{#2}}{#1\ \code{#2}} } + +% \deftypecvgeneral {subind}category type var args +% +\def\deftypecvgeneral#1#2 #3 #4 #5\endheader{% + \dosubind{vr}{\code{#4}}{#1}% + \defname{#2}{#3}{#4}\defunargs{#5\unskip}% +} + +% Untyped variables: + +% @defvr category var args +\makedefun{defvr}#1 {\deftypevrheader{#1} {} } + +% @defcv category class var args +\makedefun{defcv}#1 {\defcvof{#1\ \putwordof}} + +% \defcvof {category of}class var args +\def\defcvof#1#2 {\deftypecvof{#1}#2 {} } + +% Types: + +% @deftp category name args +\makedefun{deftp}#1 #2 #3\endheader{% + \doind{tp}{\code{#2}}% + \defname{#1}{}{#2}\defunargs{#3\unskip}% +} + +% Remaining @defun-like shortcuts: +\makedefun{defun}{\deffnheader{\putwordDeffunc} } +\makedefun{defmac}{\deffnheader{\putwordDefmac} } +\makedefun{defspec}{\deffnheader{\putwordDefspec} } +\makedefun{deftypefun}{\deftypefnheader{\putwordDeffunc} } +\makedefun{defvar}{\defvrheader{\putwordDefvar} } +\makedefun{defopt}{\defvrheader{\putwordDefopt} } +\makedefun{deftypevar}{\deftypevrheader{\putwordDefvar} } +\makedefun{defmethod}{\defopon\putwordMethodon} +\makedefun{deftypemethod}{\deftypeopon\putwordMethodon} +\makedefun{defivar}{\defcvof\putwordInstanceVariableof} +\makedefun{deftypeivar}{\deftypecvof\putwordInstanceVariableof} + +% \defname, which formats the name of the @def (not the args). +% #1 is the category, such as "Function". +% #2 is the return type, if any. +% #3 is the function name. +% +% We are followed by (but not passed) the arguments, if any. +% +\def\defname#1#2#3{% + \par + % Get the values of \leftskip and \rightskip as they were outside the @def... + \advance\leftskip by -\defbodyindent + % + % Determine if we are typesetting the return type of a typed function + % on a line by itself. + \rettypeownlinefalse + \ifdoingtypefn % doing a typed function specifically? + % then check user option for putting return type on its own line: + \expandafter\ifx\csname SETtxideftypefnnl\endcsname\relax \else + \rettypeownlinetrue + \fi + \fi + % + % How we'll format the category name. Putting it in brackets helps + % distinguish it from the body text that may end up on the next line + % just below it. + \def\temp{#1}% + \setbox0=\hbox{\kern\deflastargmargin \ifx\temp\empty\else [\rm\temp]\fi} + % + % Figure out line sizes for the paragraph shape. We'll always have at + % least two. + \tempnum = 2 + % + % The first line needs space for \box0; but if \rightskip is nonzero, + % we need only space for the part of \box0 which exceeds it: + \dimen0=\hsize \advance\dimen0 by -\wd0 \advance\dimen0 by \rightskip + % + % If doing a return type on its own line, we'll have another line. + \ifrettypeownline + \advance\tempnum by 1 + \def\maybeshapeline{0in \hsize}% + \else + \def\maybeshapeline{}% + \fi + % + % The continuations: + \dimen2=\hsize \advance\dimen2 by -\defargsindent + % + % The final paragraph shape: + \parshape \tempnum 0in \dimen0 \maybeshapeline \defargsindent \dimen2 + % + % Put the category name at the right margin. + \noindent + \hbox to 0pt{% + \hfil\box0 \kern-\hsize + % \hsize has to be shortened this way: + \kern\leftskip + % Intentionally do not respect \rightskip, since we need the space. + }% + % + % Allow all lines to be underfull without complaint: + \tolerance=10000 \hbadness=10000 + \exdentamount=\defbodyindent + {% + % defun fonts. We use typewriter by default (used to be bold) because: + % . we're printing identifiers, they should be in tt in principle. + % . in languages with many accents, such as Czech or French, it's + % common to leave accents off identifiers. The result looks ok in + % tt, but exceedingly strange in rm. + % . we don't want -- and --- to be treated as ligatures. + % . this still does not fix the ?` and !` ligatures, but so far no + % one has made identifiers using them :). + \df \tt + \def\temp{#2}% text of the return type + \ifx\temp\empty\else + \tclose{\temp}% typeset the return type + \ifrettypeownline + % put return type on its own line; prohibit line break following: + \hfil\vadjust{\nobreak}\break + \else + \space % type on same line, so just followed by a space + \fi + \fi % no return type + #3% output function name + }% + {\rm\enskip}% hskip 0.5 em of \rmfont + % + \boldbrax + % arguments will be output next, if any. +} + +% Print arguments in slanted roman (not ttsl), inconsistently with using +% tt for the name. This is because literal text is sometimes needed in +% the argument list (groff manual), and ttsl and tt are not very +% distinguishable. Prevent hyphenation at `-' chars. +% +\def\defunargs#1{% + % use sl by default (not ttsl), + % tt for the names. + \df \sl \hyphenchar\font=0 + % + % On the other hand, if an argument has two dashes (for instance), we + % want a way to get ttsl. We used to recommend @var for that, so + % leave the code in, but it's strange for @var to lead to typewriter. + % Nowadays we recommend @code, since the difference between a ttsl hyphen + % and a tt hyphen is pretty tiny. @code also disables ?` !`. + \def\var##1{{\setupmarkupstyle{var}\ttslanted{##1}}}% + #1% + \sl\hyphenchar\font=45 +} + +% We want ()&[] to print specially on the defun line. +% +\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 = ) + +% 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. +{ + \activeparens + \global\let(=\lparen \global\let)=\rparen + \global\let[=\lbrack \global\let]=\rbrack + \global\let& = \& + + \gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb} + \gdef\magicamp{\let&=\amprm} +} + +\newcount\parencount + +% If we encounter &foo, then turn on ()-hacking afterwards +\newif\ifampseen +\def\amprm#1 {\ampseentrue{\bf\ }} + +\def\parenfont{% + \ifampseen + % At the first level, print parens in roman, + % otherwise use the default font. + \ifnum \parencount=1 \rm \fi + \else + % The \sf parens (in \boldbrax) actually are a little bolder than + % the contained text. This is especially needed for [ and ] . + \sf + \fi +} +\def\infirstlevel#1{% + \ifampseen + \ifnum\parencount=1 + #1% + \fi + \fi +} +\def\bfafterword#1 {#1 \bf} + +\def\opnr{% + \global\advance\parencount by 1 + {\parenfont(}% + \infirstlevel \bfafterword +} +\def\clnr{% + {\parenfont)}% + \infirstlevel \sl + \global\advance\parencount by -1 +} + +\newcount\brackcount +\def\lbrb{% + \global\advance\brackcount by 1 + {\bf[}% +} +\def\rbrb{% + {\bf]}% + \global\advance\brackcount by -1 +} + +\def\checkparencounts{% + \ifnum\parencount=0 \else \badparencount \fi + \ifnum\brackcount=0 \else \badbrackcount \fi +} +% these should not use \errmessage; the glibc manual, at least, actually +% has such constructs (when documenting function pointers). +\def\badparencount{% + \message{Warning: unbalanced parentheses in @def...}% + \global\parencount=0 +} +\def\badbrackcount{% + \message{Warning: unbalanced square brackets in @def...}% + \global\brackcount=0 +} + + +\message{macros,} +% @macro. + +% To do this right we need a feature of e-TeX, \scantokens, +% which we arrange to emulate with a temporary file in ordinary TeX. +\ifx\eTeXversion\thisisundefined + \newwrite\macscribble + \def\scantokens#1{% + \toks0={#1}% + \immediate\openout\macscribble=\jobname.tmp + \immediate\write\macscribble{\the\toks0}% + \immediate\closeout\macscribble + \input \jobname.tmp + } +\fi + +% alias because \c means cedilla in @tex or @math +\let\texinfoc=\c + +\newcount\savedcatcodeone +\newcount\savedcatcodetwo + +% Used at the time of macro expansion. +% Argument is macro body with arguments substituted +\def\scanmacro#1{% + \newlinechar`\^^M + \def\xeatspaces{\eatspaces}% + % + % Temporarily undo catcode changes of \printindex. Set catcode of @ to + % 0 so that @-commands in macro expansions aren't printed literally when + % formatting an index file, where \ is used as the escape character. + \savedcatcodeone=\catcode`\@ + \savedcatcodetwo=\catcode`\\ + \catcode`\@=0 + \catcode`\\=\active + % + % Process the macro body under the current catcode regime. + \scantokens{#1@texinfoc}% + % + \catcode`\@=\savedcatcodeone + \catcode`\\=\savedcatcodetwo + % + % The \texinfoc is to remove the \newlinechar added by \scantokens, and + % can be noticed by \parsearg. + % We avoid surrounding the call to \scantokens with \bgroup and \egroup + % to allow macros to open or close groups themselves. +} + +% Used for copying and captions +\def\scanexp#1{% + \expandafter\scanmacro\expandafter{#1}% +} + +\newcount\paramno % Count of parameters +\newtoks\macname % Macro name +\newif\ifrecursive % Is it recursive? + +% List of all defined macros in the form +% \commondummyword\macro1\commondummyword\macro2... +% Currently is also contains all @aliases; the list can be split +% if there is a need. +\def\macrolist{} + +% Add the macro to \macrolist +\def\addtomacrolist#1{\expandafter \addtomacrolistxxx \csname#1\endcsname} +\def\addtomacrolistxxx#1{% + \toks0 = \expandafter{\macrolist\commondummyword#1}% + \xdef\macrolist{\the\toks0}% +} + +% Utility routines. +% This does \let #1 = #2, with \csnames; that is, +% \let \csname#1\endcsname = \csname#2\endcsname +% (except of course we have to play expansion games). +% +\def\cslet#1#2{% + \expandafter\let + \csname#1\expandafter\endcsname + \csname#2\endcsname +} + +% Trim leading and trailing spaces off a string. +% Concepts from aro-bend problem 15 (see CTAN). +{\catcode`\@=11 +\gdef\eatspaces #1{\expandafter\trim@\expandafter{#1 }} +\gdef\trim@ #1{\trim@@ @#1 @ #1 @ @@} +\gdef\trim@@ #1@ #2@ #3@@{\trim@@@\empty #2 @} +\def\unbrace#1{#1} +\unbrace{\gdef\trim@@@ #1 } #2@{#1} +} + +% Trim a single trailing ^^M off a string. +{\catcode`\^^M=\other \catcode`\Q=3% +\gdef\eatcr #1{\eatcra #1Q^^MQ}% +\gdef\eatcra#1^^MQ{\eatcrb#1Q}% +\gdef\eatcrb#1Q#2Q{#1}% +} + +% Macro bodies are absorbed as an argument in a context where +% all characters are catcode 10, 11 or 12, except \ which is active +% (as in normal texinfo). It is necessary to change the definition of \ +% to recognize macro arguments; this is the job of \mbodybackslash. +% +% Non-ASCII encodings make 8-bit characters active, so un-activate +% them to avoid their expansion. Must do this non-globally, to +% confine the change to the current group. +% +% It's necessary to have hard CRs when the macro is executed. This is +% done by making ^^M (\endlinechar) catcode 12 when reading the macro +% body, and then making it the \newlinechar in \scanmacro. +% +\def\scanctxt{% used as subroutine + \catcode`\"=\other + \catcode`\+=\other + \catcode`\<=\other + \catcode`\>=\other + \catcode`\^=\other + \catcode`\_=\other + \catcode`\|=\other + \catcode`\~=\other + \passthroughcharstrue +} + +\def\scanargctxt{% used for copying and captions, not macros. + \scanctxt + \catcode`\@=\other + \catcode`\\=\other + \catcode`\^^M=\other +} + +\def\macrobodyctxt{% used for @macro definitions + \scanctxt + \catcode`\ =\other + \catcode`\@=\other + \catcode`\{=\other + \catcode`\}=\other + \catcode`\^^M=\other + \usembodybackslash +} + +% Used when scanning braced macro arguments. Note, however, that catcode +% changes here are ineffectual if the macro invocation was nested inside +% an argument to another Texinfo command. +\def\macroargctxt{% + \scanctxt + \catcode`\ =\active + \catcode`\^^M=\other + \catcode`\\=\active +} + +\def\macrolineargctxt{% used for whole-line arguments without braces + \scanctxt + \catcode`\{=\other + \catcode`\}=\other +} + +% \mbodybackslash is the definition of \ in @macro bodies. +% It maps \foo\ => \csname macarg.foo\endcsname => #N +% where N is the macro parameter number. +% We define \csname macarg.\endcsname to be \realbackslash, so +% \\ in macro replacement text gets you a backslash. +% +{\catcode`@=0 @catcode`@\=@active + @gdef@usembodybackslash{@let\=@mbodybackslash} + @gdef@mbodybackslash#1\{@csname macarg.#1@endcsname} +} +\expandafter\def\csname macarg.\endcsname{\realbackslash} + +\def\margbackslash#1{\char`\#1 } + +\def\macro{\recursivefalse\parsearg\macroxxx} +\def\rmacro{\recursivetrue\parsearg\macroxxx} + +\def\macroxxx#1{% + \getargs{#1}% now \macname is the macname and \argl the arglist + \ifx\argl\empty % no arguments + \paramno=0\relax + \else + \expandafter\parsemargdef \argl;% + \if\paramno>256\relax + \ifx\eTeXversion\thisisundefined + \errhelp = \EMsimple + \errmessage{You need eTeX to compile a file with macros with more than 256 arguments} + \fi + \fi + \fi + \if1\csname ismacro.\the\macname\endcsname + \message{Warning: redefining \the\macname}% + \else + \expandafter\ifx\csname \the\macname\endcsname \relax + \else \errmessage{Macro name \the\macname\space already defined}\fi + \global\cslet{macsave.\the\macname}{\the\macname}% + \global\expandafter\let\csname ismacro.\the\macname\endcsname=1% + \addtomacrolist{\the\macname}% + \fi + \begingroup \macrobodyctxt + \ifrecursive \expandafter\parsermacbody + \else \expandafter\parsemacbody + \fi} + +\parseargdef\unmacro{% + \if1\csname ismacro.#1\endcsname + \global\cslet{#1}{macsave.#1}% + \global\expandafter\let \csname ismacro.#1\endcsname=0% + % Remove the macro name from \macrolist: + \begingroup + \expandafter\let\csname#1\endcsname \relax + \let\commondummyword\unmacrodo + \xdef\macrolist{\macrolist}% + \endgroup + \else + \errmessage{Macro #1 not defined}% + \fi +} + +% Called by \do from \dounmacro on each macro. The idea is to omit any +% macro definitions that have been changed to \relax. +% +\def\unmacrodo#1{% + \ifx #1\relax + % remove this + \else + \noexpand\commondummyword \noexpand#1% + \fi +} + +% \getargs -- Parse the arguments to a @macro line. Set \macname to +% the name of the macro, and \argl to the braced argument list. +\def\getargs#1{\getargsxxx#1{}} +\def\getargsxxx#1#{\getmacname #1 \relax\getmacargs} +\def\getmacname#1 #2\relax{\macname={#1}} +\def\getmacargs#1{\def\argl{#1}} +% This made use of the feature that if the last token of a +% <parameter list> is #, then the preceding argument is delimited by +% an opening brace, and that opening brace is not consumed. + +% Parse the optional {params} list to @macro or @rmacro. +% Set \paramno to the number of arguments, +% and \paramlist to a parameter text for the macro (e.g. #1,#2,#3 for a +% three-param macro.) Define \macarg.BLAH for each BLAH in the params +% list to some hook where the argument is to be expanded. If there are +% less than 10 arguments that hook is to be replaced by ##N where N +% is the position in that list, that is to say the macro arguments are to be +% defined `a la TeX in the macro body. +% +% That gets used by \mbodybackslash (above). +% +% If there are 10 or more arguments, a different technique is used: see +% \parsemmanyargdef. +% +\def\parsemargdef#1;{% + \paramno=0\def\paramlist{}% + \let\hash\relax + % \hash is redefined to `#' later to get it into definitions + \let\xeatspaces\relax + \parsemargdefxxx#1,;,% + \ifnum\paramno<10\relax\else + \paramno0\relax + \parsemmanyargdef@@#1,;,% 10 or more arguments + \fi +} +\def\parsemargdefxxx#1,{% + \if#1;\let\next=\relax + \else \let\next=\parsemargdefxxx + \advance\paramno by 1 + \expandafter\edef\csname macarg.\eatspaces{#1}\endcsname + {\xeatspaces{\hash\the\paramno}}% + \edef\paramlist{\paramlist\hash\the\paramno,}% + \fi\next} + +% \parsemacbody, \parsermacbody +% +% Read recursive and nonrecursive macro bodies. (They're different since +% rec and nonrec macros end differently.) +% +% We are in \macrobodyctxt, and the \xdef causes backslashshes in the macro +% body to be transformed. +% Set \macrobody to the body of the macro, and call \defmacro. +% +{\catcode`\ =\other\long\gdef\parsemacbody#1@end macro{% +\xdef\macrobody{\eatcr{#1}}\endgroup\defmacro}}% +{\catcode`\ =\other\long\gdef\parsermacbody#1@end rmacro{% +\xdef\macrobody{\eatcr{#1}}\endgroup\defmacro}}% + +% Make @ a letter, so that we can make private-to-Texinfo macro names. +\edef\texiatcatcode{\the\catcode`\@} +\catcode `@=11\relax + +%%%%%%%%%%%%%% Code for > 10 arguments only %%%%%%%%%%%%%%%%%% + +% If there are 10 or more arguments, a different technique is used, where the +% hook remains in the body, and when macro is to be expanded the body is +% processed again to replace the arguments. +% +% In that case, the hook is \the\toks N-1, and we simply set \toks N-1 to the +% argument N value and then \edef the body (nothing else will expand because of +% the catcode regime under which the body was input). +% +% If you compile with TeX (not eTeX), and you have macros with 10 or more +% arguments, no macro can have more than 256 arguments (else error). +% +% In case that there are 10 or more arguments we parse again the arguments +% list to set new definitions for the \macarg.BLAH macros corresponding to +% each BLAH argument. It was anyhow needed to parse already once this list +% in order to count the arguments, and as macros with at most 9 arguments +% are by far more frequent than macro with 10 or more arguments, defining +% twice the \macarg.BLAH macros does not cost too much processing power. +\def\parsemmanyargdef@@#1,{% + \if#1;\let\next=\relax + \else + \let\next=\parsemmanyargdef@@ + \edef\tempb{\eatspaces{#1}}% + \expandafter\def\expandafter\tempa + \expandafter{\csname macarg.\tempb\endcsname}% + % Note that we need some extra \noexpand\noexpand, this is because we + % don't want \the to be expanded in the \parsermacbody as it uses an + % \xdef . + \expandafter\edef\tempa + {\noexpand\noexpand\noexpand\the\toks\the\paramno}% + \advance\paramno by 1\relax + \fi\next} + + +\let\endargs@\relax +\let\nil@\relax +\def\nilm@{\nil@}% +\long\def\nillm@{\nil@}% + +% This macro is expanded during the Texinfo macro expansion, not during its +% definition. It gets all the arguments' values and assigns them to macros +% macarg.ARGNAME +% +% #1 is the macro name +% #2 is the list of argument names +% #3 is the list of argument values +\def\getargvals@#1#2#3{% + \def\macargdeflist@{}% + \def\saveparamlist@{#2}% Need to keep a copy for parameter expansion. + \def\paramlist{#2,\nil@}% + \def\macroname{#1}% + \begingroup + \macroargctxt + \def\argvaluelist{#3,\nil@}% + \def\@tempa{#3}% + \ifx\@tempa\empty + \setemptyargvalues@ + \else + \getargvals@@ + \fi +} +\def\getargvals@@{% + \ifx\paramlist\nilm@ + % Some sanity check needed here that \argvaluelist is also empty. + \ifx\argvaluelist\nillm@ + \else + \errhelp = \EMsimple + \errmessage{Too many arguments in macro `\macroname'!}% + \fi + \let\next\macargexpandinbody@ + \else + \ifx\argvaluelist\nillm@ + % No more arguments values passed to macro. Set remaining named-arg + % macros to empty. + \let\next\setemptyargvalues@ + \else + % pop current arg name into \@tempb + \def\@tempa##1{\pop@{\@tempb}{\paramlist}##1\endargs@}% + \expandafter\@tempa\expandafter{\paramlist}% + % pop current argument value into \@tempc + \def\@tempa##1{\longpop@{\@tempc}{\argvaluelist}##1\endargs@}% + \expandafter\@tempa\expandafter{\argvaluelist}% + % Here \@tempb is the current arg name and \@tempc is the current arg value. + % First place the new argument macro definition into \@tempd + \expandafter\macname\expandafter{\@tempc}% + \expandafter\let\csname macarg.\@tempb\endcsname\relax + \expandafter\def\expandafter\@tempe\expandafter{% + \csname macarg.\@tempb\endcsname}% + \edef\@tempd{\long\def\@tempe{\the\macname}}% + \push@\@tempd\macargdeflist@ + \let\next\getargvals@@ + \fi + \fi + \next +} + +\def\push@#1#2{% + \expandafter\expandafter\expandafter\def + \expandafter\expandafter\expandafter#2% + \expandafter\expandafter\expandafter{% + \expandafter#1#2}% +} + +% Replace arguments by their values in the macro body, and place the result +% in macro \@tempa. +% +\def\macvalstoargs@{% + % To do this we use the property that token registers that are \the'ed + % within an \edef expand only once. So we are going to place all argument + % values into respective token registers. + % + % First we save the token context, and initialize argument numbering. + \begingroup + \paramno0\relax + % Then, for each argument number #N, we place the corresponding argument + % value into a new token list register \toks#N + \expandafter\putargsintokens@\saveparamlist@,;,% + % Then, we expand the body so that argument are replaced by their + % values. The trick for values not to be expanded themselves is that they + % are within tokens and that tokens expand only once in an \edef . + \edef\@tempc{\csname mac.\macroname .body\endcsname}% + % Now we restore the token stack pointer to free the token list registers + % which we have used, but we make sure that expanded body is saved after + % group. + \expandafter + \endgroup + \expandafter\def\expandafter\@tempa\expandafter{\@tempc}% + } + +% Define the named-macro outside of this group and then close this group. +% +\def\macargexpandinbody@{% + \expandafter + \endgroup + \macargdeflist@ + % First the replace in body the macro arguments by their values, the result + % is in \@tempa . + \macvalstoargs@ + % Then we point at the \norecurse or \gobble (for recursive) macro value + % with \@tempb . + \expandafter\let\expandafter\@tempb\csname mac.\macroname .recurse\endcsname + % Depending on whether it is recursive or not, we need some tailing + % \egroup . + \ifx\@tempb\gobble + \let\@tempc\relax + \else + \let\@tempc\egroup + \fi + % And now we do the real job: + \edef\@tempd{\noexpand\@tempb{\macroname}\noexpand\scanmacro{\@tempa}\@tempc}% + \@tempd +} + +\def\putargsintokens@#1,{% + \if#1;\let\next\relax + \else + \let\next\putargsintokens@ + % First we allocate the new token list register, and give it a temporary + % alias \@tempb . + \toksdef\@tempb\the\paramno + % Then we place the argument value into that token list register. + \expandafter\let\expandafter\@tempa\csname macarg.#1\endcsname + \expandafter\@tempb\expandafter{\@tempa}% + \advance\paramno by 1\relax + \fi + \next +} + +% Trailing missing arguments are set to empty. +% +\def\setemptyargvalues@{% + \ifx\paramlist\nilm@ + \let\next\macargexpandinbody@ + \else + \expandafter\setemptyargvaluesparser@\paramlist\endargs@ + \let\next\setemptyargvalues@ + \fi + \next +} + +\def\setemptyargvaluesparser@#1,#2\endargs@{% + \expandafter\def\expandafter\@tempa\expandafter{% + \expandafter\def\csname macarg.#1\endcsname{}}% + \push@\@tempa\macargdeflist@ + \def\paramlist{#2}% +} + +% #1 is the element target macro +% #2 is the list macro +% #3,#4\endargs@ is the list value +\def\pop@#1#2#3,#4\endargs@{% + \def#1{#3}% + \def#2{#4}% +} +\long\def\longpop@#1#2#3,#4\endargs@{% + \long\def#1{#3}% + \long\def#2{#4}% +} + + +%%%%%%%%%%%%%% End of code for > 10 arguments %%%%%%%%%%%%%%%%%% + + +% This defines a Texinfo @macro or @rmacro, called by \parsemacbody. +% \macrobody has the body of the macro in it, with placeholders for +% its parameters, looking like "\xeatspaces{\hash 1}". +% \paramno is the number of parameters +% \paramlist is a TeX parameter text, e.g. "#1,#2,#3," +% There are four cases: macros of zero, one, up to nine, and many arguments. +% \xdef is used so that macro definitions will survive the file +% they're defined in: @include reads the file inside a group. +% +\def\defmacro{% + \let\hash=##% convert placeholders to macro parameter chars + \ifnum\paramno=1 + \def\xeatspaces##1{##1}% + % This removes the pair of braces around the argument. We don't + % use \eatspaces, because this can cause ends of lines to be lost + % when the argument to \eatspaces is read, leading to line-based + % commands like "@itemize" not being read correctly. + \else + \let\xeatspaces\relax % suppress expansion + \fi + \ifcase\paramno + % 0 + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup + \noexpand\spaceisspace + \noexpand\endlineisspace + \noexpand\expandafter % skip any whitespace after the macro name. + \expandafter\noexpand\csname\the\macname @@@\endcsname}% + \expandafter\xdef\csname\the\macname @@@\endcsname{% + \egroup + \noexpand\scanmacro{\macrobody}}% + \or % 1 + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup + \noexpand\braceorline + \expandafter\noexpand\csname\the\macname @@@\endcsname}% + \expandafter\xdef\csname\the\macname @@@\endcsname##1{% + \egroup + \noexpand\scanmacro{\macrobody}% + }% + \else % at most 9 + \ifnum\paramno<10\relax + % @MACNAME sets the context for reading the macro argument + % @MACNAME@@ gets the argument, processes backslashes and appends a + % comma. + % @MACNAME@@@ removes braces surrounding the argument list. + % @MACNAME@@@@ scans the macro body with arguments substituted. + \expandafter\xdef\csname\the\macname\endcsname{% + \bgroup + \noexpand\expandafter % This \expandafter skip any spaces after the + \noexpand\macroargctxt % macro before we change the catcode of space. + \noexpand\expandafter + \expandafter\noexpand\csname\the\macname @@\endcsname}% + \expandafter\xdef\csname\the\macname @@\endcsname##1{% + \noexpand\passargtomacro + \expandafter\noexpand\csname\the\macname @@@\endcsname{##1,}}% + \expandafter\xdef\csname\the\macname @@@\endcsname##1{% + \expandafter\noexpand\csname\the\macname @@@@\endcsname ##1}% + \expandafter\expandafter + \expandafter\xdef + \expandafter\expandafter + \csname\the\macname @@@@\endcsname\paramlist{% + \egroup\noexpand\scanmacro{\macrobody}}% + \else % 10 or more: + \expandafter\xdef\csname\the\macname\endcsname{% + \noexpand\getargvals@{\the\macname}{\argl}% + }% + \global\expandafter\let\csname mac.\the\macname .body\endcsname\macrobody + \global\expandafter\let\csname mac.\the\macname .recurse\endcsname\gobble + \fi + \fi} + +\catcode `\@\texiatcatcode\relax % end private-to-Texinfo catcodes + +\def\norecurse#1{\bgroup\cslet{#1}{macsave.#1}} + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +{\catcode`\@=0 \catcode`\\=13 % We need to manipulate \ so use @ as escape +@catcode`@_=11 % private names +@catcode`@!=11 % used as argument separator + +% \passargtomacro#1#2 - +% Call #1 with a list of tokens #2, with any doubled backslashes in #2 +% compressed to one. +% +% This implementation works by expansion, and not execution (so we cannot use +% \def or similar). This reduces the risk of this failing in contexts where +% complete expansion is done with no execution (for example, in writing out to +% an auxiliary file for an index entry). +% +% State is kept in the input stream: the argument passed to +% @look_ahead, @gobble_and_check_finish and @add_segment is +% +% THE_MACRO ARG_RESULT ! {PENDING_BS} NEXT_TOKEN (... rest of input) +% +% where: +% THE_MACRO - name of the macro we want to call +% ARG_RESULT - argument list we build to pass to that macro +% PENDING_BS - either a backslash or nothing +% NEXT_TOKEN - used to look ahead in the input stream to see what's coming next + +@gdef@passargtomacro#1#2{% + @add_segment #1!{}@relax#2\@_finish\% +} +@gdef@_finish{@_finishx} @global@let@_finishx@relax + +% #1 - THE_MACRO ARG_RESULT +% #2 - PENDING_BS +% #3 - NEXT_TOKEN +% #4 used to look ahead +% +% If the next token is not a backslash, process the rest of the argument; +% otherwise, remove the next token. +@gdef@look_ahead#1!#2#3#4{% + @ifx#4\% + @expandafter@gobble_and_check_finish + @else + @expandafter@add_segment + @fi#1!{#2}#4#4% +} + +% #1 - THE_MACRO ARG_RESULT +% #2 - PENDING_BS +% #3 - NEXT_TOKEN +% #4 should be a backslash, which is gobbled. +% #5 looks ahead +% +% Double backslash found. Add a single backslash, and look ahead. +@gdef@gobble_and_check_finish#1!#2#3#4#5{% + @add_segment#1\!{}#5#5% +} + +@gdef@is_fi{@fi} + +% #1 - THE_MACRO ARG_RESULT +% #2 - PENDING_BS +% #3 - NEXT_TOKEN +% #4 is input stream until next backslash +% +% Input stream is either at the start of the argument, or just after a +% backslash sequence, either a lone backslash, or a doubled backslash. +% NEXT_TOKEN contains the first token in the input stream: if it is \finish, +% finish; otherwise, append to ARG_RESULT the segment of the argument up until +% the next backslash. PENDING_BACKSLASH contains a backslash to represent +% a backslash just before the start of the input stream that has not been +% added to ARG_RESULT. +@gdef@add_segment#1!#2#3#4\{% +@ifx#3@_finish + @call_the_macro#1!% +@else + % append the pending backslash to the result, followed by the next segment + @expandafter@is_fi@look_ahead#1#2#4!{\}@fi + % this @fi is discarded by @look_ahead. + % we can't get rid of it with \expandafter because we don't know how + % long #4 is. +} + +% #1 - THE_MACRO +% #2 - ARG_RESULT +% #3 discards the res of the conditional in @add_segment, and @is_fi ends the +% conditional. +@gdef@call_the_macro#1#2!#3@fi{@is_fi #1{#2}} + +} +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% \braceorline MAC is used for a one-argument macro MAC. It checks +% whether the next non-whitespace character is a {. It sets the context +% for reading the argument (slightly different in the two cases). Then, +% to read the argument, in the whole-line case, it then calls the regular +% \parsearg MAC; in the lbrace case, it calls \passargtomacro MAC. +% +\def\braceorline#1{\let\macnamexxx=#1\futurelet\nchar\braceorlinexxx} +\def\braceorlinexxx{% + \ifx\nchar\bgroup + \macroargctxt + \expandafter\passargtomacro + \else + \macrolineargctxt\expandafter\parsearg + \fi \macnamexxx} + + +% @alias. +% We need some trickery to remove the optional spaces around the equal +% sign. Make them active and then expand them all to nothing. +% +\def\alias{\parseargusing\obeyspaces\aliasxxx} +\def\aliasxxx #1{\aliasyyy#1\relax} +\def\aliasyyy #1=#2\relax{% + {% + \expandafter\let\obeyedspace=\empty + \addtomacrolist{#1}% + \xdef\next{\global\let\makecsname{#1}=\makecsname{#2}}% + }% + \next +} + + +\message{cross references,} + +\newwrite\auxfile +\newif\ifhavexrefs % True if xref values are known. +\newif\ifwarnedxrefs % True if we warned once that they aren't known. + +% @inforef is relatively simple. +\def\inforef #1{\inforefzzz #1,,,,**} +\def\inforefzzz #1,#2,#3,#4**{% + \putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}}, + node \samp{\ignorespaces#1{}}} + +% @node's only job in TeX is to define \lastnode, which is used in +% cross-references. The @node line might or might not have commas, and +% might or might not have spaces before the first comma, like: +% @node foo , bar , ... +% We don't want such trailing spaces in the node name. +% +\parseargdef\node{\checkenv{}\donode #1 ,\finishnodeparse} +% +% also remove a trailing comma, in case of something like this: +% @node Help-Cross, , , Cross-refs +\def\donode#1 ,#2\finishnodeparse{\dodonode #1,\finishnodeparse} +\def\dodonode#1,#2\finishnodeparse{\gdef\lastnode{#1}} + +\let\nwnode=\node +\let\lastnode=\empty + +% Write a cross-reference definition for the current node. #1 is the +% type (Ynumbered, Yappendix, Ynothing). +% +\def\donoderef#1{% + \ifx\lastnode\empty\else + \setref{\lastnode}{#1}% + \global\let\lastnode=\empty + \fi +} + +% @anchor{NAME} -- define xref target at arbitrary point. +% +\newcount\savesfregister +% +\def\savesf{\relax \ifhmode \savesfregister=\spacefactor \fi} +\def\restoresf{\relax \ifhmode \spacefactor=\savesfregister \fi} +\def\anchor#1{\savesf \setref{#1}{Ynothing}\restoresf \ignorespaces} + +% \setref{NAME}{SNT} defines a cross-reference point NAME (a node or an +% anchor), which consists of three parts: +% 1) NAME-title - the current sectioning name taken from \lastsection, +% or the anchor name. +% 2) NAME-snt - section number and type, passed as the SNT arg, or +% empty for anchors. +% 3) NAME-pg - the page number. +% +% This is called from \donoderef, \anchor, and \dofloat. In the case of +% floats, there is an additional part, which is not written here: +% 4) NAME-lof - the text as it should appear in a @listoffloats. +% +\def\setref#1#2{% + \pdfmkdest{#1}% + \iflinks + {% + \requireauxfile + \atdummies % preserve commands, but don't expand them + % match definition in \xrdef, \refx, \xrefX. + \def\value##1{##1}% + \edef\writexrdef##1##2{% + \write\auxfile{@xrdef{#1-% #1 of \setref, expanded by the \edef + ##1}{##2}}% these are parameters of \writexrdef + }% + \toks0 = \expandafter{\lastsection}% + \immediate \writexrdef{title}{\the\toks0 }% + \immediate \writexrdef{snt}{\csname #2\endcsname}% \Ynumbered etc. + \safewhatsit{\writexrdef{pg}{\folio}}% will be written later, at \shipout + }% + \fi +} + +% @xrefautosectiontitle on|off says whether @section(ing) names are used +% automatically in xrefs, if the third arg is not explicitly specified. +% This was provided as a "secret" @set xref-automatic-section-title +% variable, now it's official. +% +\parseargdef\xrefautomaticsectiontitle{% + \def\temp{#1}% + \ifx\temp\onword + \expandafter\let\csname SETxref-automatic-section-title\endcsname + = \empty + \else\ifx\temp\offword + \expandafter\let\csname SETxref-automatic-section-title\endcsname + = \relax + \else + \errhelp = \EMsimple + \errmessage{Unknown @xrefautomaticsectiontitle value `\temp', + must be on|off}% + \fi\fi +} + +% +% @xref, @pxref, and @ref generate cross-references. 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{\putwordsee{} \xrefXX} +\def\xref{\putwordSee{} \xrefXX} +\def\ref{\xrefXX} + +\def\xrefXX#1{\def\xrefXXarg{#1}\futurelet\tokenafterxref\xrefXXX} +\def\xrefXXX{\expandafter\xrefX\expandafter[\xrefXXarg,,,,,,,]} +% +\newbox\toprefbox +\newbox\printedrefnamebox +\newbox\infofilenamebox +\newbox\printedmanualbox +% +\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup + \unsepspaces + % + % Get args without leading/trailing spaces. + \def\printedrefname{\ignorespaces #3}% + \setbox\printedrefnamebox = \hbox{\printedrefname\unskip}% + % + \def\infofilename{\ignorespaces #4}% + \setbox\infofilenamebox = \hbox{\infofilename\unskip}% + % + \def\printedmanual{\ignorespaces #5}% + \setbox\printedmanualbox = \hbox{\printedmanual\unskip}% + % + % If the printed reference name (arg #3) was not explicitly given in + % the @xref, figure out what we want to use. + \ifdim \wd\printedrefnamebox = 0pt + % No printed node name was explicitly given. + \expandafter\ifx\csname SETxref-automatic-section-title\endcsname \relax + % Not auto section-title: use node name inside the square brackets. + \def\printedrefname{\ignorespaces #1}% + \else + % Auto section-title: use chapter/section title inside + % the square brackets if we have it. + \ifdim \wd\printedmanualbox > 0pt + % It is in another manual, so we don't have it; use node name. + \def\printedrefname{\ignorespaces #1}% + \else + \ifhavexrefs + % We (should) know the real title if we have the xref values. + \def\printedrefname{\refx{#1-title}{}}% + \else + % Otherwise just copy the Info node name. + \def\printedrefname{\ignorespaces #1}% + \fi% + \fi + \fi + \fi + % + % Make link in pdf output. + \ifpdf + % For pdfTeX and LuaTeX + {\indexnofonts + \makevalueexpandable + \turnoffactive + % This expands tokens, so do it after making catcode changes, so _ + % etc. don't get their TeX definitions. This ignores all spaces in + % #4, including (wrongly) those in the middle of the filename. + \getfilename{#4}% + % + % This (wrongly) does not take account of leading or trailing + % spaces in #1, which should be ignored. + \setpdfdestname{#1}% + % + \ifx\pdfdestname\empty + \def\pdfdestname{Top}% no empty targets + \fi + % + \leavevmode + \startlink attr{/Border [0 0 0]}% + \ifnum\filenamelength>0 + goto file{\the\filename.pdf} name{\pdfdestname}% + \else + goto name{\pdfmkpgn{\pdfdestname}}% + \fi + }% + \setcolor{\linkcolor}% + \else + \ifx\XeTeXrevision\thisisundefined + \else + % For XeTeX + {\indexnofonts + \makevalueexpandable + \turnoffactive + % This expands tokens, so do it after making catcode changes, so _ + % etc. don't get their TeX definitions. This ignores all spaces in + % #4, including (wrongly) those in the middle of the filename. + \getfilename{#4}% + % + % This (wrongly) does not take account of leading or trailing + % spaces in #1, which should be ignored. + \setpdfdestname{#1}% + % + \ifx\pdfdestname\empty + \def\pdfdestname{Top}% no empty targets + \fi + % + \leavevmode + \ifnum\filenamelength>0 + % With default settings, + % XeTeX (xdvipdfmx) replaces link destination names with integers. + % In this case, the replaced destination names of + % remote PDFs are no longer known. In order to avoid a replacement, + % you can use xdvipdfmx's command line option `-C 0x0010'. + % If you use XeTeX 0.99996+ (TeX Live 2016+), + % this command line option is no longer necessary + % because we can use the `dvipdfmx:config' special. + \special{pdf:bann << /Border [0 0 0] /Type /Annot /Subtype /Link /A + << /S /GoToR /F (\the\filename.pdf) /D (\pdfdestname) >> >>}% + \else + \special{pdf:bann << /Border [0 0 0] /Type /Annot /Subtype /Link /A + << /S /GoTo /D (\pdfdestname) >> >>}% + \fi + }% + \setcolor{\linkcolor}% + \fi + \fi + {% + % Have to otherify everything special to allow the \csname to + % include an _ in the xref name, etc. + \indexnofonts + \turnoffactive + \def\value##1{##1}% + \expandafter\global\expandafter\let\expandafter\Xthisreftitle + \csname XR#1-title\endcsname + }% + % + % Float references are printed completely differently: "Figure 1.2" + % instead of "[somenode], p.3". \iffloat distinguishes them by + % \Xthisreftitle being set to a magic string. + \iffloat\Xthisreftitle + % If the user specified the print name (third arg) to the ref, + % print it instead of our usual "Figure 1.2". + \ifdim\wd\printedrefnamebox = 0pt + \refx{#1-snt}{}% + \else + \printedrefname + \fi + % + % If the user also gave the printed manual name (fifth arg), append + % "in MANUALNAME". + \ifdim \wd\printedmanualbox > 0pt + \space \putwordin{} \cite{\printedmanual}% + \fi + \else + % node/anchor (non-float) references. + % + % If we use \unhbox 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 \wd\printedmanualbox > 0pt + % Cross-manual reference with a printed manual name. + % + \crossmanualxref{\cite{\printedmanual\unskip}}% + % + \else\ifdim \wd\infofilenamebox > 0pt + % Cross-manual reference with only an info filename (arg 4), no + % printed manual name (arg 5). This is essentially the same as + % the case above; we output the filename, since we have nothing else. + % + \crossmanualxref{\code{\infofilename\unskip}}% + % + \else + % Reference within this manual. + % + % _ (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 + % Only output a following space if the -snt ref is nonempty; for + % @unnumbered and @anchor, it won't be. + \setbox2 = \hbox{\ignorespaces \refx{#1-snt}{}}% + \ifdim \wd2 > 0pt \refx{#1-snt}\space\fi + }% + % output the `[mynode]' via the macro below so it can be overridden. + \xrefprintnodename\printedrefname + % + % But we always want a comma and a space: + ,\space + % + % output the `page 3'. + \turnoffactive \putwordpage\tie\refx{#1-pg}{}% + % Add a , if xref followed by a space + \if\space\noexpand\tokenafterxref ,% + \else\ifx\ \tokenafterxref ,% @TAB + \else\ifx\*\tokenafterxref ,% @* + \else\ifx\ \tokenafterxref ,% @SPACE + \else\ifx\ + \tokenafterxref ,% @NL + \else\ifx\tie\tokenafterxref ,% @tie + \fi\fi\fi\fi\fi\fi + \fi\fi + \fi + \endlink +\endgroup} + +% Output a cross-manual xref to #1. Used just above (twice). +% +% Only include the text "Section ``foo'' in" if the foo is neither +% missing or Top. Thus, @xref{,,,foo,The Foo Manual} outputs simply +% "see The Foo Manual", the idea being to refer to the whole manual. +% +% But, this being TeX, we can't easily compare our node name against the +% string "Top" while ignoring the possible spaces before and after in +% the input. By adding the arbitrary 7sp below, we make it much less +% likely that a real node name would have the same width as "Top" (e.g., +% in a monospaced font). Hopefully it will never happen in practice. +% +% For the same basic reason, we retypeset the "Top" at every +% reference, since the current font is indeterminate. +% +\def\crossmanualxref#1{% + \setbox\toprefbox = \hbox{Top\kern7sp}% + \setbox2 = \hbox{\ignorespaces \printedrefname \unskip \kern7sp}% + \ifdim \wd2 > 7sp % nonempty? + \ifdim \wd2 = \wd\toprefbox \else % same as Top? + \putwordSection{} ``\printedrefname'' \putwordin{}\space + \fi + \fi + #1% +} + +% This macro is called from \xrefX for the `[nodename]' part of xref +% output. It's a separate macro only so it can be changed more easily, +% since square brackets don't work well in some documents. Particularly +% one that Bob is working on :). +% +\def\xrefprintnodename#1{[#1]} + +% Things referred to by \setref. +% +\def\Ynothing{} +\def\Yomitfromtoc{} +\def\Ynumbered{% + \ifnum\secno=0 + \putwordChapter@tie \the\chapno + \else \ifnum\subsecno=0 + \putwordSection@tie \the\chapno.\the\secno + \else \ifnum\subsubsecno=0 + \putwordSection@tie \the\chapno.\the\secno.\the\subsecno + \else + \putwordSection@tie \the\chapno.\the\secno.\the\subsecno.\the\subsubsecno + \fi\fi\fi +} +\def\Yappendix{% + \ifnum\secno=0 + \putwordAppendix@tie @char\the\appendixno{}% + \else \ifnum\subsecno=0 + \putwordSection@tie @char\the\appendixno.\the\secno + \else \ifnum\subsubsecno=0 + \putwordSection@tie @char\the\appendixno.\the\secno.\the\subsecno + \else + \putwordSection@tie + @char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno + \fi\fi\fi +} + +% \refx{NAME}{SUFFIX} - reference a cross-reference string named NAME. SUFFIX +% is output afterwards if non-empty. +\def\refx#1#2{% + \requireauxfile + {% + \indexnofonts + \otherbackslash + \def\value##1{##1}% + \expandafter\global\expandafter\let\expandafter\thisrefX + \csname XR#1\endcsname + }% + \ifx\thisrefX\relax + % If not defined, say something at least. + \angleleft un\-de\-fined\angleright + \iflinks + \ifhavexrefs + {\toks0 = {#1}% avoid expansion of possibly-complex value + \message{\linenumber Undefined cross reference `\the\toks0'.}}% + \else + \ifwarnedxrefs\else + \global\warnedxrefstrue + \message{Cross reference values unknown; you must run TeX again.}% + \fi + \fi + \fi + \else + % It's defined, so just use it. + \thisrefX + \fi + #2% Output the suffix in any case. +} + +% This is the macro invoked by entries in the aux file. Define a control +% sequence for a cross-reference target (we prepend XR to the control sequence +% name to avoid collisions). The value is the page number. If this is a float +% type, we have more work to do. +% +\def\xrdef#1#2{% + {% Expand the node or anchor name to remove control sequences. + % \turnoffactive stops 8-bit characters being changed to commands + % like @'e. \refx does the same to retrieve the value in the definition. + \indexnofonts + \turnoffactive + \def\value##1{##1}% + \xdef\safexrefname{#1}% + }% + % + \bgroup + \expandafter\gdef\csname XR\safexrefname\endcsname{#2}% + \egroup + % We put the \gdef inside a group to avoid the definitions building up on + % TeX's save stack, which can cause it to run out of space for aux files with + % thousands of lines. \gdef doesn't use the save stack, but \csname does + % when it defines an unknown control sequence as \relax. + % + % Was that xref control sequence that we just defined for a float? + \expandafter\iffloat\csname XR\safexrefname\endcsname + % it was a float, and we have the (safe) float type in \iffloattype. + \expandafter\let\expandafter\floatlist + \csname floatlist\iffloattype\endcsname + % + % Is this the first time we've seen this float type? + \expandafter\ifx\floatlist\relax + \toks0 = {\do}% yes, so just \do + \else + % had it before, so preserve previous elements in list. + \toks0 = \expandafter{\floatlist\do}% + \fi + % + % Remember this xref in the control sequence \floatlistFLOATTYPE, + % for later use in \listoffloats. + \expandafter\xdef\csname floatlist\iffloattype\endcsname{\the\toks0 + {\safexrefname}}% + \fi +} + +% If working on a large document in chapters, it is convenient to +% be able to disable indexing, cross-referencing, and contents, for test runs. +% This is done with @novalidate at the beginning of the file. +% +\newif\iflinks \linkstrue % by default we want the aux files. +\let\novalidate = \linksfalse + +% Used when writing to the aux file, or when using data from it. +\def\requireauxfile{% + \iflinks + \tryauxfile + % Open the new aux file. TeX will close it automatically at exit. + \immediate\openout\auxfile=\jobname.aux + \fi + \global\let\requireauxfile=\relax % Only do this once. +} + +% Read the last existing aux file, if any. No error if none exists. +% +\def\tryauxfile{% + \openin 1 \jobname.aux + \ifeof 1 \else + \readdatafile{aux}% + \global\havexrefstrue + \fi + \closein 1 +} + +\def\setupdatafile{% + \catcode`\^^@=\other + \catcode`\^^A=\other + \catcode`\^^B=\other + \catcode`\^^C=\other + \catcode`\^^D=\other + \catcode`\^^E=\other + \catcode`\^^F=\other + \catcode`\^^G=\other + \catcode`\^^H=\other + \catcode`\^^K=\other + \catcode`\^^L=\other + \catcode`\^^N=\other + \catcode`\^^P=\other + \catcode`\^^Q=\other + \catcode`\^^R=\other + \catcode`\^^S=\other + \catcode`\^^T=\other + \catcode`\^^U=\other + \catcode`\^^V=\other + \catcode`\^^W=\other + \catcode`\^^X=\other + \catcode`\^^Z=\other + \catcode`\^^[=\other + \catcode`\^^\=\other + \catcode`\^^]=\other + \catcode`\^^^=\other + \catcode`\^^_=\other + % It was suggested to set the catcode of ^ to 7, which would allow ^^e4 etc. + % in xref tags, i.e., node names. But since ^^e4 notation isn't + % supported in the main text, it doesn't seem desirable. Furthermore, + % that is not enough: for node names that actually contain a ^ + % character, we would end up writing a line like this: 'xrdef {'hat + % b-title}{'hat b} and \xrdef does a \csname...\endcsname on the first + % argument, and \hat is not an expandable control sequence. It could + % all be worked out, but why? Either we support ^^ or we don't. + % + % The other change necessary for this was to define \auxhat: + % \def\auxhat{\def^{'hat }}% extra space so ok if followed by letter + % and then to call \auxhat in \setq. + % + \catcode`\^=\other + % + % Special characters. Should be turned off anyway, but... + \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 % avoid \+ for paranoia even though we've turned it off + % + % This is to support \ in node names and titles, since the \ + % characters end up in a \csname. It's easier than + % leaving it active and making its active definition an actual \ + % character. What I don't understand is why it works in the *value* + % of the xrdef. Seems like it should be a catcode12 \, and that + % should not typeset properly. But it works, so I'm moving on for + % now. --karl, 15jan04. + \catcode`\\=\other + % + % @ is our escape character in .aux files, and we need braces. + \catcode`\{=1 + \catcode`\}=2 + \catcode`\@=0 +} + +\def\readdatafile#1{% +\begingroup + \setupdatafile + \input\jobname.#1 +\endgroup} + + +\message{insertions,} +% including 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. (Generally, numeric constants should always be followed by a +% space to prevent strange expansion errors.) +\def\supereject{\par\penalty -20000\footnoteno =0 } + +% @footnotestyle is meaningful for Info output only. +\let\footnotestyle=\comment + +{\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}\ptexslash\fi + % + % Remove inadvertent blank space before typesetting the footnote number. + \unskip + \thisfootno\@sf + \dofootnote +}% + +% 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. +% +% Oh yes, they do; otherwise, @ifset (and anything else that uses +% \parseargline) fails inside footnotes because the tokens are fixed when +% the footnote is read. --karl, 16nov96. +% +\gdef\dofootnote{% + \insert\footins\bgroup + % + % Nested footnotes are not supported in TeX, that would take a lot + % more work. (\startsavinginserts does not suffice.) + \let\footnote=\errfootnotenest + % + % 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. + \hsize=\txipagewidth + \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 + % + \smallfonts \rm + % + % Because we use hanging indentation in footnotes, a @noindent appears + % to exdent this text, so make it be a no-op. makeinfo does not use + % hanging indentation so @noindent can still be needed within footnote + % text after an @example or the like (not that this is good style). + \let\noindent = \relax + % + % Hang the footnote text off the number. Use \everypar in case the + % footnote extends for more than one paragraph. + \everypar = {\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 + % + % Invoke rest of plain TeX footnote routine. + \futurelet\next\fo@t +} +}%end \catcode `\@=11 + +\def\errfootnotenest{% + \errhelp=\EMsimple + \errmessage{Nested footnotes not supported in texinfo.tex, + even though they work in makeinfo; sorry} +} + +\def\errfootnoteheading{% + \errhelp=\EMsimple + \errmessage{Footnotes in chapters, sections, etc., are not supported} +} + +% In case a @footnote appears in a vbox, save the footnote text and create +% the real \insert just after the vbox finished. Otherwise, the insertion +% would be lost. +% Similarly, if a @footnote appears inside an alignment, save the footnote +% text to a box and make the \insert when a row of the table is finished. +% And the same can be done for other insert classes. --kasal, 16nov03. +% +% Replace the \insert primitive by a cheating macro. +% Deeper inside, just make sure that the saved insertions are not spilled +% out prematurely. +% +\def\startsavinginserts{% + \ifx \insert\ptexinsert + \let\insert\saveinsert + \else + \let\checkinserts\relax + \fi +} + +% This \insert replacement works for both \insert\footins{foo} and +% \insert\footins\bgroup foo\egroup, but it doesn't work for \insert27{foo}. +% +\def\saveinsert#1{% + \edef\next{\noexpand\savetobox \makeSAVEname#1}% + \afterassignment\next + % swallow the left brace + \let\temp = +} +\def\makeSAVEname#1{\makecsname{SAVE\expandafter\gobble\string#1}} +\def\savetobox#1{\global\setbox#1 = \vbox\bgroup \unvbox#1} + +\def\checksaveins#1{\ifvoid#1\else \placesaveins#1\fi} + +\def\placesaveins#1{% + \ptexinsert \csname\expandafter\gobblesave\string#1\endcsname + {\box#1}% +} + +% eat @SAVE -- beware, all of them have catcode \other: +{ + \def\dospecials{\do S\do A\do V\do E} \uncatcodespecials % ;-) + \gdef\gobblesave @SAVE{} +} + +% initialization: +\def\newsaveins #1{% + \edef\next{\noexpand\newsaveinsX \makeSAVEname#1}% + \next +} +\def\newsaveinsX #1{% + \csname newbox\endcsname #1% + \expandafter\def\expandafter\checkinserts\expandafter{\checkinserts + \checksaveins #1}% +} + +% initialize: +\let\checkinserts\empty +\newsaveins\footins +\newsaveins\margin + + +% @image. We use the macros from epsf.tex to support this. +% If epsf.tex is not installed and @image is used, we complain. +% +% Check for and read epsf.tex up front. If we read it only at @image +% time, we might be inside a group, and then its definitions would get +% undone and the next image would fail. +\openin 1 = epsf.tex +\ifeof 1 \else + % Do not bother showing banner with epsf.tex v2.7k (available in + % doc/epsf.tex and on ctan). + \def\epsfannounce{\toks0 = }% + \input epsf.tex +\fi +\closein 1 +% +% We will only complain once about lack of epsf.tex. +\newif\ifwarnednoepsf +\newhelp\noepsfhelp{epsf.tex must be installed for images to + work. It is also included in the Texinfo distribution, or you can get + it from https://ctan.org/texarchive/macros/texinfo/texinfo/doc/epsf.tex.} +% +\def\image#1{% + \ifx\epsfbox\thisisundefined + \ifwarnednoepsf \else + \errhelp = \noepsfhelp + \errmessage{epsf.tex not found, images will be ignored}% + \global\warnednoepsftrue + \fi + \else + \imagexxx #1,,,,,\finish + \fi +} +% +% Arguments to @image: +% #1 is (mandatory) image filename; we tack on .eps extension. +% #2 is (optional) width, #3 is (optional) height. +% #4 is (ignored optional) html alt text. +% #5 is (ignored optional) extension. +% #6 is just the usual extra ignored arg for parsing stuff. +\newif\ifimagevmode +\def\imagexxx#1,#2,#3,#4,#5,#6\finish{\begingroup + \catcode`\^^M = 5 % in case we're inside an example + \normalturnoffactive % allow _ et al. in names + \def\xprocessmacroarg{\eatspaces}% in case we are being used via a macro + % If the image is by itself, center it. + \ifvmode + \imagevmodetrue + \else \ifx\centersub\centerV + % for @center @image, we need a vbox so we can have our vertical space + \imagevmodetrue + \vbox\bgroup % vbox has better behavior than vtop herev + \fi\fi + % + \ifimagevmode + \nobreak\medskip + % Usually we'll have text after the image which will insert + % \parskip glue, so insert it here too to equalize the space + % above and below. + \nobreak\vskip\parskip + \nobreak + \fi + % + % Leave vertical mode so that indentation from an enclosing + % environment such as @quotation is respected. + % However, if we're at the top level, we don't want the + % normal paragraph indentation. + % On the other hand, if we are in the case of @center @image, we don't + % want to start a paragraph, which will create a hsize-width box and + % eradicate the centering. + \ifx\centersub\centerV\else \noindent \fi + % + % Output the image. + \ifpdf + % For pdfTeX and LuaTeX <= 0.80 + \dopdfimage{#1}{#2}{#3}% + \else + \ifx\XeTeXrevision\thisisundefined + % For epsf.tex + % \epsfbox itself resets \epsf?size at each figure. + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0 > 0pt \epsfxsize=#2\relax \fi + \setbox0 = \hbox{\ignorespaces #3}% + \ifdim\wd0 > 0pt \epsfysize=#3\relax \fi + \epsfbox{#1.eps}% + \else + % For XeTeX + \doxeteximage{#1}{#2}{#3}% + \fi + \fi + % + \ifimagevmode + \medskip % space after a standalone image + \fi + \ifx\centersub\centerV \egroup \fi +\endgroup} + + +% @float FLOATTYPE,LABEL,LOC ... @end float for displayed figures, tables, +% etc. We don't actually implement floating yet, we always include the +% float "here". But it seemed the best name for the future. +% +\envparseargdef\float{\eatcommaspace\eatcommaspace\dofloat#1, , ,\finish} + +% There may be a space before second and/or third parameter; delete it. +\def\eatcommaspace#1, {#1,} + +% #1 is the optional FLOATTYPE, the text label for this float, typically +% "Figure", "Table", "Example", etc. Can't contain commas. If omitted, +% this float will not be numbered and cannot be referred to. +% +% #2 is the optional xref label. Also must be present for the float to +% be referable. +% +% #3 is the optional positioning argument; for now, it is ignored. It +% will somehow specify the positions allowed to float to (here, top, bottom). +% +% We keep a separate counter for each FLOATTYPE, which we reset at each +% chapter-level command. +\let\resetallfloatnos=\empty +% +\def\dofloat#1,#2,#3,#4\finish{% + \let\thiscaption=\empty + \let\thisshortcaption=\empty + % + % don't lose footnotes inside @float. + % + % BEWARE: when the floats start float, we have to issue warning whenever an + % insert appears inside a float which could possibly float. --kasal, 26may04 + % + \startsavinginserts + % + % We can't be used inside a paragraph. + \par + % + \vtop\bgroup + \def\floattype{#1}% + \def\floatlabel{#2}% + \def\floatloc{#3}% we do nothing with this yet. + % + \ifx\floattype\empty + \let\safefloattype=\empty + \else + {% + % the floattype might have accents or other special characters, + % but we need to use it in a control sequence name. + \indexnofonts + \turnoffactive + \xdef\safefloattype{\floattype}% + }% + \fi + % + % If label is given but no type, we handle that as the empty type. + \ifx\floatlabel\empty \else + % We want each FLOATTYPE to be numbered separately (Figure 1, + % Table 1, Figure 2, ...). (And if no label, no number.) + % + \expandafter\getfloatno\csname\safefloattype floatno\endcsname + \global\advance\floatno by 1 + % + {% + % This magic value for \lastsection is output by \setref as the + % XREFLABEL-title value. \xrefX uses it to distinguish float + % labels (which have a completely different output format) from + % node and anchor labels. And \xrdef uses it to construct the + % lists of floats. + % + \edef\lastsection{\floatmagic=\safefloattype}% + \setref{\floatlabel}{Yfloat}% + }% + \fi + % + % start with \parskip glue, I guess. + \vskip\parskip + % + % Don't suppress indentation if a float happens to start a section. + \restorefirstparagraphindent +} + +% we have these possibilities: +% @float Foo,lbl & @caption{Cap}: Foo 1.1: Cap +% @float Foo,lbl & no caption: Foo 1.1 +% @float Foo & @caption{Cap}: Foo: Cap +% @float Foo & no caption: Foo +% @float ,lbl & Caption{Cap}: 1.1: Cap +% @float ,lbl & no caption: 1.1 +% @float & @caption{Cap}: Cap +% @float & no caption: +% +\def\Efloat{% + \let\floatident = \empty + % + % In all cases, if we have a float type, it comes first. + \ifx\floattype\empty \else \def\floatident{\floattype}\fi + % + % If we have an xref label, the number comes next. + \ifx\floatlabel\empty \else + \ifx\floattype\empty \else % if also had float type, need tie first. + \appendtomacro\floatident{\tie}% + \fi + % the number. + \appendtomacro\floatident{\chaplevelprefix\the\floatno}% + \fi + % + % Start the printed caption with what we've constructed in + % \floatident, but keep it separate; we need \floatident again. + \let\captionline = \floatident + % + \ifx\thiscaption\empty \else + \ifx\floatident\empty \else + \appendtomacro\captionline{: }% had ident, so need a colon between + \fi + % + % caption text. + \appendtomacro\captionline{\scanexp\thiscaption}% + \fi + % + % If we have anything to print, print it, with space before. + % Eventually this needs to become an \insert. + \ifx\captionline\empty \else + \vskip.5\parskip + \captionline + % + % Space below caption. + \vskip\parskip + \fi + % + % If have an xref label, write the list of floats info. Do this + % after the caption, to avoid chance of it being a breakpoint. + \ifx\floatlabel\empty \else + % Write the text that goes in the lof to the aux file as + % \floatlabel-lof. Besides \floatident, we include the short + % caption if specified, else the full caption if specified, else nothing. + {% + \requireauxfile + \atdummies + % + \ifx\thisshortcaption\empty + \def\gtemp{\thiscaption}% + \else + \def\gtemp{\thisshortcaption}% + \fi + \immediate\write\auxfile{@xrdef{\floatlabel-lof}{\floatident + \ifx\gtemp\empty \else : \gtemp \fi}}% + }% + \fi + \egroup % end of \vtop + % + \checkinserts +} + +% Append the tokens #2 to the definition of macro #1, not expanding either. +% +\def\appendtomacro#1#2{% + \expandafter\def\expandafter#1\expandafter{#1#2}% +} + +% @caption, @shortcaption +% +\def\caption{\docaption\thiscaption} +\def\shortcaption{\docaption\thisshortcaption} +\def\docaption{\checkenv\float \bgroup\scanargctxt\defcaption} +\def\defcaption#1#2{\egroup \def#1{#2}} + +% The parameter is the control sequence identifying the counter we are +% going to use. Create it if it doesn't exist and assign it to \floatno. +\def\getfloatno#1{% + \ifx#1\relax + % Haven't seen this figure type before. + \csname newcount\endcsname #1% + % + % Remember to reset this floatno at the next chap. + \expandafter\gdef\expandafter\resetallfloatnos + \expandafter{\resetallfloatnos #1=0 }% + \fi + \let\floatno#1% +} + +% \setref calls this to get the XREFLABEL-snt value. We want an @xref +% to the FLOATLABEL to expand to "Figure 3.1". We call \setref when we +% first read the @float command. +% +\def\Yfloat{\floattype@tie \chaplevelprefix\the\floatno}% + +% Magic string used for the XREFLABEL-title value, so \xrefX can +% distinguish floats from other xref types. +\def\floatmagic{!!float!!} + +% #1 is the control sequence we are passed; we expand into a conditional +% which is true if #1 represents a float ref. That is, the magic +% \lastsection value which we \setref above. +% +\def\iffloat#1{\expandafter\doiffloat#1==\finish} +% +% #1 is (maybe) the \floatmagic string. If so, #2 will be the +% (safe) float type for this float. We set \iffloattype to #2. +% +\def\doiffloat#1=#2=#3\finish{% + \def\temp{#1}% + \def\iffloattype{#2}% + \ifx\temp\floatmagic +} + +% @listoffloats FLOATTYPE - print a list of floats like a table of contents. +% +\parseargdef\listoffloats{% + \def\floattype{#1}% floattype + {% + % the floattype might have accents or other special characters, + % but we need to use it in a control sequence name. + \indexnofonts + \turnoffactive + \xdef\safefloattype{\floattype}% + }% + % + % \xrdef saves the floats as a \do-list in \floatlistSAFEFLOATTYPE. + \expandafter\ifx\csname floatlist\safefloattype\endcsname \relax + \ifhavexrefs + % if the user said @listoffloats foo but never @float foo. + \message{\linenumber No `\safefloattype' floats to list.}% + \fi + \else + \begingroup + \leftskip=\tocindent % indent these entries like a toc + \let\do=\listoffloatsdo + \csname floatlist\safefloattype\endcsname + \endgroup + \fi +} + +% This is called on each entry in a list of floats. We're passed the +% xref label, in the form LABEL-title, which is how we save it in the +% aux file. We strip off the -title and look up \XRLABEL-lof, which +% has the text we're supposed to typeset here. +% +% Figures without xref labels will not be included in the list (since +% they won't appear in the aux file). +% +\def\listoffloatsdo#1{\listoffloatsdoentry#1\finish} +\def\listoffloatsdoentry#1-title\finish{{% + % Can't fully expand XR#1-lof because it can contain anything. Just + % pass the control sequence. On the other hand, XR#1-pg is just the + % page number, and we want to fully expand that so we can get a link + % in pdf output. + \toksA = \expandafter{\csname XR#1-lof\endcsname}% + % + % use the same \entry macro we use to generate the TOC and index. + \edef\writeentry{\noexpand\entry{\the\toksA}{\csname XR#1-pg\endcsname}}% + \writeentry +}} + + +\message{localization,} + +% For single-language documents, @documentlanguage is usually given very +% early, just after @documentencoding. Single argument is the language +% (de) or locale (de_DE) abbreviation. +% +{ + \catcode`\_ = \active + \globaldefs=1 +\parseargdef\documentlanguage{% + \tex % read txi-??.tex file in plain TeX. + % Read the file by the name they passed if it exists. + \let_ = \normalunderscore % normal _ character for filename test + \openin 1 txi-#1.tex + \ifeof 1 + \documentlanguagetrywithoutunderscore #1_\finish + \else + \globaldefs = 1 % everything in the txi-LL files needs to persist + \input txi-#1.tex + \fi + \closein 1 + \endgroup % end raw TeX +} +% +% If they passed de_DE, and txi-de_DE.tex doesn't exist, +% try txi-de.tex. +% +\gdef\documentlanguagetrywithoutunderscore#1_#2\finish{% + \openin 1 txi-#1.tex + \ifeof 1 + \errhelp = \nolanghelp + \errmessage{Cannot read language file txi-#1.tex}% + \else + \globaldefs = 1 % everything in the txi-LL files needs to persist + \input txi-#1.tex + \fi + \closein 1 +} +}% end of special _ catcode +% +\newhelp\nolanghelp{The given language definition file cannot be found or +is empty. Maybe you need to install it? Putting it in the current +directory should work if nowhere else does.} + +% This macro is called from txi-??.tex files; the first argument is the +% \language name to set (without the "\lang@" prefix), the second and +% third args are \{left,right}hyphenmin. +% +% The language names to pass are determined when the format is built. +% See the etex.log file created at that time, e.g., +% /usr/local/texlive/2008/texmf-var/web2c/pdftex/etex.log. +% +% With TeX Live 2008, etex now includes hyphenation patterns for all +% available languages. This means we can support hyphenation in +% Texinfo, at least to some extent. (This still doesn't solve the +% accented characters problem.) +% +\catcode`@=11 +\def\txisetlanguage#1#2#3{% + % do not set the language if the name is undefined in the current TeX. + \expandafter\ifx\csname lang@#1\endcsname \relax + \message{no patterns for #1}% + \else + \global\language = \csname lang@#1\endcsname + \fi + % but there is no harm in adjusting the hyphenmin values regardless. + \global\lefthyphenmin = #2\relax + \global\righthyphenmin = #3\relax +} + +% XeTeX and LuaTeX can handle Unicode natively. +% Their default I/O uses UTF-8 sequences instead of a byte-wise operation. +% Other TeX engines' I/O (pdfTeX, etc.) is byte-wise. +% +\newif\iftxinativeunicodecapable +\newif\iftxiusebytewiseio + +\ifx\XeTeXrevision\thisisundefined + \ifx\luatexversion\thisisundefined + \txinativeunicodecapablefalse + \txiusebytewiseiotrue + \else + \txinativeunicodecapabletrue + \txiusebytewiseiofalse + \fi +\else + \txinativeunicodecapabletrue + \txiusebytewiseiofalse +\fi + +% Set I/O by bytes instead of UTF-8 sequence for XeTeX and LuaTex +% for non-UTF-8 (byte-wise) encodings. +% +\def\setbytewiseio{% + \ifx\XeTeXrevision\thisisundefined + \else + \XeTeXdefaultencoding "bytes" % For subsequent files to be read + \XeTeXinputencoding "bytes" % For document root file + % Unfortunately, there seems to be no corresponding XeTeX command for + % output encoding. This is a problem for auxiliary index and TOC files. + % The only solution would be perhaps to write out @U{...} sequences in + % place of non-ASCII characters. + \fi + + \ifx\luatexversion\thisisundefined + \else + \directlua{ + local utf8_char, byte, gsub = unicode.utf8.char, string.byte, string.gsub + local function convert_char (char) + return utf8_char(byte(char)) + end + + local function convert_line (line) + return gsub(line, ".", convert_char) + end + + callback.register("process_input_buffer", convert_line) + + local function convert_line_out (line) + local line_out = "" + for c in string.utfvalues(line) do + line_out = line_out .. string.char(c) + end + return line_out + end + + callback.register("process_output_buffer", convert_line_out) + } + \fi + + \txiusebytewiseiotrue +} + + +% Helpers for encodings. +% Set the catcode of characters 128 through 255 to the specified number. +% +\def\setnonasciicharscatcode#1{% + \count255=128 + \loop\ifnum\count255<256 + \global\catcode\count255=#1\relax + \advance\count255 by 1 + \repeat +} + +\def\setnonasciicharscatcodenonglobal#1{% + \count255=128 + \loop\ifnum\count255<256 + \catcode\count255=#1\relax + \advance\count255 by 1 + \repeat +} + +% @documentencoding sets the definition of non-ASCII characters +% according to the specified encoding. +% +\def\documentencoding{\parseargusing\filenamecatcodes\documentencodingzzz} +\def\documentencodingzzz#1{% + % + % Encoding being declared for the document. + \def\declaredencoding{\csname #1.enc\endcsname}% + % + % Supported encodings: names converted to tokens in order to be able + % to compare them with \ifx. + \def\ascii{\csname US-ASCII.enc\endcsname}% + \def\latnine{\csname ISO-8859-15.enc\endcsname}% + \def\latone{\csname ISO-8859-1.enc\endcsname}% + \def\lattwo{\csname ISO-8859-2.enc\endcsname}% + \def\utfeight{\csname UTF-8.enc\endcsname}% + % + \ifx \declaredencoding \ascii + \asciichardefs + % + \else \ifx \declaredencoding \lattwo + \iftxinativeunicodecapable + \setbytewiseio + \fi + \setnonasciicharscatcode\active + \lattwochardefs + % + \else \ifx \declaredencoding \latone + \iftxinativeunicodecapable + \setbytewiseio + \fi + \setnonasciicharscatcode\active + \latonechardefs + % + \else \ifx \declaredencoding \latnine + \iftxinativeunicodecapable + \setbytewiseio + \fi + \setnonasciicharscatcode\active + \latninechardefs + % + \else \ifx \declaredencoding \utfeight + \iftxinativeunicodecapable + % For native Unicode handling (XeTeX and LuaTeX) + \nativeunicodechardefs + \else + % For treating UTF-8 as byte sequences (TeX, eTeX and pdfTeX) + \setnonasciicharscatcode\active + % since we already invoked \utfeightchardefs at the top level + % (below), do not re-invoke it, otherwise our check for duplicated + % definitions gets triggered. Making non-ascii chars active is + % sufficient. + \fi + % + \else + \message{Ignoring unknown document encoding: #1.}% + % + \fi % utfeight + \fi % latnine + \fi % latone + \fi % lattwo + \fi % ascii + % + \ifx\XeTeXrevision\thisisundefined + \else + \ifx \declaredencoding \utfeight + \else + \ifx \declaredencoding \ascii + \else + \message{Warning: XeTeX with non-UTF-8 encodings cannot handle % + non-ASCII characters in auxiliary files.}% + \fi + \fi + \fi +} + +% emacs-page +% A message to be logged when using a character that isn't available +% the default font encoding (OT1). +% +\def\missingcharmsg#1{\message{Character missing, sorry: #1.}} + +% Take account of \c (plain) vs. \, (Texinfo) difference. +\def\cedilla#1{\ifx\c\ptexc\c{#1}\else\,{#1}\fi} + +% First, make active non-ASCII characters in order for them to be +% correctly categorized when TeX reads the replacement text of +% macros containing the character definitions. +\setnonasciicharscatcode\active +% + +\def\gdefchar#1#2{% +\gdef#1{% + \ifpassthroughchars + \string#1% + \else + #2% + \fi +}} + +% Latin1 (ISO-8859-1) character definitions. +\def\latonechardefs{% + \gdefchar^^a0{\tie} + \gdefchar^^a1{\exclamdown} + \gdefchar^^a2{{\tcfont \char162}} % cent + \gdefchar^^a3{\pounds{}} + \gdefchar^^a4{{\tcfont \char164}} % currency + \gdefchar^^a5{{\tcfont \char165}} % yen + \gdefchar^^a6{{\tcfont \char166}} % broken bar + \gdefchar^^a7{\S} + \gdefchar^^a8{\"{}} + \gdefchar^^a9{\copyright{}} + \gdefchar^^aa{\ordf} + \gdefchar^^ab{\guillemetleft{}} + \gdefchar^^ac{\ensuremath\lnot} + \gdefchar^^ad{\-} + \gdefchar^^ae{\registeredsymbol{}} + \gdefchar^^af{\={}} + % + \gdefchar^^b0{\textdegree} + \gdefchar^^b1{$\pm$} + \gdefchar^^b2{$^2$} + \gdefchar^^b3{$^3$} + \gdefchar^^b4{\'{}} + \gdefchar^^b5{$\mu$} + \gdefchar^^b6{\P} + \gdefchar^^b7{\ensuremath\cdot} + \gdefchar^^b8{\cedilla\ } + \gdefchar^^b9{$^1$} + \gdefchar^^ba{\ordm} + \gdefchar^^bb{\guillemetright{}} + \gdefchar^^bc{$1\over4$} + \gdefchar^^bd{$1\over2$} + \gdefchar^^be{$3\over4$} + \gdefchar^^bf{\questiondown} + % + \gdefchar^^c0{\`A} + \gdefchar^^c1{\'A} + \gdefchar^^c2{\^A} + \gdefchar^^c3{\~A} + \gdefchar^^c4{\"A} + \gdefchar^^c5{\ringaccent A} + \gdefchar^^c6{\AE} + \gdefchar^^c7{\cedilla C} + \gdefchar^^c8{\`E} + \gdefchar^^c9{\'E} + \gdefchar^^ca{\^E} + \gdefchar^^cb{\"E} + \gdefchar^^cc{\`I} + \gdefchar^^cd{\'I} + \gdefchar^^ce{\^I} + \gdefchar^^cf{\"I} + % + \gdefchar^^d0{\DH} + \gdefchar^^d1{\~N} + \gdefchar^^d2{\`O} + \gdefchar^^d3{\'O} + \gdefchar^^d4{\^O} + \gdefchar^^d5{\~O} + \gdefchar^^d6{\"O} + \gdefchar^^d7{$\times$} + \gdefchar^^d8{\O} + \gdefchar^^d9{\`U} + \gdefchar^^da{\'U} + \gdefchar^^db{\^U} + \gdefchar^^dc{\"U} + \gdefchar^^dd{\'Y} + \gdefchar^^de{\TH} + \gdefchar^^df{\ss} + % + \gdefchar^^e0{\`a} + \gdefchar^^e1{\'a} + \gdefchar^^e2{\^a} + \gdefchar^^e3{\~a} + \gdefchar^^e4{\"a} + \gdefchar^^e5{\ringaccent a} + \gdefchar^^e6{\ae} + \gdefchar^^e7{\cedilla c} + \gdefchar^^e8{\`e} + \gdefchar^^e9{\'e} + \gdefchar^^ea{\^e} + \gdefchar^^eb{\"e} + \gdefchar^^ec{\`{\dotless i}} + \gdefchar^^ed{\'{\dotless i}} + \gdefchar^^ee{\^{\dotless i}} + \gdefchar^^ef{\"{\dotless i}} + % + \gdefchar^^f0{\dh} + \gdefchar^^f1{\~n} + \gdefchar^^f2{\`o} + \gdefchar^^f3{\'o} + \gdefchar^^f4{\^o} + \gdefchar^^f5{\~o} + \gdefchar^^f6{\"o} + \gdefchar^^f7{$\div$} + \gdefchar^^f8{\o} + \gdefchar^^f9{\`u} + \gdefchar^^fa{\'u} + \gdefchar^^fb{\^u} + \gdefchar^^fc{\"u} + \gdefchar^^fd{\'y} + \gdefchar^^fe{\th} + \gdefchar^^ff{\"y} +} + +% Latin9 (ISO-8859-15) encoding character definitions. +\def\latninechardefs{% + % Encoding is almost identical to Latin1. + \latonechardefs + % + \gdefchar^^a4{\euro{}} + \gdefchar^^a6{\v S} + \gdefchar^^a8{\v s} + \gdefchar^^b4{\v Z} + \gdefchar^^b8{\v z} + \gdefchar^^bc{\OE} + \gdefchar^^bd{\oe} + \gdefchar^^be{\"Y} +} + +% Latin2 (ISO-8859-2) character definitions. +\def\lattwochardefs{% + \gdefchar^^a0{\tie} + \gdefchar^^a1{\ogonek{A}} + \gdefchar^^a2{\u{}} + \gdefchar^^a3{\L} + \gdefchar^^a4{\missingcharmsg{CURRENCY SIGN}} + \gdefchar^^a5{\v L} + \gdefchar^^a6{\'S} + \gdefchar^^a7{\S} + \gdefchar^^a8{\"{}} + \gdefchar^^a9{\v S} + \gdefchar^^aa{\cedilla S} + \gdefchar^^ab{\v T} + \gdefchar^^ac{\'Z} + \gdefchar^^ad{\-} + \gdefchar^^ae{\v Z} + \gdefchar^^af{\dotaccent Z} + % + \gdefchar^^b0{\textdegree{}} + \gdefchar^^b1{\ogonek{a}} + \gdefchar^^b2{\ogonek{ }} + \gdefchar^^b3{\l} + \gdefchar^^b4{\'{}} + \gdefchar^^b5{\v l} + \gdefchar^^b6{\'s} + \gdefchar^^b7{\v{}} + \gdefchar^^b8{\cedilla\ } + \gdefchar^^b9{\v s} + \gdefchar^^ba{\cedilla s} + \gdefchar^^bb{\v t} + \gdefchar^^bc{\'z} + \gdefchar^^bd{\H{}} + \gdefchar^^be{\v z} + \gdefchar^^bf{\dotaccent z} + % + \gdefchar^^c0{\'R} + \gdefchar^^c1{\'A} + \gdefchar^^c2{\^A} + \gdefchar^^c3{\u A} + \gdefchar^^c4{\"A} + \gdefchar^^c5{\'L} + \gdefchar^^c6{\'C} + \gdefchar^^c7{\cedilla C} + \gdefchar^^c8{\v C} + \gdefchar^^c9{\'E} + \gdefchar^^ca{\ogonek{E}} + \gdefchar^^cb{\"E} + \gdefchar^^cc{\v E} + \gdefchar^^cd{\'I} + \gdefchar^^ce{\^I} + \gdefchar^^cf{\v D} + % + \gdefchar^^d0{\DH} + \gdefchar^^d1{\'N} + \gdefchar^^d2{\v N} + \gdefchar^^d3{\'O} + \gdefchar^^d4{\^O} + \gdefchar^^d5{\H O} + \gdefchar^^d6{\"O} + \gdefchar^^d7{$\times$} + \gdefchar^^d8{\v R} + \gdefchar^^d9{\ringaccent U} + \gdefchar^^da{\'U} + \gdefchar^^db{\H U} + \gdefchar^^dc{\"U} + \gdefchar^^dd{\'Y} + \gdefchar^^de{\cedilla T} + \gdefchar^^df{\ss} + % + \gdefchar^^e0{\'r} + \gdefchar^^e1{\'a} + \gdefchar^^e2{\^a} + \gdefchar^^e3{\u a} + \gdefchar^^e4{\"a} + \gdefchar^^e5{\'l} + \gdefchar^^e6{\'c} + \gdefchar^^e7{\cedilla c} + \gdefchar^^e8{\v c} + \gdefchar^^e9{\'e} + \gdefchar^^ea{\ogonek{e}} + \gdefchar^^eb{\"e} + \gdefchar^^ec{\v e} + \gdefchar^^ed{\'{\dotless{i}}} + \gdefchar^^ee{\^{\dotless{i}}} + \gdefchar^^ef{\v d} + % + \gdefchar^^f0{\dh} + \gdefchar^^f1{\'n} + \gdefchar^^f2{\v n} + \gdefchar^^f3{\'o} + \gdefchar^^f4{\^o} + \gdefchar^^f5{\H o} + \gdefchar^^f6{\"o} + \gdefchar^^f7{$\div$} + \gdefchar^^f8{\v r} + \gdefchar^^f9{\ringaccent u} + \gdefchar^^fa{\'u} + \gdefchar^^fb{\H u} + \gdefchar^^fc{\"u} + \gdefchar^^fd{\'y} + \gdefchar^^fe{\cedilla t} + \gdefchar^^ff{\dotaccent{}} +} + +% UTF-8 character definitions. +% +% This code to support UTF-8 is based on LaTeX's utf8.def, with some +% changes for Texinfo conventions. It is included here under the GPL by +% permission from Frank Mittelbach and the LaTeX team. +% +\newcount\countUTFx +\newcount\countUTFy +\newcount\countUTFz + +\gdef\UTFviiiTwoOctets#1#2{\expandafter + \UTFviiiDefined\csname u8:#1\string #2\endcsname} +% +\gdef\UTFviiiThreeOctets#1#2#3{\expandafter + \UTFviiiDefined\csname u8:#1\string #2\string #3\endcsname} +% +\gdef\UTFviiiFourOctets#1#2#3#4{\expandafter + \UTFviiiDefined\csname u8:#1\string #2\string #3\string #4\endcsname} + +\gdef\UTFviiiDefined#1{% + \ifx #1\relax + \message{\linenumber Unicode char \string #1 not defined for Texinfo}% + \else + \expandafter #1% + \fi +} + +% Give non-ASCII bytes the active definitions for processing UTF-8 sequences +\begingroup + \catcode`\~13 + \catcode`\$12 + \catcode`\"12 + + % Loop from \countUTFx to \countUTFy, performing \UTFviiiTmp + % substituting ~ and $ with a character token of that value. + \def\UTFviiiLoop{% + \global\catcode\countUTFx\active + \uccode`\~\countUTFx + \uccode`\$\countUTFx + \uppercase\expandafter{\UTFviiiTmp}% + \advance\countUTFx by 1 + \ifnum\countUTFx < \countUTFy + \expandafter\UTFviiiLoop + \fi} + + % For bytes other than the first in a UTF-8 sequence. Not expected to + % be expanded except when writing to auxiliary files. + \countUTFx = "80 + \countUTFy = "C2 + \def\UTFviiiTmp{% + \gdef~{% + \ifpassthroughchars $\fi}}% + \UTFviiiLoop + + \countUTFx = "C2 + \countUTFy = "E0 + \def\UTFviiiTmp{% + \gdef~{% + \ifpassthroughchars $% + \else\expandafter\UTFviiiTwoOctets\expandafter$\fi}}% + \UTFviiiLoop + + \countUTFx = "E0 + \countUTFy = "F0 + \def\UTFviiiTmp{% + \gdef~{% + \ifpassthroughchars $% + \else\expandafter\UTFviiiThreeOctets\expandafter$\fi}}% + \UTFviiiLoop + + \countUTFx = "F0 + \countUTFy = "F4 + \def\UTFviiiTmp{% + \gdef~{% + \ifpassthroughchars $% + \else\expandafter\UTFviiiFourOctets\expandafter$\fi + }}% + \UTFviiiLoop +\endgroup + +\def\globallet{\global\let} % save some \expandafter's below + +% @U{xxxx} to produce U+xxxx, if we support it. +\def\U#1{% + \expandafter\ifx\csname uni:#1\endcsname \relax + \iftxinativeunicodecapable + % All Unicode characters can be used if native Unicode handling is + % active. However, if the font does not have the glyph, + % letters are missing. + \begingroup + \uccode`\.="#1\relax + \uppercase{.} + \endgroup + \else + \errhelp = \EMsimple + \errmessage{Unicode character U+#1 not supported, sorry}% + \fi + \else + \csname uni:#1\endcsname + \fi +} + +% These macros are used here to construct the name of a control +% sequence to be defined. +\def\UTFviiiTwoOctetsName#1#2{% + \csname u8:#1\string #2\endcsname}% +\def\UTFviiiThreeOctetsName#1#2#3{% + \csname u8:#1\string #2\string #3\endcsname}% +\def\UTFviiiFourOctetsName#1#2#3#4{% + \csname u8:#1\string #2\string #3\string #4\endcsname}% + +% For UTF-8 byte sequences (TeX, e-TeX and pdfTeX), +% provide a definition macro to replace a Unicode character; +% this gets used by the @U command +% +\begingroup + \catcode`\"=12 + \catcode`\<=12 + \catcode`\.=12 + \catcode`\,=12 + \catcode`\;=12 + \catcode`\!=12 + \catcode`\~=13 + \gdef\DeclareUnicodeCharacterUTFviii#1#2{% + \countUTFz = "#1\relax + \begingroup + \parseXMLCharref + + % Give \u8:... its definition. The sequence of seven \expandafter's + % expands after the \gdef three times, e.g. + % + % 1. \UTFviiTwoOctetsName B1 B2 + % 2. \csname u8:B1 \string B2 \endcsname + % 3. \u8: B1 B2 (a single control sequence token) + % + \expandafter\expandafter + \expandafter\expandafter + \expandafter\expandafter + \expandafter\gdef \UTFviiiTmp{#2}% + % + \expandafter\ifx\csname uni:#1\endcsname \relax \else + \message{Internal error, already defined: #1}% + \fi + % + % define an additional control sequence for this code point. + \expandafter\globallet\csname uni:#1\endcsname \UTFviiiTmp + \endgroup} + % + % Given the value in \countUTFz as a Unicode code point, set \UTFviiiTmp + % to the corresponding UTF-8 sequence. + \gdef\parseXMLCharref{% + \ifnum\countUTFz < "A0\relax + \errhelp = \EMsimple + \errmessage{Cannot define Unicode char value < 00A0}% + \else\ifnum\countUTFz < "800\relax + \parseUTFviiiA,% + \parseUTFviiiB C\UTFviiiTwoOctetsName.,% + \else\ifnum\countUTFz < "10000\relax + \parseUTFviiiA;% + \parseUTFviiiA,% + \parseUTFviiiB E\UTFviiiThreeOctetsName.{,;}% + \else + \parseUTFviiiA;% + \parseUTFviiiA,% + \parseUTFviiiA!% + \parseUTFviiiB F\UTFviiiFourOctetsName.{!,;}% + \fi\fi\fi + } + + % Extract a byte from the end of the UTF-8 representation of \countUTFx. + % It must be a non-initial byte in the sequence. + % Change \uccode of #1 for it to be used in \parseUTFviiiB as one + % of the bytes. + \gdef\parseUTFviiiA#1{% + \countUTFx = \countUTFz + \divide\countUTFz by 64 + \countUTFy = \countUTFz % Save to be the future value of \countUTFz. + \multiply\countUTFz by 64 + + % \countUTFz is now \countUTFx with the last 5 bits cleared. Subtract + % in order to get the last five bits. + \advance\countUTFx by -\countUTFz + + % Convert this to the byte in the UTF-8 sequence. + \advance\countUTFx by 128 + \uccode `#1\countUTFx + \countUTFz = \countUTFy} + + % Used to put a UTF-8 byte sequence into \UTFviiiTmp + % #1 is the increment for \countUTFz to yield a the first byte of the UTF-8 + % sequence. + % #2 is one of the \UTFviii*OctetsName macros. + % #3 is always a full stop (.) + % #4 is a template for the other bytes in the sequence. The values for these + % bytes is substituted in here with \uppercase using the \uccode's. + \gdef\parseUTFviiiB#1#2#3#4{% + \advance\countUTFz by "#10\relax + \uccode `#3\countUTFz + \uppercase{\gdef\UTFviiiTmp{#2#3#4}}} +\endgroup + +% For native Unicode handling (XeTeX and LuaTeX), +% provide a definition macro that sets a catcode to `other' non-globally +% +\def\DeclareUnicodeCharacterNativeOther#1#2{% + \catcode"#1=\other +} + +% https://en.wikipedia.org/wiki/Plane_(Unicode)#Basic_M +% U+0000..U+007F = https://en.wikipedia.org/wiki/Basic_Latin_(Unicode_block) +% U+0080..U+00FF = https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block) +% U+0100..U+017F = https://en.wikipedia.org/wiki/Latin_Extended-A +% U+0180..U+024F = https://en.wikipedia.org/wiki/Latin_Extended-B +% +% Many of our renditions are less than wonderful, and all the missing +% characters are available somewhere. Loading the necessary fonts +% awaits user request. We can't truly support Unicode without +% reimplementing everything that's been done in LaTeX for many years, +% plus probably using luatex or xetex, and who knows what else. +% We won't be doing that here in this simple file. But we can try to at +% least make most of the characters not bomb out. +% +\def\unicodechardefs{% + \DeclareUnicodeCharacter{00A0}{\tie}% + \DeclareUnicodeCharacter{00A1}{\exclamdown}% + \DeclareUnicodeCharacter{00A2}{{\tcfont \char162}}% 0242=cent + \DeclareUnicodeCharacter{00A3}{\pounds{}}% + \DeclareUnicodeCharacter{00A4}{{\tcfont \char164}}% 0244=currency + \DeclareUnicodeCharacter{00A5}{{\tcfont \char165}}% 0245=yen + \DeclareUnicodeCharacter{00A6}{{\tcfont \char166}}% 0246=brokenbar + \DeclareUnicodeCharacter{00A7}{\S}% + \DeclareUnicodeCharacter{00A8}{\"{ }}% + \DeclareUnicodeCharacter{00A9}{\copyright{}}% + \DeclareUnicodeCharacter{00AA}{\ordf}% + \DeclareUnicodeCharacter{00AB}{\guillemetleft{}}% + \DeclareUnicodeCharacter{00AC}{\ensuremath\lnot}% + \DeclareUnicodeCharacter{00AD}{\-}% + \DeclareUnicodeCharacter{00AE}{\registeredsymbol{}}% + \DeclareUnicodeCharacter{00AF}{\={ }}% + % + \DeclareUnicodeCharacter{00B0}{\ringaccent{ }}% + \DeclareUnicodeCharacter{00B1}{\ensuremath\pm}% + \DeclareUnicodeCharacter{00B2}{$^2$}% + \DeclareUnicodeCharacter{00B3}{$^3$}% + \DeclareUnicodeCharacter{00B4}{\'{ }}% + \DeclareUnicodeCharacter{00B5}{$\mu$}% + \DeclareUnicodeCharacter{00B6}{\P}% + \DeclareUnicodeCharacter{00B7}{\ensuremath\cdot}% + \DeclareUnicodeCharacter{00B8}{\cedilla{ }}% + \DeclareUnicodeCharacter{00B9}{$^1$}% + \DeclareUnicodeCharacter{00BA}{\ordm}% + \DeclareUnicodeCharacter{00BB}{\guillemetright{}}% + \DeclareUnicodeCharacter{00BC}{$1\over4$}% + \DeclareUnicodeCharacter{00BD}{$1\over2$}% + \DeclareUnicodeCharacter{00BE}{$3\over4$}% + \DeclareUnicodeCharacter{00BF}{\questiondown}% + % + \DeclareUnicodeCharacter{00C0}{\`A}% + \DeclareUnicodeCharacter{00C1}{\'A}% + \DeclareUnicodeCharacter{00C2}{\^A}% + \DeclareUnicodeCharacter{00C3}{\~A}% + \DeclareUnicodeCharacter{00C4}{\"A}% + \DeclareUnicodeCharacter{00C5}{\AA}% + \DeclareUnicodeCharacter{00C6}{\AE}% + \DeclareUnicodeCharacter{00C7}{\cedilla{C}}% + \DeclareUnicodeCharacter{00C8}{\`E}% + \DeclareUnicodeCharacter{00C9}{\'E}% + \DeclareUnicodeCharacter{00CA}{\^E}% + \DeclareUnicodeCharacter{00CB}{\"E}% + \DeclareUnicodeCharacter{00CC}{\`I}% + \DeclareUnicodeCharacter{00CD}{\'I}% + \DeclareUnicodeCharacter{00CE}{\^I}% + \DeclareUnicodeCharacter{00CF}{\"I}% + % + \DeclareUnicodeCharacter{00D0}{\DH}% + \DeclareUnicodeCharacter{00D1}{\~N}% + \DeclareUnicodeCharacter{00D2}{\`O}% + \DeclareUnicodeCharacter{00D3}{\'O}% + \DeclareUnicodeCharacter{00D4}{\^O}% + \DeclareUnicodeCharacter{00D5}{\~O}% + \DeclareUnicodeCharacter{00D6}{\"O}% + \DeclareUnicodeCharacter{00D7}{\ensuremath\times}% + \DeclareUnicodeCharacter{00D8}{\O}% + \DeclareUnicodeCharacter{00D9}{\`U}% + \DeclareUnicodeCharacter{00DA}{\'U}% + \DeclareUnicodeCharacter{00DB}{\^U}% + \DeclareUnicodeCharacter{00DC}{\"U}% + \DeclareUnicodeCharacter{00DD}{\'Y}% + \DeclareUnicodeCharacter{00DE}{\TH}% + \DeclareUnicodeCharacter{00DF}{\ss}% + % + \DeclareUnicodeCharacter{00E0}{\`a}% + \DeclareUnicodeCharacter{00E1}{\'a}% + \DeclareUnicodeCharacter{00E2}{\^a}% + \DeclareUnicodeCharacter{00E3}{\~a}% + \DeclareUnicodeCharacter{00E4}{\"a}% + \DeclareUnicodeCharacter{00E5}{\aa}% + \DeclareUnicodeCharacter{00E6}{\ae}% + \DeclareUnicodeCharacter{00E7}{\cedilla{c}}% + \DeclareUnicodeCharacter{00E8}{\`e}% + \DeclareUnicodeCharacter{00E9}{\'e}% + \DeclareUnicodeCharacter{00EA}{\^e}% + \DeclareUnicodeCharacter{00EB}{\"e}% + \DeclareUnicodeCharacter{00EC}{\`{\dotless{i}}}% + \DeclareUnicodeCharacter{00ED}{\'{\dotless{i}}}% + \DeclareUnicodeCharacter{00EE}{\^{\dotless{i}}}% + \DeclareUnicodeCharacter{00EF}{\"{\dotless{i}}}% + % + \DeclareUnicodeCharacter{00F0}{\dh}% + \DeclareUnicodeCharacter{00F1}{\~n}% + \DeclareUnicodeCharacter{00F2}{\`o}% + \DeclareUnicodeCharacter{00F3}{\'o}% + \DeclareUnicodeCharacter{00F4}{\^o}% + \DeclareUnicodeCharacter{00F5}{\~o}% + \DeclareUnicodeCharacter{00F6}{\"o}% + \DeclareUnicodeCharacter{00F7}{\ensuremath\div}% + \DeclareUnicodeCharacter{00F8}{\o}% + \DeclareUnicodeCharacter{00F9}{\`u}% + \DeclareUnicodeCharacter{00FA}{\'u}% + \DeclareUnicodeCharacter{00FB}{\^u}% + \DeclareUnicodeCharacter{00FC}{\"u}% + \DeclareUnicodeCharacter{00FD}{\'y}% + \DeclareUnicodeCharacter{00FE}{\th}% + \DeclareUnicodeCharacter{00FF}{\"y}% + % + \DeclareUnicodeCharacter{0100}{\=A}% + \DeclareUnicodeCharacter{0101}{\=a}% + \DeclareUnicodeCharacter{0102}{\u{A}}% + \DeclareUnicodeCharacter{0103}{\u{a}}% + \DeclareUnicodeCharacter{0104}{\ogonek{A}}% + \DeclareUnicodeCharacter{0105}{\ogonek{a}}% + \DeclareUnicodeCharacter{0106}{\'C}% + \DeclareUnicodeCharacter{0107}{\'c}% + \DeclareUnicodeCharacter{0108}{\^C}% + \DeclareUnicodeCharacter{0109}{\^c}% + \DeclareUnicodeCharacter{010A}{\dotaccent{C}}% + \DeclareUnicodeCharacter{010B}{\dotaccent{c}}% + \DeclareUnicodeCharacter{010C}{\v{C}}% + \DeclareUnicodeCharacter{010D}{\v{c}}% + \DeclareUnicodeCharacter{010E}{\v{D}}% + \DeclareUnicodeCharacter{010F}{d'}% + % + \DeclareUnicodeCharacter{0110}{\DH}% + \DeclareUnicodeCharacter{0111}{\dh}% + \DeclareUnicodeCharacter{0112}{\=E}% + \DeclareUnicodeCharacter{0113}{\=e}% + \DeclareUnicodeCharacter{0114}{\u{E}}% + \DeclareUnicodeCharacter{0115}{\u{e}}% + \DeclareUnicodeCharacter{0116}{\dotaccent{E}}% + \DeclareUnicodeCharacter{0117}{\dotaccent{e}}% + \DeclareUnicodeCharacter{0118}{\ogonek{E}}% + \DeclareUnicodeCharacter{0119}{\ogonek{e}}% + \DeclareUnicodeCharacter{011A}{\v{E}}% + \DeclareUnicodeCharacter{011B}{\v{e}}% + \DeclareUnicodeCharacter{011C}{\^G}% + \DeclareUnicodeCharacter{011D}{\^g}% + \DeclareUnicodeCharacter{011E}{\u{G}}% + \DeclareUnicodeCharacter{011F}{\u{g}}% + % + \DeclareUnicodeCharacter{0120}{\dotaccent{G}}% + \DeclareUnicodeCharacter{0121}{\dotaccent{g}}% + \DeclareUnicodeCharacter{0122}{\cedilla{G}}% + \DeclareUnicodeCharacter{0123}{\cedilla{g}}% + \DeclareUnicodeCharacter{0124}{\^H}% + \DeclareUnicodeCharacter{0125}{\^h}% + \DeclareUnicodeCharacter{0126}{\missingcharmsg{H WITH STROKE}}% + \DeclareUnicodeCharacter{0127}{\missingcharmsg{h WITH STROKE}}% + \DeclareUnicodeCharacter{0128}{\~I}% + \DeclareUnicodeCharacter{0129}{\~{\dotless{i}}}% + \DeclareUnicodeCharacter{012A}{\=I}% + \DeclareUnicodeCharacter{012B}{\={\dotless{i}}}% + \DeclareUnicodeCharacter{012C}{\u{I}}% + \DeclareUnicodeCharacter{012D}{\u{\dotless{i}}}% + \DeclareUnicodeCharacter{012E}{\ogonek{I}}% + \DeclareUnicodeCharacter{012F}{\ogonek{i}}% + % + \DeclareUnicodeCharacter{0130}{\dotaccent{I}}% + \DeclareUnicodeCharacter{0131}{\dotless{i}}% + \DeclareUnicodeCharacter{0132}{IJ}% + \DeclareUnicodeCharacter{0133}{ij}% + \DeclareUnicodeCharacter{0134}{\^J}% + \DeclareUnicodeCharacter{0135}{\^{\dotless{j}}}% + \DeclareUnicodeCharacter{0136}{\cedilla{K}}% + \DeclareUnicodeCharacter{0137}{\cedilla{k}}% + \DeclareUnicodeCharacter{0138}{\ensuremath\kappa}% + \DeclareUnicodeCharacter{0139}{\'L}% + \DeclareUnicodeCharacter{013A}{\'l}% + \DeclareUnicodeCharacter{013B}{\cedilla{L}}% + \DeclareUnicodeCharacter{013C}{\cedilla{l}}% + \DeclareUnicodeCharacter{013D}{L'}% should kern + \DeclareUnicodeCharacter{013E}{l'}% should kern + \DeclareUnicodeCharacter{013F}{L\U{00B7}}% + % + \DeclareUnicodeCharacter{0140}{l\U{00B7}}% + \DeclareUnicodeCharacter{0141}{\L}% + \DeclareUnicodeCharacter{0142}{\l}% + \DeclareUnicodeCharacter{0143}{\'N}% + \DeclareUnicodeCharacter{0144}{\'n}% + \DeclareUnicodeCharacter{0145}{\cedilla{N}}% + \DeclareUnicodeCharacter{0146}{\cedilla{n}}% + \DeclareUnicodeCharacter{0147}{\v{N}}% + \DeclareUnicodeCharacter{0148}{\v{n}}% + \DeclareUnicodeCharacter{0149}{'n}% + \DeclareUnicodeCharacter{014A}{\missingcharmsg{ENG}}% + \DeclareUnicodeCharacter{014B}{\missingcharmsg{eng}}% + \DeclareUnicodeCharacter{014C}{\=O}% + \DeclareUnicodeCharacter{014D}{\=o}% + \DeclareUnicodeCharacter{014E}{\u{O}}% + \DeclareUnicodeCharacter{014F}{\u{o}}% + % + \DeclareUnicodeCharacter{0150}{\H{O}}% + \DeclareUnicodeCharacter{0151}{\H{o}}% + \DeclareUnicodeCharacter{0152}{\OE}% + \DeclareUnicodeCharacter{0153}{\oe}% + \DeclareUnicodeCharacter{0154}{\'R}% + \DeclareUnicodeCharacter{0155}{\'r}% + \DeclareUnicodeCharacter{0156}{\cedilla{R}}% + \DeclareUnicodeCharacter{0157}{\cedilla{r}}% + \DeclareUnicodeCharacter{0158}{\v{R}}% + \DeclareUnicodeCharacter{0159}{\v{r}}% + \DeclareUnicodeCharacter{015A}{\'S}% + \DeclareUnicodeCharacter{015B}{\'s}% + \DeclareUnicodeCharacter{015C}{\^S}% + \DeclareUnicodeCharacter{015D}{\^s}% + \DeclareUnicodeCharacter{015E}{\cedilla{S}}% + \DeclareUnicodeCharacter{015F}{\cedilla{s}}% + % + \DeclareUnicodeCharacter{0160}{\v{S}}% + \DeclareUnicodeCharacter{0161}{\v{s}}% + \DeclareUnicodeCharacter{0162}{\cedilla{T}}% + \DeclareUnicodeCharacter{0163}{\cedilla{t}}% + \DeclareUnicodeCharacter{0164}{\v{T}}% + \DeclareUnicodeCharacter{0165}{\v{t}}% + \DeclareUnicodeCharacter{0166}{\missingcharmsg{H WITH STROKE}}% + \DeclareUnicodeCharacter{0167}{\missingcharmsg{h WITH STROKE}}% + \DeclareUnicodeCharacter{0168}{\~U}% + \DeclareUnicodeCharacter{0169}{\~u}% + \DeclareUnicodeCharacter{016A}{\=U}% + \DeclareUnicodeCharacter{016B}{\=u}% + \DeclareUnicodeCharacter{016C}{\u{U}}% + \DeclareUnicodeCharacter{016D}{\u{u}}% + \DeclareUnicodeCharacter{016E}{\ringaccent{U}}% + \DeclareUnicodeCharacter{016F}{\ringaccent{u}}% + % + \DeclareUnicodeCharacter{0170}{\H{U}}% + \DeclareUnicodeCharacter{0171}{\H{u}}% + \DeclareUnicodeCharacter{0172}{\ogonek{U}}% + \DeclareUnicodeCharacter{0173}{\ogonek{u}}% + \DeclareUnicodeCharacter{0174}{\^W}% + \DeclareUnicodeCharacter{0175}{\^w}% + \DeclareUnicodeCharacter{0176}{\^Y}% + \DeclareUnicodeCharacter{0177}{\^y}% + \DeclareUnicodeCharacter{0178}{\"Y}% + \DeclareUnicodeCharacter{0179}{\'Z}% + \DeclareUnicodeCharacter{017A}{\'z}% + \DeclareUnicodeCharacter{017B}{\dotaccent{Z}}% + \DeclareUnicodeCharacter{017C}{\dotaccent{z}}% + \DeclareUnicodeCharacter{017D}{\v{Z}}% + \DeclareUnicodeCharacter{017E}{\v{z}}% + \DeclareUnicodeCharacter{017F}{\missingcharmsg{LONG S}}% + % + \DeclareUnicodeCharacter{01C4}{D\v{Z}}% + \DeclareUnicodeCharacter{01C5}{D\v{z}}% + \DeclareUnicodeCharacter{01C6}{d\v{z}}% + \DeclareUnicodeCharacter{01C7}{LJ}% + \DeclareUnicodeCharacter{01C8}{Lj}% + \DeclareUnicodeCharacter{01C9}{lj}% + \DeclareUnicodeCharacter{01CA}{NJ}% + \DeclareUnicodeCharacter{01CB}{Nj}% + \DeclareUnicodeCharacter{01CC}{nj}% + \DeclareUnicodeCharacter{01CD}{\v{A}}% + \DeclareUnicodeCharacter{01CE}{\v{a}}% + \DeclareUnicodeCharacter{01CF}{\v{I}}% + % + \DeclareUnicodeCharacter{01D0}{\v{\dotless{i}}}% + \DeclareUnicodeCharacter{01D1}{\v{O}}% + \DeclareUnicodeCharacter{01D2}{\v{o}}% + \DeclareUnicodeCharacter{01D3}{\v{U}}% + \DeclareUnicodeCharacter{01D4}{\v{u}}% + % + \DeclareUnicodeCharacter{01E2}{\={\AE}}% + \DeclareUnicodeCharacter{01E3}{\={\ae}}% + \DeclareUnicodeCharacter{01E6}{\v{G}}% + \DeclareUnicodeCharacter{01E7}{\v{g}}% + \DeclareUnicodeCharacter{01E8}{\v{K}}% + \DeclareUnicodeCharacter{01E9}{\v{k}}% + % + \DeclareUnicodeCharacter{01F0}{\v{\dotless{j}}}% + \DeclareUnicodeCharacter{01F1}{DZ}% + \DeclareUnicodeCharacter{01F2}{Dz}% + \DeclareUnicodeCharacter{01F3}{dz}% + \DeclareUnicodeCharacter{01F4}{\'G}% + \DeclareUnicodeCharacter{01F5}{\'g}% + \DeclareUnicodeCharacter{01F8}{\`N}% + \DeclareUnicodeCharacter{01F9}{\`n}% + \DeclareUnicodeCharacter{01FC}{\'{\AE}}% + \DeclareUnicodeCharacter{01FD}{\'{\ae}}% + \DeclareUnicodeCharacter{01FE}{\'{\O}}% + \DeclareUnicodeCharacter{01FF}{\'{\o}}% + % + \DeclareUnicodeCharacter{021E}{\v{H}}% + \DeclareUnicodeCharacter{021F}{\v{h}}% + % + \DeclareUnicodeCharacter{0226}{\dotaccent{A}}% + \DeclareUnicodeCharacter{0227}{\dotaccent{a}}% + \DeclareUnicodeCharacter{0228}{\cedilla{E}}% + \DeclareUnicodeCharacter{0229}{\cedilla{e}}% + \DeclareUnicodeCharacter{022E}{\dotaccent{O}}% + \DeclareUnicodeCharacter{022F}{\dotaccent{o}}% + % + \DeclareUnicodeCharacter{0232}{\=Y}% + \DeclareUnicodeCharacter{0233}{\=y}% + \DeclareUnicodeCharacter{0237}{\dotless{j}}% + % + \DeclareUnicodeCharacter{02DB}{\ogonek{ }}% + % + % Greek letters upper case + \DeclareUnicodeCharacter{0391}{{\it A}}% + \DeclareUnicodeCharacter{0392}{{\it B}}% + \DeclareUnicodeCharacter{0393}{\ensuremath{\mit\Gamma}}% + \DeclareUnicodeCharacter{0394}{\ensuremath{\mit\Delta}}% + \DeclareUnicodeCharacter{0395}{{\it E}}% + \DeclareUnicodeCharacter{0396}{{\it Z}}% + \DeclareUnicodeCharacter{0397}{{\it H}}% + \DeclareUnicodeCharacter{0398}{\ensuremath{\mit\Theta}}% + \DeclareUnicodeCharacter{0399}{{\it I}}% + \DeclareUnicodeCharacter{039A}{{\it K}}% + \DeclareUnicodeCharacter{039B}{\ensuremath{\mit\Lambda}}% + \DeclareUnicodeCharacter{039C}{{\it M}}% + \DeclareUnicodeCharacter{039D}{{\it N}}% + \DeclareUnicodeCharacter{039E}{\ensuremath{\mit\Xi}}% + \DeclareUnicodeCharacter{039F}{{\it O}}% + \DeclareUnicodeCharacter{03A0}{\ensuremath{\mit\Pi}}% + \DeclareUnicodeCharacter{03A1}{{\it P}}% + %\DeclareUnicodeCharacter{03A2}{} % none - corresponds to final sigma + \DeclareUnicodeCharacter{03A3}{\ensuremath{\mit\Sigma}}% + \DeclareUnicodeCharacter{03A4}{{\it T}}% + \DeclareUnicodeCharacter{03A5}{\ensuremath{\mit\Upsilon}}% + \DeclareUnicodeCharacter{03A6}{\ensuremath{\mit\Phi}}% + \DeclareUnicodeCharacter{03A7}{{\it X}}% + \DeclareUnicodeCharacter{03A8}{\ensuremath{\mit\Psi}}% + \DeclareUnicodeCharacter{03A9}{\ensuremath{\mit\Omega}}% + % + % Vowels with accents + \DeclareUnicodeCharacter{0390}{\ensuremath{\ddot{\acute\iota}}}% + \DeclareUnicodeCharacter{03AC}{\ensuremath{\acute\alpha}}% + \DeclareUnicodeCharacter{03AD}{\ensuremath{\acute\epsilon}}% + \DeclareUnicodeCharacter{03AE}{\ensuremath{\acute\eta}}% + \DeclareUnicodeCharacter{03AF}{\ensuremath{\acute\iota}}% + \DeclareUnicodeCharacter{03B0}{\ensuremath{\acute{\ddot\upsilon}}}% + % + % Standalone accent + \DeclareUnicodeCharacter{0384}{\ensuremath{\acute{\ }}}% + % + % Greek letters lower case + \DeclareUnicodeCharacter{03B1}{\ensuremath\alpha}% + \DeclareUnicodeCharacter{03B2}{\ensuremath\beta}% + \DeclareUnicodeCharacter{03B3}{\ensuremath\gamma}% + \DeclareUnicodeCharacter{03B4}{\ensuremath\delta}% + \DeclareUnicodeCharacter{03B5}{\ensuremath\epsilon}% + \DeclareUnicodeCharacter{03B6}{\ensuremath\zeta}% + \DeclareUnicodeCharacter{03B7}{\ensuremath\eta}% + \DeclareUnicodeCharacter{03B8}{\ensuremath\theta}% + \DeclareUnicodeCharacter{03B9}{\ensuremath\iota}% + \DeclareUnicodeCharacter{03BA}{\ensuremath\kappa}% + \DeclareUnicodeCharacter{03BB}{\ensuremath\lambda}% + \DeclareUnicodeCharacter{03BC}{\ensuremath\mu}% + \DeclareUnicodeCharacter{03BD}{\ensuremath\nu}% + \DeclareUnicodeCharacter{03BE}{\ensuremath\xi}% + \DeclareUnicodeCharacter{03BF}{{\it o}}% omicron + \DeclareUnicodeCharacter{03C0}{\ensuremath\pi}% + \DeclareUnicodeCharacter{03C1}{\ensuremath\rho}% + \DeclareUnicodeCharacter{03C2}{\ensuremath\varsigma}% + \DeclareUnicodeCharacter{03C3}{\ensuremath\sigma}% + \DeclareUnicodeCharacter{03C4}{\ensuremath\tau}% + \DeclareUnicodeCharacter{03C5}{\ensuremath\upsilon}% + \DeclareUnicodeCharacter{03C6}{\ensuremath\phi}% + \DeclareUnicodeCharacter{03C7}{\ensuremath\chi}% + \DeclareUnicodeCharacter{03C8}{\ensuremath\psi}% + \DeclareUnicodeCharacter{03C9}{\ensuremath\omega}% + % + % More Greek vowels with accents + \DeclareUnicodeCharacter{03CA}{\ensuremath{\ddot\iota}}% + \DeclareUnicodeCharacter{03CB}{\ensuremath{\ddot\upsilon}}% + \DeclareUnicodeCharacter{03CC}{\ensuremath{\acute o}}% + \DeclareUnicodeCharacter{03CD}{\ensuremath{\acute\upsilon}}% + \DeclareUnicodeCharacter{03CE}{\ensuremath{\acute\omega}}% + % + % Variant Greek letters + \DeclareUnicodeCharacter{03D1}{\ensuremath\vartheta}% + \DeclareUnicodeCharacter{03D6}{\ensuremath\varpi}% + \DeclareUnicodeCharacter{03F1}{\ensuremath\varrho}% + % + \DeclareUnicodeCharacter{1E02}{\dotaccent{B}}% + \DeclareUnicodeCharacter{1E03}{\dotaccent{b}}% + \DeclareUnicodeCharacter{1E04}{\udotaccent{B}}% + \DeclareUnicodeCharacter{1E05}{\udotaccent{b}}% + \DeclareUnicodeCharacter{1E06}{\ubaraccent{B}}% + \DeclareUnicodeCharacter{1E07}{\ubaraccent{b}}% + \DeclareUnicodeCharacter{1E0A}{\dotaccent{D}}% + \DeclareUnicodeCharacter{1E0B}{\dotaccent{d}}% + \DeclareUnicodeCharacter{1E0C}{\udotaccent{D}}% + \DeclareUnicodeCharacter{1E0D}{\udotaccent{d}}% + \DeclareUnicodeCharacter{1E0E}{\ubaraccent{D}}% + \DeclareUnicodeCharacter{1E0F}{\ubaraccent{d}}% + % + \DeclareUnicodeCharacter{1E1E}{\dotaccent{F}}% + \DeclareUnicodeCharacter{1E1F}{\dotaccent{f}}% + % + \DeclareUnicodeCharacter{1E20}{\=G}% + \DeclareUnicodeCharacter{1E21}{\=g}% + \DeclareUnicodeCharacter{1E22}{\dotaccent{H}}% + \DeclareUnicodeCharacter{1E23}{\dotaccent{h}}% + \DeclareUnicodeCharacter{1E24}{\udotaccent{H}}% + \DeclareUnicodeCharacter{1E25}{\udotaccent{h}}% + \DeclareUnicodeCharacter{1E26}{\"H}% + \DeclareUnicodeCharacter{1E27}{\"h}% + % + \DeclareUnicodeCharacter{1E30}{\'K}% + \DeclareUnicodeCharacter{1E31}{\'k}% + \DeclareUnicodeCharacter{1E32}{\udotaccent{K}}% + \DeclareUnicodeCharacter{1E33}{\udotaccent{k}}% + \DeclareUnicodeCharacter{1E34}{\ubaraccent{K}}% + \DeclareUnicodeCharacter{1E35}{\ubaraccent{k}}% + \DeclareUnicodeCharacter{1E36}{\udotaccent{L}}% + \DeclareUnicodeCharacter{1E37}{\udotaccent{l}}% + \DeclareUnicodeCharacter{1E3A}{\ubaraccent{L}}% + \DeclareUnicodeCharacter{1E3B}{\ubaraccent{l}}% + \DeclareUnicodeCharacter{1E3E}{\'M}% + \DeclareUnicodeCharacter{1E3F}{\'m}% + % + \DeclareUnicodeCharacter{1E40}{\dotaccent{M}}% + \DeclareUnicodeCharacter{1E41}{\dotaccent{m}}% + \DeclareUnicodeCharacter{1E42}{\udotaccent{M}}% + \DeclareUnicodeCharacter{1E43}{\udotaccent{m}}% + \DeclareUnicodeCharacter{1E44}{\dotaccent{N}}% + \DeclareUnicodeCharacter{1E45}{\dotaccent{n}}% + \DeclareUnicodeCharacter{1E46}{\udotaccent{N}}% + \DeclareUnicodeCharacter{1E47}{\udotaccent{n}}% + \DeclareUnicodeCharacter{1E48}{\ubaraccent{N}}% + \DeclareUnicodeCharacter{1E49}{\ubaraccent{n}}% + % + \DeclareUnicodeCharacter{1E54}{\'P}% + \DeclareUnicodeCharacter{1E55}{\'p}% + \DeclareUnicodeCharacter{1E56}{\dotaccent{P}}% + \DeclareUnicodeCharacter{1E57}{\dotaccent{p}}% + \DeclareUnicodeCharacter{1E58}{\dotaccent{R}}% + \DeclareUnicodeCharacter{1E59}{\dotaccent{r}}% + \DeclareUnicodeCharacter{1E5A}{\udotaccent{R}}% + \DeclareUnicodeCharacter{1E5B}{\udotaccent{r}}% + \DeclareUnicodeCharacter{1E5E}{\ubaraccent{R}}% + \DeclareUnicodeCharacter{1E5F}{\ubaraccent{r}}% + % + \DeclareUnicodeCharacter{1E60}{\dotaccent{S}}% + \DeclareUnicodeCharacter{1E61}{\dotaccent{s}}% + \DeclareUnicodeCharacter{1E62}{\udotaccent{S}}% + \DeclareUnicodeCharacter{1E63}{\udotaccent{s}}% + \DeclareUnicodeCharacter{1E6A}{\dotaccent{T}}% + \DeclareUnicodeCharacter{1E6B}{\dotaccent{t}}% + \DeclareUnicodeCharacter{1E6C}{\udotaccent{T}}% + \DeclareUnicodeCharacter{1E6D}{\udotaccent{t}}% + \DeclareUnicodeCharacter{1E6E}{\ubaraccent{T}}% + \DeclareUnicodeCharacter{1E6F}{\ubaraccent{t}}% + % + \DeclareUnicodeCharacter{1E7C}{\~V}% + \DeclareUnicodeCharacter{1E7D}{\~v}% + \DeclareUnicodeCharacter{1E7E}{\udotaccent{V}}% + \DeclareUnicodeCharacter{1E7F}{\udotaccent{v}}% + % + \DeclareUnicodeCharacter{1E80}{\`W}% + \DeclareUnicodeCharacter{1E81}{\`w}% + \DeclareUnicodeCharacter{1E82}{\'W}% + \DeclareUnicodeCharacter{1E83}{\'w}% + \DeclareUnicodeCharacter{1E84}{\"W}% + \DeclareUnicodeCharacter{1E85}{\"w}% + \DeclareUnicodeCharacter{1E86}{\dotaccent{W}}% + \DeclareUnicodeCharacter{1E87}{\dotaccent{w}}% + \DeclareUnicodeCharacter{1E88}{\udotaccent{W}}% + \DeclareUnicodeCharacter{1E89}{\udotaccent{w}}% + \DeclareUnicodeCharacter{1E8A}{\dotaccent{X}}% + \DeclareUnicodeCharacter{1E8B}{\dotaccent{x}}% + \DeclareUnicodeCharacter{1E8C}{\"X}% + \DeclareUnicodeCharacter{1E8D}{\"x}% + \DeclareUnicodeCharacter{1E8E}{\dotaccent{Y}}% + \DeclareUnicodeCharacter{1E8F}{\dotaccent{y}}% + % + \DeclareUnicodeCharacter{1E90}{\^Z}% + \DeclareUnicodeCharacter{1E91}{\^z}% + \DeclareUnicodeCharacter{1E92}{\udotaccent{Z}}% + \DeclareUnicodeCharacter{1E93}{\udotaccent{z}}% + \DeclareUnicodeCharacter{1E94}{\ubaraccent{Z}}% + \DeclareUnicodeCharacter{1E95}{\ubaraccent{z}}% + \DeclareUnicodeCharacter{1E96}{\ubaraccent{h}}% + \DeclareUnicodeCharacter{1E97}{\"t}% + \DeclareUnicodeCharacter{1E98}{\ringaccent{w}}% + \DeclareUnicodeCharacter{1E99}{\ringaccent{y}}% + % + \DeclareUnicodeCharacter{1EA0}{\udotaccent{A}}% + \DeclareUnicodeCharacter{1EA1}{\udotaccent{a}}% + % + \DeclareUnicodeCharacter{1EB8}{\udotaccent{E}}% + \DeclareUnicodeCharacter{1EB9}{\udotaccent{e}}% + \DeclareUnicodeCharacter{1EBC}{\~E}% + \DeclareUnicodeCharacter{1EBD}{\~e}% + % + \DeclareUnicodeCharacter{1ECA}{\udotaccent{I}}% + \DeclareUnicodeCharacter{1ECB}{\udotaccent{i}}% + \DeclareUnicodeCharacter{1ECC}{\udotaccent{O}}% + \DeclareUnicodeCharacter{1ECD}{\udotaccent{o}}% + % + \DeclareUnicodeCharacter{1EE4}{\udotaccent{U}}% + \DeclareUnicodeCharacter{1EE5}{\udotaccent{u}}% + % + \DeclareUnicodeCharacter{1EF2}{\`Y}% + \DeclareUnicodeCharacter{1EF3}{\`y}% + \DeclareUnicodeCharacter{1EF4}{\udotaccent{Y}}% + % + \DeclareUnicodeCharacter{1EF8}{\~Y}% + \DeclareUnicodeCharacter{1EF9}{\~y}% + % + % Punctuation + \DeclareUnicodeCharacter{2013}{--}% + \DeclareUnicodeCharacter{2014}{---}% + \DeclareUnicodeCharacter{2018}{\quoteleft{}}% + \DeclareUnicodeCharacter{2019}{\quoteright{}}% + \DeclareUnicodeCharacter{201A}{\quotesinglbase{}}% + \DeclareUnicodeCharacter{201C}{\quotedblleft{}}% + \DeclareUnicodeCharacter{201D}{\quotedblright{}}% + \DeclareUnicodeCharacter{201E}{\quotedblbase{}}% + \DeclareUnicodeCharacter{2020}{\ensuremath\dagger}% + \DeclareUnicodeCharacter{2021}{\ensuremath\ddagger}% + \DeclareUnicodeCharacter{2022}{\bullet{}}% + \DeclareUnicodeCharacter{202F}{\thinspace}% + \DeclareUnicodeCharacter{2026}{\dots{}}% + \DeclareUnicodeCharacter{2039}{\guilsinglleft{}}% + \DeclareUnicodeCharacter{203A}{\guilsinglright{}}% + % + \DeclareUnicodeCharacter{20AC}{\euro{}}% + % + \DeclareUnicodeCharacter{2192}{\expansion{}}% + \DeclareUnicodeCharacter{21D2}{\result{}}% + % + % Mathematical symbols + \DeclareUnicodeCharacter{2200}{\ensuremath\forall}% + \DeclareUnicodeCharacter{2203}{\ensuremath\exists}% + \DeclareUnicodeCharacter{2208}{\ensuremath\in}% + \DeclareUnicodeCharacter{2212}{\minus{}}% + \DeclareUnicodeCharacter{2217}{\ast}% + \DeclareUnicodeCharacter{221E}{\ensuremath\infty}% + \DeclareUnicodeCharacter{2225}{\ensuremath\parallel}% + \DeclareUnicodeCharacter{2227}{\ensuremath\wedge}% + \DeclareUnicodeCharacter{2229}{\ensuremath\cap}% + \DeclareUnicodeCharacter{2261}{\equiv{}}% + \DeclareUnicodeCharacter{2264}{\ensuremath\leq}% + \DeclareUnicodeCharacter{2265}{\ensuremath\geq}% + \DeclareUnicodeCharacter{2282}{\ensuremath\subset}% + \DeclareUnicodeCharacter{2287}{\ensuremath\supseteq}% + % + \DeclareUnicodeCharacter{2016}{\ensuremath\Vert}% + \DeclareUnicodeCharacter{2032}{\ensuremath\prime}% + \DeclareUnicodeCharacter{210F}{\ensuremath\hbar}% + \DeclareUnicodeCharacter{2111}{\ensuremath\Im}% + \DeclareUnicodeCharacter{2113}{\ensuremath\ell}% + \DeclareUnicodeCharacter{2118}{\ensuremath\wp}% + \DeclareUnicodeCharacter{211C}{\ensuremath\Re}% + \DeclareUnicodeCharacter{2135}{\ensuremath\aleph}% + \DeclareUnicodeCharacter{2190}{\ensuremath\leftarrow}% + \DeclareUnicodeCharacter{2191}{\ensuremath\uparrow}% + \DeclareUnicodeCharacter{2193}{\ensuremath\downarrow}% + \DeclareUnicodeCharacter{2194}{\ensuremath\leftrightarrow}% + \DeclareUnicodeCharacter{2195}{\ensuremath\updownarrow}% + \DeclareUnicodeCharacter{2196}{\ensuremath\nwarrow}% + \DeclareUnicodeCharacter{2197}{\ensuremath\nearrow}% + \DeclareUnicodeCharacter{2198}{\ensuremath\searrow}% + \DeclareUnicodeCharacter{2199}{\ensuremath\swarrow}% + \DeclareUnicodeCharacter{21A6}{\ensuremath\mapsto}% + \DeclareUnicodeCharacter{21A9}{\ensuremath\hookleftarrow}% + \DeclareUnicodeCharacter{21AA}{\ensuremath\hookrightarrow}% + \DeclareUnicodeCharacter{21BC}{\ensuremath\leftharpoonup}% + \DeclareUnicodeCharacter{21BD}{\ensuremath\leftharpoondown}% + \DeclareUnicodeCharacter{21C0}{\ensuremath\rightharpoonup}% + \DeclareUnicodeCharacter{21C1}{\ensuremath\rightharpoondown}% + \DeclareUnicodeCharacter{21CC}{\ensuremath\rightleftharpoons}% + \DeclareUnicodeCharacter{21D0}{\ensuremath\Leftarrow}% + \DeclareUnicodeCharacter{21D1}{\ensuremath\Uparrow}% + \DeclareUnicodeCharacter{21D3}{\ensuremath\Downarrow}% + \DeclareUnicodeCharacter{21D4}{\ensuremath\Leftrightarrow}% + \DeclareUnicodeCharacter{21D5}{\ensuremath\Updownarrow}% + \DeclareUnicodeCharacter{2202}{\ensuremath\partial}% + \DeclareUnicodeCharacter{2205}{\ensuremath\emptyset}% + \DeclareUnicodeCharacter{2207}{\ensuremath\nabla}% + \DeclareUnicodeCharacter{2209}{\ensuremath\notin}% + \DeclareUnicodeCharacter{220B}{\ensuremath\owns}% + \DeclareUnicodeCharacter{220F}{\ensuremath\prod}% + \DeclareUnicodeCharacter{2210}{\ensuremath\coprod}% + \DeclareUnicodeCharacter{2211}{\ensuremath\sum}% + \DeclareUnicodeCharacter{2213}{\ensuremath\mp}% + \DeclareUnicodeCharacter{2218}{\ensuremath\circ}% + \DeclareUnicodeCharacter{221A}{\ensuremath\surd}% + \DeclareUnicodeCharacter{221D}{\ensuremath\propto}% + \DeclareUnicodeCharacter{2220}{\ensuremath\angle}% + \DeclareUnicodeCharacter{2223}{\ensuremath\mid}% + \DeclareUnicodeCharacter{2228}{\ensuremath\vee}% + \DeclareUnicodeCharacter{222A}{\ensuremath\cup}% + \DeclareUnicodeCharacter{222B}{\ensuremath\smallint}% + \DeclareUnicodeCharacter{222E}{\ensuremath\oint}% + \DeclareUnicodeCharacter{223C}{\ensuremath\sim}% + \DeclareUnicodeCharacter{2240}{\ensuremath\wr}% + \DeclareUnicodeCharacter{2243}{\ensuremath\simeq}% + \DeclareUnicodeCharacter{2245}{\ensuremath\cong}% + \DeclareUnicodeCharacter{2248}{\ensuremath\approx}% + \DeclareUnicodeCharacter{224D}{\ensuremath\asymp}% + \DeclareUnicodeCharacter{2250}{\ensuremath\doteq}% + \DeclareUnicodeCharacter{2260}{\ensuremath\neq}% + \DeclareUnicodeCharacter{226A}{\ensuremath\ll}% + \DeclareUnicodeCharacter{226B}{\ensuremath\gg}% + \DeclareUnicodeCharacter{227A}{\ensuremath\prec}% + \DeclareUnicodeCharacter{227B}{\ensuremath\succ}% + \DeclareUnicodeCharacter{2283}{\ensuremath\supset}% + \DeclareUnicodeCharacter{2286}{\ensuremath\subseteq}% + \DeclareUnicodeCharacter{228E}{\ensuremath\uplus}% + \DeclareUnicodeCharacter{2291}{\ensuremath\sqsubseteq}% + \DeclareUnicodeCharacter{2292}{\ensuremath\sqsupseteq}% + \DeclareUnicodeCharacter{2293}{\ensuremath\sqcap}% + \DeclareUnicodeCharacter{2294}{\ensuremath\sqcup}% + \DeclareUnicodeCharacter{2295}{\ensuremath\oplus}% + \DeclareUnicodeCharacter{2296}{\ensuremath\ominus}% + \DeclareUnicodeCharacter{2297}{\ensuremath\otimes}% + \DeclareUnicodeCharacter{2298}{\ensuremath\oslash}% + \DeclareUnicodeCharacter{2299}{\ensuremath\odot}% + \DeclareUnicodeCharacter{22A2}{\ensuremath\vdash}% + \DeclareUnicodeCharacter{22A3}{\ensuremath\dashv}% + \DeclareUnicodeCharacter{22A4}{\ensuremath\ptextop}% + \DeclareUnicodeCharacter{22A5}{\ensuremath\bot}% + \DeclareUnicodeCharacter{22A8}{\ensuremath\models}% + \DeclareUnicodeCharacter{22C0}{\ensuremath\bigwedge}% + \DeclareUnicodeCharacter{22C1}{\ensuremath\bigvee}% + \DeclareUnicodeCharacter{22C2}{\ensuremath\bigcap}% + \DeclareUnicodeCharacter{22C3}{\ensuremath\bigcup}% + \DeclareUnicodeCharacter{22C4}{\ensuremath\diamond}% + \DeclareUnicodeCharacter{22C5}{\ensuremath\cdot}% + \DeclareUnicodeCharacter{22C6}{\ensuremath\star}% + \DeclareUnicodeCharacter{22C8}{\ensuremath\bowtie}% + \DeclareUnicodeCharacter{2308}{\ensuremath\lceil}% + \DeclareUnicodeCharacter{2309}{\ensuremath\rceil}% + \DeclareUnicodeCharacter{230A}{\ensuremath\lfloor}% + \DeclareUnicodeCharacter{230B}{\ensuremath\rfloor}% + \DeclareUnicodeCharacter{2322}{\ensuremath\frown}% + \DeclareUnicodeCharacter{2323}{\ensuremath\smile}% + % + \DeclareUnicodeCharacter{25B3}{\ensuremath\triangle}% + \DeclareUnicodeCharacter{25B7}{\ensuremath\triangleright}% + \DeclareUnicodeCharacter{25BD}{\ensuremath\bigtriangledown}% + \DeclareUnicodeCharacter{25C1}{\ensuremath\triangleleft}% + \DeclareUnicodeCharacter{25C7}{\ensuremath\diamond}% + \DeclareUnicodeCharacter{2660}{\ensuremath\spadesuit}% + \DeclareUnicodeCharacter{2661}{\ensuremath\heartsuit}% + \DeclareUnicodeCharacter{2662}{\ensuremath\diamondsuit}% + \DeclareUnicodeCharacter{2663}{\ensuremath\clubsuit}% + \DeclareUnicodeCharacter{266D}{\ensuremath\flat}% + \DeclareUnicodeCharacter{266E}{\ensuremath\natural}% + \DeclareUnicodeCharacter{266F}{\ensuremath\sharp}% + \DeclareUnicodeCharacter{26AA}{\ensuremath\bigcirc}% + \DeclareUnicodeCharacter{27B9}{\ensuremath\rangle}% + \DeclareUnicodeCharacter{27C2}{\ensuremath\perp}% + \DeclareUnicodeCharacter{27E8}{\ensuremath\langle}% + \DeclareUnicodeCharacter{27F5}{\ensuremath\longleftarrow}% + \DeclareUnicodeCharacter{27F6}{\ensuremath\longrightarrow}% + \DeclareUnicodeCharacter{27F7}{\ensuremath\longleftrightarrow}% + \DeclareUnicodeCharacter{27FC}{\ensuremath\longmapsto}% + \DeclareUnicodeCharacter{29F5}{\ensuremath\setminus}% + \DeclareUnicodeCharacter{2A00}{\ensuremath\bigodot}% + \DeclareUnicodeCharacter{2A01}{\ensuremath\bigoplus}% + \DeclareUnicodeCharacter{2A02}{\ensuremath\bigotimes}% + \DeclareUnicodeCharacter{2A04}{\ensuremath\biguplus}% + \DeclareUnicodeCharacter{2A06}{\ensuremath\bigsqcup}% + \DeclareUnicodeCharacter{2A3F}{\ensuremath\amalg}% + \DeclareUnicodeCharacter{2AAF}{\ensuremath\preceq}% + \DeclareUnicodeCharacter{2AB0}{\ensuremath\succeq}% + % + \global\mathchardef\checkmark="1370% actually the square root sign + \DeclareUnicodeCharacter{2713}{\ensuremath\checkmark}% +}% end of \unicodechardefs + +% UTF-8 byte sequence (pdfTeX) definitions (replacing and @U command) +% It makes the setting that replace UTF-8 byte sequence. +\def\utfeightchardefs{% + \let\DeclareUnicodeCharacter\DeclareUnicodeCharacterUTFviii + \unicodechardefs +} + +% Whether the active definitions of non-ASCII characters expand to +% non-active tokens with the same character code. This is used to +% write characters literally, instead of using active definitions for +% printing the correct glyphs. +\newif\ifpassthroughchars +\passthroughcharsfalse + +% For native Unicode handling (XeTeX and LuaTeX), +% provide a definition macro to replace/pass-through a Unicode character +% +\def\DeclareUnicodeCharacterNative#1#2{% + \catcode"#1=\active + \def\dodeclareunicodecharacternative##1##2##3{% + \begingroup + \uccode`\~="##2\relax + \uppercase{\gdef~}{% + \ifpassthroughchars + ##1% + \else + ##3% + \fi + } + \endgroup + } + \begingroup + \uccode`\.="#1\relax + \uppercase{\def\UTFNativeTmp{.}}% + \expandafter\dodeclareunicodecharacternative\UTFNativeTmp{#1}{#2}% + \endgroup +} + +% Native Unicode handling (XeTeX and LuaTeX) character replacing definition. +% It activates the setting that replaces Unicode characters. +\def\nativeunicodechardefs{% + \let\DeclareUnicodeCharacter\DeclareUnicodeCharacterNative + \unicodechardefs +} + +% For native Unicode handling (XeTeX and LuaTeX), +% make the character token expand +% to the sequences given in \unicodechardefs for printing. +\def\DeclareUnicodeCharacterNativeAtU#1#2{% + \def\UTFAtUTmp{#2} + \expandafter\globallet\csname uni:#1\endcsname \UTFAtUTmp +} + +% @U command definitions for native Unicode handling (XeTeX and LuaTeX). +\def\nativeunicodechardefsatu{% + \let\DeclareUnicodeCharacter\DeclareUnicodeCharacterNativeAtU + \unicodechardefs +} + +% US-ASCII character definitions. +\def\asciichardefs{% nothing need be done + \relax +} + +% define all Unicode characters we know about, for the sake of @U. +\iftxinativeunicodecapable + \nativeunicodechardefsatu +\else + \utfeightchardefs +\fi + + +% Make non-ASCII characters printable again for compatibility with +% existing Texinfo documents that may use them, even without declaring a +% document encoding. +% +\setnonasciicharscatcode \other + + +\message{formatting,} + +\newdimen\defaultparindent \defaultparindent = 15pt + +\chapheadingskip = 15pt plus 4pt minus 2pt +\secheadingskip = 12pt plus 3pt minus 2pt +\subsecheadingskip = 9pt plus 2pt minus 2pt + +% Prevent underfull vbox error messages. +\vbadness = 10000 + +% Don't be very finicky about underfull hboxes, either. +\hbadness = 6666 + +% Following George Bush, 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. We call this whenever the paper size is set. +% +\def\setemergencystretch{% + \ifx\emergencystretch\thisisundefined + % Allow us to assign to \emergencystretch anyway. + \def\emergencystretch{\dimen0}% + \else + \emergencystretch = .15\hsize + \fi +} + +% Parameters in order: 1) textheight; 2) textwidth; +% 3) voffset; 4) hoffset; 5) binding offset; 6) topskip; +% 7) physical page height; 8) physical page width. +% +% We also call \setleading{\textleading}, so the caller should define +% \textleading. The caller should also set \parskip. +% +\def\internalpagesizes#1#2#3#4#5#6#7#8{% + \voffset = #3\relax + \topskip = #6\relax + \splittopskip = \topskip + % + \vsize = #1\relax + \advance\vsize by \topskip + \outervsize = \vsize + \advance\outervsize by 2\topandbottommargin + \txipageheight = \vsize + % + \hsize = #2\relax + \outerhsize = \hsize + \advance\outerhsize by 0.5in + \txipagewidth = \hsize + % + \normaloffset = #4\relax + \bindingoffset = #5\relax + % + \ifpdf + \pdfpageheight #7\relax + \pdfpagewidth #8\relax + % if we don't reset these, they will remain at "1 true in" of + % whatever layout pdftex was dumped with. + \pdfhorigin = 1 true in + \pdfvorigin = 1 true in + \else + \ifx\XeTeXrevision\thisisundefined + \special{papersize=#8,#7}% + \else + \pdfpageheight #7\relax + \pdfpagewidth #8\relax + % XeTeX does not have \pdfhorigin and \pdfvorigin. + \fi + \fi + % + \setleading{\textleading} + % + \parindent = \defaultparindent + \setemergencystretch +} + +% @letterpaper (the default). +\def\letterpaper{{\globaldefs = 1 + \parskip = 3pt plus 2pt minus 1pt + \textleading = 13.2pt + % + % If page is nothing but text, make it come out even. + \internalpagesizes{607.2pt}{6in}% that's 46 lines + {\voffset}{.25in}% + {\bindingoffset}{36pt}% + {11in}{8.5in}% +}} + +% Use @smallbook to reset parameters for 7x9.25 trim size. +\def\smallbook{{\globaldefs = 1 + \parskip = 2pt plus 1pt + \textleading = 12pt + % + \internalpagesizes{7.5in}{5in}% + {-.2in}{0in}% + {\bindingoffset}{16pt}% + {9.25in}{7in}% + % + \lispnarrowing = 0.3in + \tolerance = 700 + \contentsrightmargin = 0pt + \defbodyindent = .5cm +}} + +% Use @smallerbook to reset parameters for 6x9 trim size. +% (Just testing, parameters still in flux.) +\def\smallerbook{{\globaldefs = 1 + \parskip = 1.5pt plus 1pt + \textleading = 12pt + % + \internalpagesizes{7.4in}{4.8in}% + {-.2in}{-.4in}% + {0pt}{14pt}% + {9in}{6in}% + % + \lispnarrowing = 0.25in + \tolerance = 700 + \contentsrightmargin = 0pt + \defbodyindent = .4cm +}} + +% Use @afourpaper to print on European A4 paper. +\def\afourpaper{{\globaldefs = 1 + \parskip = 3pt plus 2pt minus 1pt + \textleading = 13.2pt + % + % Double-side printing via postscript on Laserjet 4050 + % prints double-sided nicely when \bindingoffset=10mm and \hoffset=-6mm. + % To change the settings for a different printer or situation, adjust + % \normaloffset until the front-side and back-side texts align. Then + % do the same for \bindingoffset. You can set these for testing in + % your texinfo source file like this: + % @tex + % \global\normaloffset = -6mm + % \global\bindingoffset = 10mm + % @end tex + \internalpagesizes{673.2pt}{160mm}% that's 51 lines + {\voffset}{\hoffset}% + {\bindingoffset}{44pt}% + {297mm}{210mm}% + % + \tolerance = 700 + \contentsrightmargin = 0pt + \defbodyindent = 5mm +}} + +% Use @afivepaper to print on European A5 paper. +% From romildo@urano.iceb.ufop.br, 2 July 2000. +% He also recommends making @example and @lisp be small. +\def\afivepaper{{\globaldefs = 1 + \parskip = 2pt plus 1pt minus 0.1pt + \textleading = 12.5pt + % + \internalpagesizes{160mm}{120mm}% + {\voffset}{\hoffset}% + {\bindingoffset}{8pt}% + {210mm}{148mm}% + % + \lispnarrowing = 0.2in + \tolerance = 800 + \contentsrightmargin = 0pt + \defbodyindent = 2mm + \tableindent = 12mm +}} + +% A specific text layout, 24x15cm overall, intended for A4 paper. +\def\afourlatex{{\globaldefs = 1 + \afourpaper + \internalpagesizes{237mm}{150mm}% + {\voffset}{4.6mm}% + {\bindingoffset}{7mm}% + {297mm}{210mm}% + % + % Must explicitly reset to 0 because we call \afourpaper. + \globaldefs = 0 +}} + +% Use @afourwide to print on A4 paper in landscape format. +\def\afourwide{{\globaldefs = 1 + \afourpaper + \internalpagesizes{241mm}{165mm}% + {\voffset}{-2.95mm}% + {\bindingoffset}{7mm}% + {297mm}{210mm}% + \globaldefs = 0 +}} + +% @pagesizes TEXTHEIGHT[,TEXTWIDTH] +% Perhaps we should allow setting the margins, \topskip, \parskip, +% and/or leading, also. Or perhaps we should compute them somehow. +% +\parseargdef\pagesizes{\pagesizesyyy #1,,\finish} +\def\pagesizesyyy#1,#2,#3\finish{{% + \setbox0 = \hbox{\ignorespaces #2}\ifdim\wd0 > 0pt \hsize=#2\relax \fi + \globaldefs = 1 + % + \parskip = 3pt plus 2pt minus 1pt + \setleading{\textleading}% + % + \dimen0 = #1\relax + \advance\dimen0 by \voffset + \advance\dimen0 by 1in % reference point for DVI is 1 inch from top of page + % + \dimen2 = \hsize + \advance\dimen2 by \normaloffset + \advance\dimen2 by 1in % reference point is 1 inch from left edge of page + % + \internalpagesizes{#1}{\hsize}% + {\voffset}{\normaloffset}% + {\bindingoffset}{44pt}% + {\dimen0}{\dimen2}% +}} + +% Set default to letter. +% +\letterpaper + +% Default value of \hfuzz, for suppressing warnings about overfull hboxes. +\hfuzz = 1pt + + +\message{and turning on texinfo input format.} + +\def^^L{\par} % remove \outer, so ^L can appear in an @comment + +% DEL is a comment character, in case @c does not suffice. +\catcode`\^^? = 14 + +% Define macros to output various characters with catcode for normal text. +\catcode`\"=\other \def\normaldoublequote{"} +\catcode`\$=\other \def\normaldollar{$}%$ font-lock fix +\catcode`\+=\other \def\normalplus{+} +\catcode`\<=\other \def\normalless{<} +\catcode`\>=\other \def\normalgreater{>} +\catcode`\^=\other \def\normalcaret{^} +\catcode`\_=\other \def\normalunderscore{_} +\catcode`\|=\other \def\normalverticalbar{|} +\catcode`\~=\other \def\normaltilde{~} + +% This macro is used to make a character print one way in \tt +% (where it can probably be output as-is), 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\font=0pt #1\else #2\fi} + +% Same as above, but check for italic font. Actually this also catches +% non-italic slanted fonts since it is impossible to distinguish them from +% italic fonts. But since this is only used by $ and it uses \sl anyway +% this is not a problem. +\def\ifusingit#1#2{\ifdim \fontdimen1\font>0pt #1\else #2\fi} + +% Set catcodes for Texinfo file + +% Active characters for printing the wanted glyph. +% 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\char34}} +\let"=\activedoublequote +\catcode`\~=\active \def\activetilde{{\tt\char126}} \let~ = \activetilde +\chardef\hatchar=`\^ +\catcode`\^=\active \def\activehat{{\tt \hatchar}} \let^ = \activehat + +\catcode`\_=\active +\def_{\ifusingtt\normalunderscore\_} +\def\_{\leavevmode \kern.07em \vbox{\hrule width.3em height.1ex}\kern .07em } +\let\realunder=_ + +\catcode`\|=\active \def|{{\tt\char124}} + +\chardef \less=`\< +\catcode`\<=\active \def\activeless{{\tt \less}}\let< = \activeless +\chardef \gtr=`\> +\catcode`\>=\active \def\activegtr{{\tt \gtr}}\let> = \activegtr +\catcode`\+=\active \def+{{\tt \char 43}} +\catcode`\$=\active \def${\ifusingit{{\sl\$}}\normaldollar}%$ font-lock fix +\catcode`\-=\active \let-=\normaldash + + +% used for headline/footline in the output routine, in case the page +% breaks in the middle of an @tex block. +\def\texinfochars{% + \let< = \activeless + \let> = \activegtr + \let~ = \activetilde + \let^ = \activehat + \markupsetuplqdefault \markupsetuprqdefault + \let\b = \strong + \let\i = \smartitalic + % in principle, all other definitions in \tex have to be undone too. +} + +% Used sometimes to turn off (effectively) the active characters even after +% parsing them. +\def\turnoffactive{% + \normalturnoffactive + \otherbackslash +} + +\catcode`\@=0 + +% \backslashcurfont outputs one backslash character in current font, +% as in \char`\\. +\global\chardef\backslashcurfont=`\\ +\global\let\rawbackslashxx=\backslashcurfont % let existing .??s files work + +% \realbackslash is an actual character `\' with catcode other, and +% \doublebackslash is two of them (for the pdf outlines). +{\catcode`\\=\other @gdef@realbackslash{\} @gdef@doublebackslash{\\}} + +% In Texinfo, backslash is an active character; it prints the backslash +% in fixed width font. +\catcode`\\=\active % @ for escape char from now on. + +% Print a typewriter backslash. For math mode, we can't simply use +% \backslashcurfont: the story here is that in math mode, the \char +% of \backslashcurfont ends up printing the roman \ from the math symbol +% font (because \char in math mode uses the \mathcode, and plain.tex +% sets \mathcode`\\="026E). Hence we use an explicit \mathchar, +% which is the decimal equivalent of "715c (class 7, e.g., use \fam; +% ignored family value; char position "5C). We can't use " for the +% usual hex value because it has already been made active. + +@def@ttbackslash{{@tt @ifmmode @mathchar29020 @else @backslashcurfont @fi}} +@let@backslashchar = @ttbackslash % @backslashchar{} is for user documents. + +% \rawbackslash defines an active \ to do \backslashcurfont. +% \otherbackslash defines an active \ to be a literal `\' character with +% catcode other. We switch back and forth between these. +@gdef@rawbackslash{@let\=@backslashcurfont} +@gdef@otherbackslash{@let\=@realbackslash} + +% Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of +% the literal character `\'. +% +{@catcode`- = @active + @gdef@normalturnoffactive{% + @passthroughcharstrue + @let-=@normaldash + @let"=@normaldoublequote + @let$=@normaldollar %$ font-lock fix + @let+=@normalplus + @let<=@normalless + @let>=@normalgreater + @let^=@normalcaret + @let_=@normalunderscore + @let|=@normalverticalbar + @let~=@normaltilde + @let\=@ttbackslash + @markupsetuplqdefault + @markupsetuprqdefault + @unsepspaces + } +} + +% If a .fmt file is being used, characters that might appear in a file +% name cannot be active until we have parsed the command line. +% So turn them off again, and have @fixbackslash turn them back on. +@catcode`+=@other @catcode`@_=@other + +% \enablebackslashhack - allow file to begin `\input texinfo' +% +% 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. +% If the file did not have a `\input texinfo', then it is turned off after +% the first line; otherwise the first `\' in the file would cause an error. +% This is used on the very last line of this file, texinfo.tex. +% We also use @c to call @fixbackslash, in case ends of lines are hidden. +{ +@catcode`@^=7 +@catcode`@^^M=13@gdef@enablebackslashhack{% + @global@let\ = @eatinput% + @catcode`@^^M=13% + @def@c{@fixbackslash@c}% + % Definition for the newline at the end of this file. + @def ^^M{@let^^M@secondlinenl}% + % Definition for a newline in the main Texinfo file. + @gdef @secondlinenl{@fixbackslash}% + % In case the first line has a whole-line command on it + @let@originalparsearg@parsearg + @def@parsearg{@fixbackslash@originalparsearg} +}} + +{@catcode`@^=7 @catcode`@^^M=13% +@gdef@eatinput input texinfo#1^^M{@fixbackslash}} + +% Emergency active definition of newline, in case an active newline token +% appears by mistake. +{@catcode`@^=7 @catcode13=13% +@gdef@enableemergencynewline{% + @gdef^^M{% + @par% + %<warning: active newline>@par% +}}} + + +@gdef@fixbackslash{% + @ifx\@eatinput @let\ = @ttbackslash @fi + @catcode13=5 % regular end of line + @enableemergencynewline + @let@c=@texinfoc + @let@parsearg@originalparsearg + % Also turn back on active characters that might appear in the input + % file name, in case not using a pre-dumped format. + @catcode`+=@active + @catcode`@_=@active + % + % If texinfo.cnf is present on the system, read it. + % Useful for site-wide @afourpaper, etc. This macro, @fixbackslash, gets + % called at the beginning of every Texinfo file. Not opening texinfo.cnf + % directly in this file, texinfo.tex, makes it possible to make a format + % file for Texinfo. + % + @openin 1 texinfo.cnf + @ifeof 1 @else @input texinfo.cnf @fi + @closein 1 +} + + +% Say @foo, not \foo, in error messages. +@escapechar = `@@ + +% These (along with & and #) are made active for url-breaking, so need +% active definitions as the normal characters. +@def@normaldot{.} +@def@normalquest{?} +@def@normalslash{/} + +% These look ok in all fonts, so just make them not special. +% @hashchar{} gets its own user-level command, because of #line. +@catcode`@& = @other @def@normalamp{&} +@catcode`@# = @other @def@normalhash{#} +@catcode`@% = @other @def@normalpercent{%} + +@let @hashchar = @normalhash + +@c Finally, make ` and ' active, so that txicodequoteundirected and +@c txicodequotebacktick work right in, e.g., @w{@code{`foo'}}. If we +@c don't make ` and ' active, @code will not get them as active chars. +@c Do this last of all since we use ` in the previous @catcode assignments. +@catcode`@'=@active +@catcode`@`=@active +@markupsetuplqdefault +@markupsetuprqdefault + +@c Local variables: +@c eval: (add-hook 'write-file-hooks 'time-stamp) +@c page-delimiter: "^\\\\message\\|emacs-page" +@c time-stamp-start: "def\\\\texinfoversion{" +@c time-stamp-format: "%:y-%02m-%02d.%02H" +@c time-stamp-end: "}" +@c End: + +@c vim:sw=2: + +@enablebackslashhack diff --git a/config/unlocked-io.m4 b/config/unlocked-io.m4 new file mode 100644 index 0000000..657f60d --- /dev/null +++ b/config/unlocked-io.m4 @@ -0,0 +1,41 @@ +# unlocked-io.m4 serial 15 + +# Copyright (C) 1998-2006, 2009-2012, 2014-2015, 2018 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +dnl From Jim Meyering. +dnl +dnl See if the glibc *_unlocked I/O macros or functions are available. +dnl Use only those *_unlocked macros or functions that are declared +dnl (because some of them were declared in Solaris 2.5.1 but were removed +dnl in Solaris 2.6, whereas we want binaries built on Solaris 2.5.1 to run +dnl on Solaris 2.6). + +AC_DEFUN([gl_FUNC_GLIBC_UNLOCKED_IO], +[ + AC_DEFINE([USE_UNLOCKED_IO], [1], + [Define to 1 if you want getc etc. to use unlocked I/O if available. + Unlocked I/O can improve performance in unithreaded apps, + but it is not safe for multithreaded apps.]) + + dnl Persuade glibc and Solaris <stdio.h> to declare + dnl fgets_unlocked(), fputs_unlocked() etc. + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + + AC_CHECK_DECLS_ONCE([clearerr_unlocked]) + AC_CHECK_DECLS_ONCE([feof_unlocked]) + AC_CHECK_DECLS_ONCE([ferror_unlocked]) + AC_CHECK_DECLS_ONCE([fflush_unlocked]) + AC_CHECK_DECLS_ONCE([fgets_unlocked]) + AC_CHECK_DECLS_ONCE([fputc_unlocked]) + AC_CHECK_DECLS_ONCE([fputs_unlocked]) + AC_CHECK_DECLS_ONCE([fread_unlocked]) + AC_CHECK_DECLS_ONCE([fwrite_unlocked]) + AC_CHECK_DECLS_ONCE([getc_unlocked]) + AC_CHECK_DECLS_ONCE([getchar_unlocked]) + AC_CHECK_DECLS_ONCE([putc_unlocked]) + AC_CHECK_DECLS_ONCE([putchar_unlocked]) +]) diff --git a/configure b/configure new file mode 100755 index 0000000..f149ede --- /dev/null +++ b/configure @@ -0,0 +1,21317 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.69 for GNU AutoGen 5.18.16. +# +# Report bugs to <autogen-users@lists.sourceforge.net>. +# +# +# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +## PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# Use a proper internal environment variable to ensure we don't fall + # into an infinite loop, continuously re-executing ourselves. + if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then + _as_can_reexec=no; export _as_can_reexec; + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +as_fn_exit 255 + fi + # We don't want this to propagate to other subprocesses. + { _as_can_reexec=; unset _as_can_reexec;} +if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which + # is contrary to our usage. Disable this feature. + alias -g '\${1+\"\$@\"}'='\"\$@\"' + setopt NO_GLOB_SUBST +else + case \`(set -o) 2>/dev/null\` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi +" + as_required="as_fn_return () { (exit \$1); } +as_fn_success () { as_fn_return 0; } +as_fn_failure () { as_fn_return 1; } +as_fn_ret_success () { return 0; } +as_fn_ret_failure () { return 1; } + +exitcode=0 +as_fn_success || { exitcode=1; echo as_fn_success failed.; } +as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } +as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } +as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } +if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + +else + exitcode=1; echo positional parameters were not saved. +fi +test x\$exitcode = x0 || exit 1 +test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && + test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1 + + test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( + ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO + PATH=/empty FPATH=/empty; export PATH FPATH + test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ + || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1" + if (eval "$as_required") 2>/dev/null; then : + as_have_required=yes +else + as_have_required=no +fi + if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : + +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_found=false +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + as_found=: + case $as_dir in #( + /*) + for as_base in sh bash ksh sh5; do + # Try only shells that exist, to save several forks. + as_shell=$as_dir/$as_base + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : + CONFIG_SHELL=$as_shell as_have_required=yes + if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : + break 2 +fi +fi + done;; + esac + as_found=false +done +$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && + { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : + CONFIG_SHELL=$SHELL as_have_required=yes +fi; } +IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : + export CONFIG_SHELL + # We cannot yet assume a decent shell, so we have to provide a +# neutralization value for shells without unset; and this also +# works around shells that cannot unset nonexistent variables. +# Preserve -v and -x to the replacement shell. +BASH_ENV=/dev/null +ENV=/dev/null +(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; +esac +exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} +# Admittedly, this is quite paranoid, since all the known shells bail +# out after a failed `exec'. +$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 +exit 255 +fi + + if test x$as_have_required = xno; then : + $as_echo "$0: This script requires a shell more modern than all" + $as_echo "$0: the shells that I found on your system." + if test x${ZSH_VERSION+set} = xset ; then + $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" + $as_echo "$0: be upgraded to zsh 4.3.4 or later." + else + $as_echo "$0: Please tell bug-autoconf@gnu.org and +$0: autogen-users@lists.sourceforge.net about your system, +$0: including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one." + fi + exit 1 +fi +fi +fi +SHELL=${CONFIG_SHELL-/bin/sh} +export SHELL +# Unset more variables known to interfere with behavior of common tools. +CLICOLOR_FORCE= GREP_OPTIONS= +unset CLICOLOR_FORCE GREP_OPTIONS + +## --------------------- ## +## M4sh Shell Functions. ## +## --------------------- ## +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + + + as_lineno_1=$LINENO as_lineno_1a=$LINENO + as_lineno_2=$LINENO as_lineno_2a=$LINENO + eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && + test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { + # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + + # If we had to re-execute with $CONFIG_SHELL, we're ensured to have + # already done that, so ensure we don't try to do so again and fall + # in an infinite loop. This has already happened in practice. + _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + +SHELL=${CONFIG_SHELL-/bin/sh} + + +test -n "$DJDIR" || exec 7<&0 </dev/null +exec 6>&1 + +# Name of the host. +# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= + +# Identity of this package. +PACKAGE_NAME='GNU AutoGen' +PACKAGE_TARNAME='autogen' +PACKAGE_VERSION='5.18.16' +PACKAGE_STRING='GNU AutoGen 5.18.16' +PACKAGE_BUGREPORT='autogen-users@lists.sourceforge.net' +PACKAGE_URL='http://www.gnu.org/software/autogen/' + +ac_unique_file="agen5/autogen.c" +# Factoring default headers for most tests. +ac_includes_default="\ +#include <stdio.h> +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif +#ifdef HAVE_SYS_STAT_H +# include <sys/stat.h> +#endif +#ifdef STDC_HEADERS +# include <stdlib.h> +# include <stddef.h> +#else +# ifdef HAVE_STDLIB_H +# include <stdlib.h> +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include <memory.h> +# endif +# include <string.h> +#endif +#ifdef HAVE_STRINGS_H +# include <strings.h> +#endif +#ifdef HAVE_INTTYPES_H +# include <inttypes.h> +#endif +#ifdef HAVE_STDINT_H +# include <stdint.h> +#endif +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif" + +ac_subst_vars='am__EXEEXT_FALSE +am__EXEEXT_TRUE +LTLIBOBJS +CONFIG_SHELL +WARN_CFLAGS +INCLIST +ENABLE_STATIC +DEBUG_ENABLED +ac_aux_dir +CLexe +GDexe +AGexe +CLnam +GDnam +AGnam +M4_SRC +LIBOBJS +SUBDIR_SNPRINTFV_FALSE +SUBDIR_SNPRINTFV_TRUE +CONVENIENCE_SNPRINTFV_FALSE +CONVENIENCE_SNPRINTFV_TRUE +INSTALL_SNPRINTFV_FALSE +INSTALL_SNPRINTFV_TRUE +INCSNPRINTFV +LIBSNPRINTFV +POSIX_SHELL +GL_GENERATE_STDNORETURN_H_FALSE +GL_GENERATE_STDNORETURN_H_TRUE +STDNORETURN_H +GUILE_LDFLAGS +GUILE_LTLIBS +HOST_CPU_C_ABI +HOST_CPU +GUILE_LIBS +GUILE_CFLAGS +GUILE_EFFECTIVE_VERSION +PKG_CONFIG_LIBDIR +PKG_CONFIG_PATH +PKG_CONFIG +AG_LDFLAGS +AG_TIMEOUT +HAVE_XML_LIB_FALSE +HAVE_XML_LIB_TRUE +AG_XML2 +LIBXML2_LIBS +LIBXML2_CFLAGS +AG_STATIC_AUTOGEN +DO_SHELL_CMDS_FALSE +DO_SHELL_CMDS_TRUE +AGEN5_TESTS +OPTS_TESTDIR +DYNAMIC_AG +NEED_PATHFIND_FALSE +NEED_PATHFIND_TRUE +TEXI2HTML +GO_AGE +GO_REVISION +GO_CURRENT +AO_TEMPLATE_VERSION +AO_AGE +AO_REVISION +AO_CURRENT +AG_MINOR_VERSION +AG_MAJOR_VERSION +AG_VERSION +LT_SYS_LIBRARY_PATH +OTOOL64 +OTOOL +LIPO +NMEDIT +DSYMUTIL +MANIFEST_TOOL +RANLIB +ac_ct_AR +AR +LN_S +NM +ac_ct_DUMPBIN +DUMPBIN +LD +FGREP +SED +LIBTOOL +OBJDUMP +DLLTOOL +AS +EGREP +GREP +CPP +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +am__nodep +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__include +DEPDIR +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +AM_BACKSLASH +AM_DEFAULT_VERBOSITY +AM_DEFAULT_V +AM_V +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +target_os +target_vendor +target_cpu +target +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_URL +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL +am__quote' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_silent_rules +enable_dependency_tracking +enable_shared +enable_static +with_pic +enable_fast_install +with_aix_soname +with_gnu_ld +with_sysroot +enable_libtool_lock +with_dmalloc +enable_shell +enable_static_autogen +with_libxml2 +with_libxml2_cflags +with_libxml2_libs +enable_timeout +enable_debug +with_packager +with_packager_version +with_packager_bug_reports +enable_rpath +enable_nls +with_regex_header +with_libregex +with_libregex_cflags +with_libregex_libs +enable_optional_args +enable_snprintfv_install +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CPP +LT_SYS_LIBRARY_PATH +PKG_CONFIG +PKG_CONFIG_PATH +PKG_CONFIG_LIBDIR +GUILE_CFLAGS +GUILE_LIBS' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +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=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *=) ac_optarg= ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -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_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$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 ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid feature name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$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 | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$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 ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + 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 | -n) + 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 ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$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_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + as_fn_error $? "invalid package name: $ac_useropt" + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=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 ;; + + -*) as_fn_error $? "unrecognized option: \`$ac_option' +Try \`$0 --help' for more information" + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + case $ac_envvar in #( + '' | [0-9]* | *[!_$as_cr_alnum]* ) + as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; + esac + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + as_fn_error $? "missing argument to $ac_option" +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + as_fn_error $? "working directory cannot be determined" +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + as_fn_error $? "pwd does not report name of working directory" + + +# 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 the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + 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 + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # 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 <<_ACEOF +\`configure' configures GNU AutoGen 5.18.16 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking ...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/autogen] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --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 + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] + --target=TARGET configure for building compilers for TARGET [HOST] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of GNU AutoGen 5.18.16:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-silent-rules less verbose build output (undo: "make V=1") + --disable-silent-rules verbose build output (undo: "make V=0") + --enable-dependency-tracking + do not reject slow dependency extractors + --disable-dependency-tracking + speeds up one-time build + --enable-shared[=PKGS] build shared libraries [default=yes] + --enable-static[=PKGS] build static libraries [default=yes] + --enable-fast-install[=PKGS] + optimize for fast installation [default=yes] + --disable-libtool-lock avoid locking (might break parallel builds) + --disable-shell shell scripts are desired + --enable-static-autogen statically link autogen to libopts + --enable-timeout specify an autogen timeout + --enable-debug wanting autogen debugging + --disable-rpath do not hardcode runtime library paths + --disable-nls disable nls support in libopts + --disable-optional-args not wanting optional option args + --enable-snprintfv-install install libsnprintfv yes + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use + both] + --with-aix-soname=aix|svr4|both + shared library versioning (aka "SONAME") variant to + provide on AIX, [default=aix]. + --with-gnu-ld assume the C compiler uses GNU ld [default=no] + --with-sysroot[=DIR] Search for dependent libraries within DIR (or the + compiler's sysroot if not specified). + --with-dmalloc use dmalloc, as in http://www.dmalloc.com + --with-libxml2 libxml2 installation prefix + --with-libxml2-cflags libxml2 compile flags + --with-libxml2-libs libxml2 link command arguments + --with-packager name of the packager of this software is supplied + --with-packager-version packager-specific version information is supplied + --with-packager-bug-reports + bug reporting URI/e-mail/etc. is supplied + --with-gnu-ld assume the C compiler uses GNU ld [default=no] + --with-regex-header a reg expr header is specified + --with-libregex libregex installation prefix + --with-libregex-cflags libregex compile flags + --with-libregex-libs libregex link command arguments + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a + nonstandard directory <lib dir> + LIBS libraries to pass to the linker, e.g. -l<library> + CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if + you have headers in a nonstandard directory <include dir> + CPP C preprocessor + LT_SYS_LIBRARY_PATH + User-defined run-time library search path. + PKG_CONFIG path to pkg-config utility + PKG_CONFIG_PATH + directories to add to pkg-config's search path + PKG_CONFIG_LIBDIR + path overriding pkg-config's built-in search path + GUILE_CFLAGS + C compiler flags for GUILE, overriding pkg-config + GUILE_LIBS linker flags for GUILE, overriding pkg-config + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to <autogen-users@lists.sourceforge.net>. +GNU AutoGen home page: <http://www.gnu.org/software/autogen/>. +General help using GNU software: <http://www.gnu.org/gethelp/>. +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +GNU AutoGen configure 5.18.16 +generated by GNU Autoconf 2.69 + +Copyright (C) 2012 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi + +## ------------------------ ## +## Autoconf initialization. ## +## ------------------------ ## + +# ac_fn_c_try_compile LINENO +# -------------------------- +# Try to compile conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext + if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_compile + +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_c_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval \${$3+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} +( $as_echo "## -------------------------------------------------- ## +## Report this to autogen-users@lists.sourceforge.net ## +## -------------------------------------------------- ##" + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_mongrel + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + +# ac_fn_c_try_link LINENO +# ----------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_link () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + rm -f conftest.$ac_objext conftest$ac_exeext + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + test -x conftest$ac_exeext + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information + # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would + # interfere with the next link command; also delete a directory that is + # left behind by Apple's compiler. We do this before executing the actions. + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_link + +# ac_fn_c_check_func LINENO FUNC VAR +# ---------------------------------- +# Tests whether FUNC exists, setting the cache variable VAR accordingly +ac_fn_c_check_func () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Define $2 to an innocuous variant, in case <limits.h> declares $2. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define $2 innocuous_$2 + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $2 (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + +#undef $2 + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $2 (); +/* 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_$2 || defined __stub___$2 +choke me +#endif + +int +main () +{ +return $2 (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_func + +# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES +# --------------------------------------------- +# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR +# accordingly. +ac_fn_c_check_decl () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + as_decl_name=`echo $2|sed 's/ *(.*//'` + as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 +$as_echo_n "checking whether $as_decl_name is declared... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +#ifndef $as_decl_name +#ifdef __cplusplus + (void) $as_decl_use; +#else + (void) $as_decl_name; +#endif +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_decl + +# ac_fn_c_check_type LINENO TYPE VAR INCLUDES +# ------------------------------------------- +# Tests whether TYPE exists after having included INCLUDES, setting cache +# variable VAR accordingly. +ac_fn_c_check_type () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=no" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof ($2)) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +if (sizeof (($2))) + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + eval "$3=yes" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_type + +# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES +# -------------------------------------------- +# Tries to find the compile-time value of EXPR in a program that includes +# INCLUDES, setting VAR accordingly. Returns whether the value could be +# computed +ac_fn_c_compute_int () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) >= 0)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_lo=0 ac_mid=0 + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) <= $ac_mid)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_hi=$ac_mid; break +else + as_fn_arith $ac_mid + 1 && ac_lo=$as_val + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) < 0)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_hi=-1 ac_mid=-1 + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) >= $ac_mid)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_lo=$ac_mid; break +else + as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + ac_lo= ac_hi= +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +# Binary search between lo and hi bounds. +while test "x$ac_lo" != "x$ac_hi"; do + as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) <= $ac_mid)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_hi=$ac_mid +else + as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in #(( +?*) eval "$3=\$ac_lo"; ac_retval=0 ;; +'') ac_retval=1 ;; +esac + else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +static long int longval () { return $2; } +static unsigned long int ulongval () { return $2; } +#include <stdio.h> +#include <stdlib.h> +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + return 1; + if (($2) < 0) + { + long int i = longval (); + if (i != ($2)) + return 1; + fprintf (f, "%ld", i); + } + else + { + unsigned long int i = ulongval (); + if (i != ($2)) + return 1; + fprintf (f, "%lu", i); + } + /* Do not output a trailing newline, as this causes \r\n confusion + on some platforms. */ + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + echo >>conftest.val; read $3 <conftest.val; ac_retval=0 +else + ac_retval=1 +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +rm -f conftest.val + + fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_compute_int + +# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES +# ---------------------------------------------------- +# Tries to find if the field MEMBER exists in type AGGR, after including +# INCLUDES, setting cache variable VAR accordingly. +ac_fn_c_check_member () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5 +$as_echo_n "checking for $2.$3... " >&6; } +if eval \${$4+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$5 +int +main () +{ +static $2 ac_aggr; +if (ac_aggr.$3) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$4=yes" +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$5 +int +main () +{ +static $2 ac_aggr; +if (sizeof ac_aggr.$3) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$4=yes" +else + eval "$4=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$4 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_member +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by GNU AutoGen $as_me 5.18.16, which was +generated by GNU Autoconf 2.69. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" + done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; + 2) + as_fn_append ac_configure_args1 " '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + as_fn_append ac_configure_args " '$ac_arg'" + ;; + esac + done +done +{ ac_configure_args0=; unset ac_configure_args0;} +{ ac_configure_args1=; unset ac_configure_args1;} + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + $as_echo "## ---------------- ## +## Cache variables. ## +## ---------------- ##" + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + $as_echo "## ----------------- ## +## Output variables. ## +## ----------------- ##" + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + $as_echo "## ------------------- ## +## File substitutions. ## +## ------------------- ##" + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + $as_echo "## ----------- ## +## confdefs.h. ## +## ----------- ##" + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +$as_echo "/* confdefs.h */" > confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_URL "$PACKAGE_URL" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + # We do not want a PATH search for config.site. + case $CONFIG_SITE in #(( + -*) ac_site_file1=./$CONFIG_SITE;; + */*) ac_site_file1=$CONFIG_SITE;; + *) ac_site_file1=./$CONFIG_SITE;; + esac +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" \ + || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "failed to load site script $ac_site_file +See \`config.log' for more details" "$LINENO" 5; } + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special files + # actually), so we avoid doing that. DJGPP emulates it as a regular file. + if test /dev/null != "$cache_file" && test -f "$cache_file"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) as_fn_append ac_configure_args " '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 +fi +## -------------------- ## +## Main body of script. ## +## -------------------- ## + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +ac_aux_dir= +for ac_dir in config "$srcdir"/config; 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 + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + as_fn_error $? "cannot find install-sh, install.sh, or shtool in config \"$srcdir\"/config" "$LINENO" 5 +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if ${ac_cv_build+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if ${ac_cv_host+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5 +$as_echo_n "checking target system type... " >&6; } +if ${ac_cv_target+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$target_alias" = x; then + ac_cv_target=$ac_cv_host +else + ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5 +$as_echo "$ac_cv_target" >&6; } +case $ac_cv_target in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;; +esac +target=$ac_cv_target +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_target +shift +target_cpu=$1 +target_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +target_os=$* +IFS=$ac_save_IFS +case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac + + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +test -n "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- +. $srcdir/VERSION +d=`dirname $0` +ag_top_srcdir=`cd $d && pwd` +ag_top_builddir=`pwd` +am__api_version='1.16' + +# 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 +# AmigaOS /C/install, which installs bootblocks on floppy discs +# 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" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /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 + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +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. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&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}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; +esac + +# 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 ( + am_has_slept=no + for am_try in 1 2; do + echo "timestamp, slept: $am_has_slept" > conftest.file + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $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". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken + alias in your environment" "$LINENO" 5 + fi + if test "$2" = conftest.file || test $am_try -eq 2; then + break + fi + # Just in case. + sleep 1 + am_has_slept=yes + done + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +# If we didn't sleep, we still need to ensure time stamps of config.status and +# generated files are strictly newer. +am_sleep_pid= +if grep 'slept: no' conftest.file >/dev/null 2>&1; then + ( sleep 1 ) & + am_sleep_pid=$! +fi + +rm -f conftest.file + +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" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# Expand $ac_aux_dir to an absolute path. +am_aux_dir=`cd "$ac_aux_dir" && pwd` + +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --is-lightweight"; then + am_missing_run="$MISSING " +else + am_missing_run= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using 'strip' when the user +# run "make install-strip". However 'strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the 'STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if ${ac_cv_path_mkdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +for ac_prog in gawk mawk 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 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +# Check whether --enable-silent-rules was given. +if test "${enable_silent_rules+set}" = set; then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in # ((( + yes) AM_DEFAULT_VERBOSITY=0;; + no) AM_DEFAULT_VERBOSITY=1;; + *) AM_DEFAULT_VERBOSITY=1;; +esac +am_make=${MAKE-make} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +$as_echo_n "checking whether $am_make supports nested variables... " >&6; } +if ${am_cv_make_support_nested_variables+:} false; then : + $as_echo_n "(cached) " >&6 +else + if $as_echo 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +$as_echo "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='autogen' + VERSION='5.18.16' + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# For better backward compatibility. To be removed once Automake 1.9.x +# dies out for good. For more background, see: +# <https://lists.gnu.org/archive/html/automake/2012-07/msg00001.html> +# <https://lists.gnu.org/archive/html/automake/2012-07/msg00014.html> +mkdir_p='$(MKDIR_P)' + +# We need awk for the "check" target (and possibly the TAP driver). The +# system "awk" is bad on some platforms. +# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AMTAR='$${TAR-tar}' + + +# We'll loop over all known methods to create a tar archive until one works. +_am_tools='gnutar pax cpio none' + +am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' + + + + + + +# POSIX will say in a future version that running "rm -f" with no argument +# is OK; and we want to be able to make that assumption in our Makefile +# recipes. So use an aggressive probe to check that the usage we want is +# actually supported "in the wild" to an acceptable degree. +# See automake bug#10828. +# To make any issue more visible, cause the running configure to be aborted +# by default if the 'rm' program in use doesn't match our expectations; the +# user can still override this though. +if rm -f && rm -fr && rm -rf; then : OK; else + cat >&2 <<'END' +Oops! + +Your 'rm' program seems unable to run without file operands specified +on the command line, even when the '-f' option is present. This is contrary +to the behaviour of most rm programs out there, and not conforming with +the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542> + +Please tell bug-automake@gnu.org about your system, including the value +of your $PATH and any error possibly output before this message. This +can help us improve future automake versions. + +END + if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then + echo 'Configuration will proceed anyway, since you have set the' >&2 + echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 + echo >&2 + else + cat >&2 <<'END' +Aborting the configuration process, to ensure you take notice of the issue. + +You can download and install GNU coreutils to get an 'rm' implementation +that behaves properly: <https://www.gnu.org/software/coreutils/>. + +If you want to complete the configuration process using your problematic +'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM +to "yes", and re-run configure. + +END + as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 + fi +fi + +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5 +$as_echo_n "checking whether ${MAKE-make} supports the include directive... " >&6; } +cat > confinc.mk << 'END' +am__doit: + @echo this is the am__doit target >confinc.out +.PHONY: am__doit +END +am__include="#" +am__quote= +# BSD make does it like this. +echo '.include "confinc.mk" # ignored' > confmf.BSD +# Other make implementations (GNU, Solaris 10, AIX) do it like this. +echo 'include confinc.mk # ignored' > confmf.GNU +_am_result=no +for s in GNU BSD; do + { echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5 + (${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + case $?:`cat confinc.out 2>/dev/null` in #( + '0:this is the am__doit target') : + case $s in #( + BSD) : + am__include='.include' am__quote='"' ;; #( + *) : + am__include='include' am__quote='' ;; +esac ;; #( + *) : + ;; +esac + if test "$am__include" != "#"; then + _am_result="yes ($s style)" + break + fi +done +rm -f confinc.* confmf.* +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5 +$as_echo "${_am_result}" >&6; } + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +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 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_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 $# != 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 + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_CC+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "no acceptable C compiler found in \$PATH +See \`config.log' for more details" "$LINENO" 5; } + +# Provide some information about the compiler. +$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +for ac_option in --version -v -V -qversion; do + { { ac_try="$ac_compiler $ac_option >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compiler $ac_option >&5") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + sed '10a\ +... rest of stderr output deleted ... + 10q' conftest.err >conftest.er1 + cat conftest.er1 >&5 + fi + rm -f conftest.er1 conftest.err + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } +done + +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { { ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi +if test -z "$ac_file"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "C compiler cannot create executables +See \`config.log' for more details" "$LINENO" 5; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +ac_exeext=$ac_cv_exeext + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest conftest$ac_cv_exeext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdio.h> +int +main () +{ +FILE *f = fopen ("conftest.out", "w"); + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +ac_clean_files="$ac_clean_files conftest.out" +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +if test "$cross_compiling" != yes; then + { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if { ac_try='./conftest$ac_cv_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details" "$LINENO" 5; } + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out +ac_clean_files=$ac_clean_files_save +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if ${ac_cv_objext+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { { ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then : + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot compute suffix of object files: cannot compile +See \`config.log' for more details" "$LINENO" 5; } +fi +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if ${ac_cv_c_compiler_gnu+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_compiler_gnu=yes +else + ac_compiler_gnu=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if ${ac_cv_prog_cc_g+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +else + CFLAGS="" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_g=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&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 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdarg.h> +#include <stdio.h> +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 +$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } +if ${am_cv_prog_cc_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF + # Make sure it works both with $CC and with simple cc. + # Following AC_PROG_CC_C_O, we do the test twice because some + # compilers refuse to overwrite an existing .o file with -o, + # though they will create one. + am_cv_prog_cc_c_o=yes + for am_i in 1 2; do + if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 + ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } \ + && test -f conftest2.$ac_objext; then + : OK + else + am_cv_prog_cc_c_o=no + break + fi + done + rm -f core conftest* + unset am_i +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 +$as_echo "$am_cv_prog_cc_c_o" >&6; } +if test "$am_cv_prog_cc_c_o" != yes; then + # Losing compiler, so override with the script. + # FIXME: It is wrong to rewrite CC. + # But if we don't then we get into trouble of one sort or another. + # A longer-term fix would be to have automake use am__CC in this case, + # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" + CC="$am_aux_dir/compile $CC" +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named 'D' -- because '-MD' means "put the output + # in D". + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with + # Solaris 10 /bin/sh. + echo '/* dummy */' > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with '-c' and '-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle '-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs. + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # After this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested. + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok '-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + # <limits.h> exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ac_nonexistent.h> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <float.h> + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <string.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + 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 confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdlib.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + 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 confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <ctype.h> +#include <stdlib.h> +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#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)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default" +if test "x$ac_cv_header_minix_config_h" = xyes; then : + MINIX=yes +else + MINIX= +fi + + + if test "$MINIX" = yes; then + +$as_echo "#define _POSIX_SOURCE 1" >>confdefs.h + + +$as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h + + +$as_echo "#define _MINIX 1" >>confdefs.h + + +$as_echo "#define _NETBSD_SOURCE 1" >>confdefs.h + + fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5 +$as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; } +if ${ac_cv_safe_to_define___extensions__+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +# define __EXTENSIONS__ 1 + $ac_includes_default +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_safe_to_define___extensions__=yes +else + ac_cv_safe_to_define___extensions__=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5 +$as_echo "$ac_cv_safe_to_define___extensions__" >&6; } + test $ac_cv_safe_to_define___extensions__ = yes && + $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h + + $as_echo "#define _ALL_SOURCE 1" >>confdefs.h + + $as_echo "#define _DARWIN_C_SOURCE 1" >>confdefs.h + + $as_echo "#define _GNU_SOURCE 1" >>confdefs.h + + $as_echo "#define _NETBSD_SOURCE 1" >>confdefs.h + + $as_echo "#define _OPENBSD_SOURCE 1" >>confdefs.h + + $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h + + $as_echo "#define __STDC_WANT_IEC_60559_ATTRIBS_EXT__ 1" >>confdefs.h + + $as_echo "#define __STDC_WANT_IEC_60559_BFP_EXT__ 1" >>confdefs.h + + $as_echo "#define __STDC_WANT_IEC_60559_DFP_EXT__ 1" >>confdefs.h + + $as_echo "#define __STDC_WANT_IEC_60559_FUNCS_EXT__ 1" >>confdefs.h + + $as_echo "#define __STDC_WANT_IEC_60559_TYPES_EXT__ 1" >>confdefs.h + + $as_echo "#define __STDC_WANT_LIB_EXT2__ 1" >>confdefs.h + + $as_echo "#define __STDC_WANT_MATH_SPEC_FUNCS__ 1" >>confdefs.h + + $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether _XOPEN_SOURCE should be defined" >&5 +$as_echo_n "checking whether _XOPEN_SOURCE should be defined... " >&6; } +if ${ac_cv_should_define__xopen_source+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_should_define__xopen_source=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include <wchar.h> + mbstate_t x; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #define _XOPEN_SOURCE 500 + #include <wchar.h> + mbstate_t x; +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_should_define__xopen_source=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_should_define__xopen_source" >&5 +$as_echo "$ac_cv_should_define__xopen_source" >&6; } + test $ac_cv_should_define__xopen_source = yes && + $as_echo "#define _XOPEN_SOURCE 500" >>confdefs.h + + $as_echo "#define _HPUX_ALT_XOPEN_SOCKET_API 1" >>confdefs.h + + + +enable_win32_dll=yes + +case $host in +*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. +set dummy ${ac_tool_prefix}as; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AS+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AS"; then + ac_cv_prog_AS="$AS" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AS="${ac_tool_prefix}as" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AS=$ac_cv_prog_AS +if test -n "$AS"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AS" >&5 +$as_echo "$AS" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_AS"; then + ac_ct_AS=$AS + # Extract the first word of "as", so it can be a program name with args. +set dummy as; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AS+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AS"; then + ac_cv_prog_ac_ct_AS="$ac_ct_AS" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AS="as" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AS=$ac_cv_prog_ac_ct_AS +if test -n "$ac_ct_AS"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AS" >&5 +$as_echo "$ac_ct_AS" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_AS" = x; then + AS="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AS=$ac_ct_AS + fi +else + AS="$ac_cv_prog_AS" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. +set dummy ${ac_tool_prefix}dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DLLTOOL=$ac_cv_prog_DLLTOOL +if test -n "$DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 +$as_echo "$DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DLLTOOL"; then + ac_ct_DLLTOOL=$DLLTOOL + # Extract the first word of "dlltool", so it can be a program name with args. +set dummy dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DLLTOOL"; then + ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DLLTOOL="dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL +if test -n "$ac_ct_DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 +$as_echo "$ac_ct_DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DLLTOOL" = x; then + DLLTOOL="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DLLTOOL=$ac_ct_DLLTOOL + fi +else + DLLTOOL="$ac_cv_prog_DLLTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +$as_echo "$OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +$as_echo "$ac_ct_OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + + ;; +esac + +test -z "$AS" && AS=as + + + + + +test -z "$DLLTOOL" && DLLTOOL=dlltool + + + + + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + + + +case `pwd` in + *\ * | *\ *) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 +$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; +esac + + + +macro_version='2.4.6' +macro_revision='2.4.6' + + + + + + + + + + + + + +ltmain=$ac_aux_dir/ltmain.sh + +# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 +$as_echo_n "checking how to print strings... " >&6; } +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "" +} + +case $ECHO in + printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 +$as_echo "printf" >&6; } ;; + print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 +$as_echo "print -r" >&6; } ;; + *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 +$as_echo "cat" >&6; } ;; +esac + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +$as_echo_n "checking for a sed that does not truncate output... " >&6; } +if ${ac_cv_path_SED+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_SED" || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +$as_echo "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 +$as_echo_n "checking for fgrep... " >&6; } +if ${ac_cv_path_FGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 + then ac_cv_path_FGREP="$GREP -F" + else + if test -z "$FGREP"; then + ac_path_FGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in fgrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_FGREP" || continue +# Check for GNU ac_path_FGREP and select it if it is found. + # Check for GNU $ac_path_FGREP +case `"$ac_path_FGREP" --version 2>&1` in +*GNU*) + ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'FGREP' >> "conftest.nl" + "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_FGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_FGREP="$ac_path_FGREP" + ac_path_FGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_FGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_FGREP"; then + as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_FGREP=$FGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 +$as_echo "$ac_cv_path_FGREP" >&6; } + FGREP="$ac_cv_path_FGREP" + + +test -z "$GREP" && GREP=grep + + + + + + + + + + + + + + + + + + + +# Check whether --with-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then : + withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test yes = "$GCC"; then + # Check if gcc -print-prog-name=ld gives a path. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return, which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname 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 yes = "$with_gnu_ld"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if ${lt_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$LD"; then + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD=$ac_dir/$ac_prog + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in + *GNU* | *'with BFD'*) + test no != "$with_gnu_ld" && break + ;; + *) + test yes != "$with_gnu_ld" && break + ;; + esac + fi + done + IFS=$lt_save_ifs +else + lt_cv_path_LD=$LD # Let the user override the test with a path. +fi +fi + +LD=$lt_cv_path_LD +if test -n "$LD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${lt_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 </dev/null` in +*GNU* | *'with BFD'*) + lt_cv_prog_gnu_ld=yes + ;; +*) + lt_cv_prog_gnu_ld=no + ;; +esac +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5 +$as_echo "$lt_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$lt_cv_prog_gnu_ld + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 +$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } +if ${lt_cv_path_NM+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM=$NM +else + lt_nm_to_check=${ac_tool_prefix}nm + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + tmp_nm=$ac_dir/$lt_tmp_nm + if test -f "$tmp_nm" || test -f "$tmp_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 + # Tru64's nm complains that /dev/null is an invalid object file + # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty + case $build_os in + mingw*) lt_bad_file=conftest.nm/nofile ;; + *) lt_bad_file=/dev/null ;; + esac + case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in + *$lt_bad_file* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break 2 + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break 2 + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS=$lt_save_ifs + done + : ${lt_cv_path_NM=no} +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 +$as_echo "$lt_cv_path_NM" >&6; } +if test no != "$lt_cv_path_NM"; then + NM=$lt_cv_path_NM +else + # Didn't find any BSD compatible name lister, look for dumpbin. + if test -n "$DUMPBIN"; then : + # Let the user override the test. + else + if test -n "$ac_tool_prefix"; then + for ac_prog in dumpbin "link -dump" + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DUMPBIN"; then + ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DUMPBIN=$ac_cv_prog_DUMPBIN +if test -n "$DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 +$as_echo "$DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$DUMPBIN" && break + done +fi +if test -z "$DUMPBIN"; then + ac_ct_DUMPBIN=$DUMPBIN + for ac_prog in dumpbin "link -dump" +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DUMPBIN"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN +if test -n "$ac_ct_DUMPBIN"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 +$as_echo "$ac_ct_DUMPBIN" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_DUMPBIN" && break +done + + if test "x$ac_ct_DUMPBIN" = x; then + DUMPBIN=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DUMPBIN=$ac_ct_DUMPBIN + fi +fi + + case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in + *COFF*) + DUMPBIN="$DUMPBIN -symbols -headers" + ;; + *) + DUMPBIN=: + ;; + esac + fi + + if test : != "$DUMPBIN"; then + NM=$DUMPBIN + fi +fi +test -z "$NM" && NM=nm + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 +$as_echo_n "checking the name lister ($NM) interface... " >&6; } +if ${lt_cv_nm_interface+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_nm_interface="BSD nm" + echo "int some_variable = 0;" > conftest.$ac_ext + (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) + (eval "$ac_compile" 2>conftest.err) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) + cat conftest.err >&5 + (eval echo "\"\$as_me:$LINENO: output\"" >&5) + cat conftest.out >&5 + if $GREP 'External.*some_variable' conftest.out > /dev/null; then + lt_cv_nm_interface="MS dumpbin" + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 +$as_echo "$lt_cv_nm_interface" >&6; } + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi + +# find the maximum length of command line arguments +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 +$as_echo_n "checking the maximum length of command line arguments... " >&6; } +if ${lt_cv_sys_max_cmd_len+:} false; then : + $as_echo_n "(cached) " >&6 +else + i=0 + teststring=ABCD + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw* | cegcc*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + mint*) + # On MiNT this can take a long time and run out of memory. + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + os2*) + # The test takes a long time on OS/2. + lt_cv_sys_max_cmd_len=8192 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len" && \ + test undefined != "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + # Make teststring a little bigger before we do anything with it. + # a 1K string should be a reasonable start. + for i in 1 2 3 4 5 6 7 8; do + teststring=$teststring$teststring + done + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + while { test X`env echo "$teststring$teststring" 2>/dev/null` \ + = "X$teststring$teststring"; } >/dev/null 2>&1 && + test 17 != "$i" # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + # Only check the string length outside the loop. + lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` + teststring= + # Add a significant safety factor because C++ compilers can tack on + # massive amounts of additional arguments before passing them to the + # linker. It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi + ;; + esac + +fi + +if test -n "$lt_cv_sys_max_cmd_len"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 +$as_echo "$lt_cv_sys_max_cmd_len" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 +$as_echo "none" >&6; } +fi +max_cmd_len=$lt_cv_sys_max_cmd_len + + + + + + +: ${CP="cp -f"} +: ${MV="mv -f"} +: ${RM="rm -f"} + +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + lt_unset=unset +else + lt_unset=false +fi + + + + + +# test EBCDIC or ASCII +case `echo X|tr X '\101'` in + A) # ASCII based system + # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr + lt_SP2NL='tr \040 \012' + lt_NL2SP='tr \015\012 \040\040' + ;; + *) # EBCDIC based system + lt_SP2NL='tr \100 \n' + lt_NL2SP='tr \r\n \100\100' + ;; +esac + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 +$as_echo_n "checking how to convert $build file names to $host format... " >&6; } +if ${lt_cv_to_host_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 + ;; + esac + ;; + *-*-cygwin* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin + ;; + *-*-cygwin* ) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; + * ) # otherwise, assume *nix + lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin + ;; + esac + ;; + * ) # unhandled hosts (and "normal" native builds) + lt_cv_to_host_file_cmd=func_convert_file_noop + ;; +esac + +fi + +to_host_file_cmd=$lt_cv_to_host_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 +$as_echo "$lt_cv_to_host_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 +$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } +if ${lt_cv_to_tool_file_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + #assume ordinary cross tools, or native build. +lt_cv_to_tool_file_cmd=func_convert_file_noop +case $host in + *-*-mingw* ) + case $build in + *-*-mingw* ) # actually msys + lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 + ;; + esac + ;; +esac + +fi + +to_tool_file_cmd=$lt_cv_to_tool_file_cmd +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 +$as_echo "$lt_cv_to_tool_file_cmd" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 +$as_echo_n "checking for $LD option to reload object files... " >&6; } +if ${lt_cv_ld_reload_flag+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_reload_flag='-r' +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 +$as_echo "$lt_cv_ld_reload_flag" >&6; } +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + if test yes != "$GCC"; then + reload_cmds=false + fi + ;; + darwin*) + if test yes = "$GCC"; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. +set dummy ${ac_tool_prefix}objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJDUMP"; then + ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJDUMP=$ac_cv_prog_OBJDUMP +if test -n "$OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 +$as_echo "$OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJDUMP"; then + ac_ct_OBJDUMP=$OBJDUMP + # Extract the first word of "objdump", so it can be a program name with args. +set dummy objdump; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJDUMP"; then + ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OBJDUMP="objdump" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP +if test -n "$ac_ct_OBJDUMP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 +$as_echo "$ac_ct_OBJDUMP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJDUMP" = x; then + OBJDUMP="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJDUMP=$ac_ct_OBJDUMP + fi +else + OBJDUMP="$ac_cv_prog_OBJDUMP" +fi + +test -z "$OBJDUMP" && OBJDUMP=objdump + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 +$as_echo_n "checking how to recognize dependent libraries... " >&6; } +if ${lt_cv_deplibs_check_method+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# 'unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# that responds to the $file_magic_cmd with a given extended regex. +# If you have 'file' or equivalent on your system and you're not sure +# whether 'pass_all' will *always* work, you probably want this one. + +case $host_os in +aix[4-9]*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[45]*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + if ( file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + # Keep this pattern in sync with the one in func_win32_libid. + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi + ;; + +cegcc*) + # use the weaker test based on 'objdump'. See mingw*. + lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +haiku*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix[3-9]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +*nto* | *qnx*) + lt_cv_deplibs_check_method=pass_all + ;; + +openbsd* | bitrig*) + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +rdos*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +tpf*) + lt_cv_deplibs_check_method=pass_all + ;; +os2*) + lt_cv_deplibs_check_method=pass_all + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 +$as_echo "$lt_cv_deplibs_check_method" >&6; } + +file_magic_glob= +want_nocaseglob=no +if test "$build" = "$host"; then + case $host_os in + mingw* | pw32*) + if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then + want_nocaseglob=yes + else + file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` + fi + ;; + esac +fi + +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown + + + + + + + + + + + + + + + + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. +set dummy ${ac_tool_prefix}dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DLLTOOL"; then + ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DLLTOOL=$ac_cv_prog_DLLTOOL +if test -n "$DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 +$as_echo "$DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DLLTOOL"; then + ac_ct_DLLTOOL=$DLLTOOL + # Extract the first word of "dlltool", so it can be a program name with args. +set dummy dlltool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DLLTOOL"; then + ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DLLTOOL="dlltool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL +if test -n "$ac_ct_DLLTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 +$as_echo "$ac_ct_DLLTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DLLTOOL" = x; then + DLLTOOL="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DLLTOOL=$ac_ct_DLLTOOL + fi +else + DLLTOOL="$ac_cv_prog_DLLTOOL" +fi + +test -z "$DLLTOOL" && DLLTOOL=dlltool + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 +$as_echo_n "checking how to associate runtime and link libraries... " >&6; } +if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_sharedlib_from_linklib_cmd='unknown' + +case $host_os in +cygwin* | mingw* | pw32* | cegcc*) + # two different shell functions defined in ltmain.sh; + # decide which one to use based on capabilities of $DLLTOOL + case `$DLLTOOL --help 2>&1` in + *--identify-strict*) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib + ;; + *) + lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback + ;; + esac + ;; +*) + # fallback: assume linklib IS sharedlib + lt_cv_sharedlib_from_linklib_cmd=$ECHO + ;; +esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 +$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } +sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd +test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO + + + + + + + +if test -n "$ac_tool_prefix"; then + for ac_prog in ar + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AR"; then + ac_cv_prog_AR="$AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AR="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AR=$ac_cv_prog_AR +if test -n "$AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 +$as_echo "$AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AR" && break + done +fi +if test -z "$AR"; then + ac_ct_AR=$AR + for ac_prog in ar +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_AR+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_AR"; then + ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_AR="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_AR=$ac_cv_prog_ac_ct_AR +if test -n "$ac_ct_AR"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 +$as_echo "$ac_ct_AR" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_AR" && break +done + + if test "x$ac_ct_AR" = x; then + AR="false" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + AR=$ac_ct_AR + fi +fi + +: ${AR=ar} +: ${AR_FLAGS=cru} + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 +$as_echo_n "checking for archiver @FILE support... " >&6; } +if ${lt_cv_ar_at_file+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ar_at_file=no + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + echo conftest.$ac_objext > conftest.lst + lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test 0 -eq "$ac_status"; then + # Ensure the archiver fails upon bogus file names. + rm -f conftest.$ac_objext libconftest.a + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 + (eval $lt_ar_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + if test 0 -ne "$ac_status"; then + lt_cv_ar_at_file=@ + fi + fi + rm -f conftest.* libconftest.a + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 +$as_echo "$lt_cv_ar_at_file" >&6; } + +if test no = "$lt_cv_ar_at_file"; then + archiver_list_spec= +else + archiver_list_spec=$lt_cv_ar_at_file +fi + + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +test -z "$STRIP" && STRIP=: + + + + + + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +$as_echo "$RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +$as_echo "$ac_ct_RANLIB" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +test -z "$RANLIB" && RANLIB=: + + + + + + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + bitrig* | openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" +fi + +case $host_os in + darwin*) + lock_old_archive_extraction=yes ;; + *) + lock_old_archive_extraction=no ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + + +# Check for command to grab the raw symbol name followed by C symbol from nm. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 +$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } +if ${lt_cv_sys_global_symbol_pipe+:} false; then : + $as_echo_n "(cached) " >&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. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw* | pw32* | cegcc*) + symcode='[ABCDGISTW]' + ;; +hpux*) + if test ia64 = "$host_cpu"; then + symcode='[ABCDEGRST]' + fi + ;; +irix* | nonstopux*) + symcode='[BCDEGRST]' + ;; +osf*) + symcode='[BCDEGQRST]' + ;; +solaris*) + symcode='[BDRT]' + ;; +sco3.2v5*) + symcode='[DT]' + ;; +sysv4.2uw2*) + symcode='[DT]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[ABDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[ABCDGIRSTW]' ;; +esac + +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Gets list of data symbols to import. + lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" + # Adjust the below global symbol transforms to fixup imported variables. + lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" + lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" + lt_c_name_lib_hook="\ + -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ + -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" +else + # Disable hooks by default. + lt_cv_sys_global_symbol_to_import= + lt_cdecl_hook= + lt_c_name_hook= + lt_c_name_lib_hook= +fi + +# Transform an extracted symbol line into a proper C declaration. +# Some systems (esp. on ia64) link data and code symbols differently, +# so use this general approach. +lt_cv_sys_global_symbol_to_cdecl="sed -n"\ +$lt_cdecl_hook\ +" -e 's/^T .* \(.*\)$/extern int \1();/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ +$lt_c_name_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" + +# Transform an extracted symbol line into symbol name with lib prefix and +# symbol address. +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ +$lt_c_name_lib_hook\ +" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ +" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ +" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# Try without a prefix underscore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + if test "$lt_cv_nm_interface" = "MS dumpbin"; then + # Fake it for dumpbin and say T for any non-static function, + # D for any global variable and I for any imported variable. + # Also find C++ and __fastcall symbols from MSVC++, + # which start with @ or ?. + lt_cv_sys_global_symbol_pipe="$AWK '"\ +" {last_section=section; section=\$ 3};"\ +" /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ +" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ +" /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ +" /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ +" /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ +" \$ 0!~/External *\|/{next};"\ +" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ +" {if(hide[section]) next};"\ +" {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ +" {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ +" s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ +" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ +" ' prfx=^$ac_symprfx" + else + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + fi + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<_LT_EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(void); +void nm_test_func(void){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +_LT_EOF + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + # Now try to grab the symbols. + nlist=conftest.nm + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 + (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if $GREP ' nm_test_var$' "$nlist" >/dev/null; then + if $GREP ' nm_test_func$' "$nlist" >/dev/null; then + cat <<_LT_EOF > conftest.$ac_ext +/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ +#if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE +/* DATA imports from DLLs on WIN32 can't be const, because runtime + relocations are performed -- see ld's documentation on pseudo-relocs. */ +# define LT_DLSYM_CONST +#elif defined __osf__ +/* This system does not cope well with relocations in const data. */ +# define LT_DLSYM_CONST +#else +# define LT_DLSYM_CONST const +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +_LT_EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' + + cat <<_LT_EOF >> conftest.$ac_ext + +/* The mapping between symbol names and symbols. */ +LT_DLSYM_CONST struct { + const char *name; + void *address; +} +lt__PROGRAM__LTX_preloaded_symbols[] = +{ + { "@PROGRAM@", (void *) 0 }, +_LT_EOF + $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext + cat <<\_LT_EOF >> conftest.$ac_ext + {0, (void *) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt__PROGRAM__LTX_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif +_LT_EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_globsym_save_LIBS=$LIBS + lt_globsym_save_CFLAGS=$CFLAGS + LIBS=conftstm.$ac_objext + CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s conftest$ac_exeext; then + pipe_works=yes + fi + LIBS=$lt_globsym_save_LIBS + CFLAGS=$lt_globsym_save_CFLAGS + 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 $lt_cv_sys_global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + fi + rm -rf conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test yes = "$pipe_works"; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done + +fi + +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 +$as_echo "failed" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } +fi + +# Response file support. +if test "$lt_cv_nm_interface" = "MS dumpbin"; then + nm_file_list_spec='@' +elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then + nm_file_list_spec='@' +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 +$as_echo_n "checking for sysroot... " >&6; } + +# Check whether --with-sysroot was given. +if test "${with_sysroot+set}" = set; then : + withval=$with_sysroot; +else + with_sysroot=no +fi + + +lt_sysroot= +case $with_sysroot in #( + yes) + if test yes = "$GCC"; then + lt_sysroot=`$CC --print-sysroot 2>/dev/null` + fi + ;; #( + /*) + lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + ;; #( + no|'') + ;; #( + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5 +$as_echo "$with_sysroot" >&6; } + as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 + ;; +esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 +$as_echo "${lt_sysroot:-no}" >&6; } + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5 +$as_echo_n "checking for a working dd... " >&6; } +if ${ac_cv_path_lt_DD+:} false; then : + $as_echo_n "(cached) " >&6 +else + printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +: ${lt_DD:=$DD} +if test -z "$lt_DD"; then + ac_path_lt_DD_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in dd; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_lt_DD="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_lt_DD" || continue +if "$ac_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: +fi + $ac_path_lt_DD_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_lt_DD"; then + : + fi +else + ac_cv_path_lt_DD=$lt_DD +fi + +rm -f conftest.i conftest2.i conftest.out +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5 +$as_echo "$ac_cv_path_lt_DD" >&6; } + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5 +$as_echo_n "checking how to truncate binary pipes... " >&6; } +if ${lt_cv_truncate_bin+:} false; then : + $as_echo_n "(cached) " >&6 +else + printf 0123456789abcdef0123456789abcdef >conftest.i +cat conftest.i conftest.i >conftest2.i +lt_cv_truncate_bin= +if "$ac_cv_path_lt_DD" bs=32 count=1 <conftest2.i >conftest.out 2>/dev/null; then + cmp -s conftest.i conftest.out \ + && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" +fi +rm -f conftest.i conftest2.i conftest.out +test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q" +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5 +$as_echo "$lt_cv_truncate_bin" >&6; } + + + + + + + +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +func_cc_basename () +{ + for cc_temp in $*""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac + done + func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +} + +# Check whether --enable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then : + enableval=$enable_libtool_lock; +fi + +test no = "$enable_libtool_lock" || enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out what ABI is being produced by ac_compile, and set mode + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE=32 + ;; + *ELF-64*) + HPUX_IA64_MODE=64 + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + if test yes = "$lt_cv_prog_gnu_ld"; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +mips64*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo '#line '$LINENO' "configure"' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + emul=elf + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + emul="${emul}32" + ;; + *64-bit*) + emul="${emul}64" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *MSB*) + emul="${emul}btsmip" + ;; + *LSB*) + emul="${emul}ltsmip" + ;; + esac + case `/usr/bin/file conftest.$ac_objext` in + *N32*) + emul="${emul}n32" + ;; + esac + LD="${LD-ld} -m $emul" + fi + rm -rf conftest* + ;; + +x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ +s390*-*linux*|s390*-*tpf*|sparc*-*linux*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. Note that the listed cases only cover the + # situations where additional linker options are needed (such as when + # doing 32-bit compilation for a host where ld defaults to 64-bit, or + # vice versa); the common cases where no linker options are needed do + # not appear in the list. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; + x86_64-*linux*) + case `/usr/bin/file conftest.o` in + *x86-64*) + LD="${LD-ld} -m elf32_x86_64" + ;; + *) + LD="${LD-ld} -m elf_i386" + ;; + esac + ;; + powerpc64le-*linux*) + LD="${LD-ld} -m elf32lppclinux" + ;; + powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + powerpcle-*linux*) + LD="${LD-ld} -m elf64lppc" + ;; + powerpc-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*|s390*-*tpf*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + 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" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 +$as_echo_n "checking whether the C compiler needs -belf... " >&6; } +if ${lt_cv_cc_needs_belf+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_cc_needs_belf=yes +else + lt_cv_cc_needs_belf=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 +$as_echo "$lt_cv_cc_needs_belf" >&6; } + if test yes != "$lt_cv_cc_needs_belf"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS=$SAVE_CFLAGS + fi + ;; +*-*solaris*) + # Find out what ABI is being produced by ac_compile, and set linker + # options accordingly. + echo 'int i;' > conftest.$ac_ext + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) + case $host in + i?86-*-solaris*|x86_64-*-solaris*) + LD="${LD-ld} -m elf_x86_64" + ;; + sparc*-*-solaris*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + # GNU ld 2.21 introduced _sol2 emulations. Use them if available. + if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then + LD=${LD-ld}_sol2 + fi + ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; +esac + +need_locks=$enable_libtool_lock + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. +set dummy ${ac_tool_prefix}mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$MANIFEST_TOOL"; then + ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL +if test -n "$MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 +$as_echo "$MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_MANIFEST_TOOL"; then + ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL + # Extract the first word of "mt", so it can be a program name with args. +set dummy mt; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_MANIFEST_TOOL"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL +if test -n "$ac_ct_MANIFEST_TOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 +$as_echo "$ac_ct_MANIFEST_TOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_MANIFEST_TOOL" = x; then + MANIFEST_TOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL + fi +else + MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" +fi + +test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 +$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } +if ${lt_cv_path_mainfest_tool+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_path_mainfest_tool=no + echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 + $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out + cat conftest.err >&5 + if $GREP 'Manifest Tool' conftest.out > /dev/null; then + lt_cv_path_mainfest_tool=yes + fi + rm -f conftest* +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 +$as_echo "$lt_cv_path_mainfest_tool" >&6; } +if test yes != "$lt_cv_path_mainfest_tool"; then + MANIFEST_TOOL=: +fi + + + + + + + case $host_os in + rhapsody* | darwin*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. +set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$DSYMUTIL"; then + ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +DSYMUTIL=$ac_cv_prog_DSYMUTIL +if test -n "$DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 +$as_echo "$DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DSYMUTIL"; then + ac_ct_DSYMUTIL=$DSYMUTIL + # Extract the first word of "dsymutil", so it can be a program name with args. +set dummy dsymutil; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_DSYMUTIL"; then + ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL +if test -n "$ac_ct_DSYMUTIL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 +$as_echo "$ac_ct_DSYMUTIL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_DSYMUTIL" = x; then + DSYMUTIL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + DSYMUTIL=$ac_ct_DSYMUTIL + fi +else + DSYMUTIL="$ac_cv_prog_DSYMUTIL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. +set dummy ${ac_tool_prefix}nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$NMEDIT"; then + ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +NMEDIT=$ac_cv_prog_NMEDIT +if test -n "$NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 +$as_echo "$NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_NMEDIT"; then + ac_ct_NMEDIT=$NMEDIT + # Extract the first word of "nmedit", so it can be a program name with args. +set dummy nmedit; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_NMEDIT"; then + ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_NMEDIT="nmedit" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT +if test -n "$ac_ct_NMEDIT"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 +$as_echo "$ac_ct_NMEDIT" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_NMEDIT" = x; then + NMEDIT=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + NMEDIT=$ac_ct_NMEDIT + fi +else + NMEDIT="$ac_cv_prog_NMEDIT" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. +set dummy ${ac_tool_prefix}lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$LIPO"; then + ac_cv_prog_LIPO="$LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_LIPO="${ac_tool_prefix}lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +LIPO=$ac_cv_prog_LIPO +if test -n "$LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 +$as_echo "$LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_LIPO"; then + ac_ct_LIPO=$LIPO + # Extract the first word of "lipo", so it can be a program name with args. +set dummy lipo; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_LIPO+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_LIPO"; then + ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_LIPO="lipo" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO +if test -n "$ac_ct_LIPO"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 +$as_echo "$ac_ct_LIPO" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_LIPO" = x; then + LIPO=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + LIPO=$ac_ct_LIPO + fi +else + LIPO="$ac_cv_prog_LIPO" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL"; then + ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OTOOL="${ac_tool_prefix}otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL=$ac_cv_prog_OTOOL +if test -n "$OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 +$as_echo "$OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL"; then + ac_ct_OTOOL=$OTOOL + # Extract the first word of "otool", so it can be a program name with args. +set dummy otool; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL"; then + ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OTOOL="otool" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL +if test -n "$ac_ct_OTOOL"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 +$as_echo "$ac_ct_OTOOL" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL" = x; then + OTOOL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL=$ac_ct_OTOOL + fi +else + OTOOL="$ac_cv_prog_OTOOL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. +set dummy ${ac_tool_prefix}otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OTOOL64"; then + ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OTOOL64=$ac_cv_prog_OTOOL64 +if test -n "$OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 +$as_echo "$OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OTOOL64"; then + ac_ct_OTOOL64=$OTOOL64 + # Extract the first word of "otool64", so it can be a program name with args. +set dummy otool64; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OTOOL64"; then + ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OTOOL64="otool64" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 +if test -n "$ac_ct_OTOOL64"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 +$as_echo "$ac_ct_OTOOL64" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OTOOL64" = x; then + OTOOL64=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OTOOL64=$ac_ct_OTOOL64 + fi +else + OTOOL64="$ac_cv_prog_OTOOL64" +fi + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 +$as_echo_n "checking for -single_module linker flag... " >&6; } +if ${lt_cv_apple_cc_single_mod+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_apple_cc_single_mod=no + if test -z "$LT_MULTI_MODULE"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + rm -rf libconftest.dylib* + echo "int foo(void){return 1;}" > conftest.c + echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ +-dynamiclib -Wl,-single_module conftest.c" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib -Wl,-single_module conftest.c 2>conftest.err + _lt_result=$? + # If there is a non-empty error log, and "single_module" + # appears in it, assume the flag caused a linker warning + if test -s conftest.err && $GREP single_module conftest.err; then + cat conftest.err >&5 + # Otherwise, if the output was created with a 0 exit code from + # the compiler, it worked. + elif test -f libconftest.dylib && test 0 = "$_lt_result"; then + lt_cv_apple_cc_single_mod=yes + else + cat conftest.err >&5 + fi + rm -rf libconftest.dylib* + rm -f conftest.* + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 +$as_echo "$lt_cv_apple_cc_single_mod" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 +$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } +if ${lt_cv_ld_exported_symbols_list+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_ld_exported_symbols_list=yes +else + lt_cv_ld_exported_symbols_list=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 +$as_echo "$lt_cv_ld_exported_symbols_list" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 +$as_echo_n "checking for -force_load linker flag... " >&6; } +if ${lt_cv_ld_force_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_ld_force_load=no + cat > conftest.c << _LT_EOF +int forced_loaded() { return 2;} +_LT_EOF + echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 + $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 + echo "$AR cru libconftest.a conftest.o" >&5 + $AR cru libconftest.a conftest.o 2>&5 + echo "$RANLIB libconftest.a" >&5 + $RANLIB libconftest.a 2>&5 + cat > conftest.c << _LT_EOF +int main() { return 0;} +_LT_EOF + echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 + $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err + _lt_result=$? + if test -s conftest.err && $GREP force_load conftest.err; then + cat conftest.err >&5 + elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then + lt_cv_ld_force_load=yes + else + cat conftest.err >&5 + fi + rm -f conftest.err libconftest.a conftest conftest.c + rm -rf conftest.dSYM + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 +$as_echo "$lt_cv_ld_force_load" >&6; } + case $host_os in + rhapsody* | darwin1.[012]) + _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + darwin*) # darwin 5.x on + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[91]*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + 10.[012][,.]*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test yes = "$lt_cv_apple_cc_single_mod"; then + _lt_dar_single_mod='$single_module' + fi + if test yes = "$lt_cv_ld_exported_symbols_list"; then + _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' + else + _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' + fi + if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then + _lt_dsymutil='~$DSYMUTIL $lib || :' + else + _lt_dsymutil= + fi + ;; + esac + +# func_munge_path_list VARIABLE PATH +# ----------------------------------- +# VARIABLE is name of variable containing _space_ separated list of +# directories to be munged by the contents of PATH, which is string +# having a format: +# "DIR[:DIR]:" +# string "DIR[ DIR]" will be prepended to VARIABLE +# ":DIR[:DIR]" +# string "DIR[ DIR]" will be appended to VARIABLE +# "DIRP[:DIRP]::[DIRA:]DIRA" +# string "DIRP[ DIRP]" will be prepended to VARIABLE and string +# "DIRA[ DIRA]" will be appended to VARIABLE +# "DIR[:DIR]" +# VARIABLE will be replaced by "DIR[ DIR]" +func_munge_path_list () +{ + case x$2 in + x) + ;; + *:) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" + ;; + x:*) + eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" + ;; + *::*) + eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" + eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" + ;; + *) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" + ;; + esac +} + +for ac_header in dlfcn.h +do : + ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default +" +if test "x$ac_cv_header_dlfcn_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_DLFCN_H 1 +_ACEOF + +fi + +done + + + + + +# Set options + + + + enable_dlopen=no + + + + # Check whether --enable-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. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else + enable_shared=yes +fi + + + + + + + + + + # Check whether --enable-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. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else + enable_static=yes +fi + + + + + + + + + + +# Check whether --with-pic was given. +if test "${with_pic+set}" = set; then : + withval=$with_pic; lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for lt_pkg in $withval; do + IFS=$lt_save_ifs + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else + pic_mode=default +fi + + + + + + + + + # Check whether --enable-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. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else + enable_fast_install=yes +fi + + + + + + + + + shared_archive_member_spec= +case $host,$enable_shared in +power*-*-aix[5-9]*,yes) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5 +$as_echo_n "checking which variant of shared library versioning to provide... " >&6; } + +# Check whether --with-aix-soname was given. +if test "${with_aix_soname+set}" = set; then : + withval=$with_aix_soname; case $withval in + aix|svr4|both) + ;; + *) + as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5 + ;; + esac + lt_cv_with_aix_soname=$with_aix_soname +else + if ${lt_cv_with_aix_soname+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_with_aix_soname=aix +fi + + with_aix_soname=$lt_cv_with_aix_soname +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5 +$as_echo "$with_aix_soname" >&6; } + if test aix != "$with_aix_soname"; then + # For the AIX way of multilib, we name the shared archive member + # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', + # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. + # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, + # the AIX toolchain works better with OBJECT_MODE set (default 32). + if test 64 = "${OBJECT_MODE-32}"; then + shared_archive_member_spec=shr_64 + else + shared_archive_member_spec=shr + fi + fi + ;; +*) + with_aix_soname=aix + ;; +esac + + + + + + + + + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS=$ltmain + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +test -z "$LN_S" && LN_S="ln -s" + + + + + + + + + + + + + + +if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 +$as_echo_n "checking for objdir... " >&6; } +if ${lt_cv_objdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 +$as_echo "$lt_cv_objdir" >&6; } +objdir=$lt_cv_objdir + + + + + +cat >>confdefs.h <<_ACEOF +#define LT_OBJDIR "$lt_cv_objdir/" +_ACEOF + + + + +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 set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Global variables: +ofile=libtool +can_build_shared=yes + +# All known linkers require a '.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a + +with_gnu_ld=$lt_cv_prog_gnu_ld + +old_CC=$CC +old_CFLAGS=$CFLAGS + +# Set sane defaults for various variables +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$LD" && LD=ld +test -z "$ac_objext" && ac_objext=o + +func_cc_basename $compiler +cc_basename=$func_cc_basename_result + + +# Only perform the check for file, if the check method requires it +test -z "$MAGIC_CMD" && MAGIC_CMD=file +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 +$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/${ac_tool_prefix}file"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD=$lt_cv_path_MAGIC_CMD + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD + ;; +esac +fi + +MAGIC_CMD=$lt_cv_path_MAGIC_CMD +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + + +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 +$as_echo_n "checking for file... " >&6; } +if ${lt_cv_path_MAGIC_CMD+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $MAGIC_CMD in +[\\/*] | ?:[\\/]*) + lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD=$MAGIC_CMD + lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR + ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" + for ac_dir in $ac_dummy; do + IFS=$lt_save_ifs + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/file"; then + lt_cv_path_MAGIC_CMD=$ac_dir/"file" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD=$lt_cv_path_MAGIC_CMD + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<_LT_EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +_LT_EOF + fi ;; + esac + fi + break + fi + done + IFS=$lt_save_ifs + MAGIC_CMD=$lt_save_MAGIC_CMD + ;; +esac +fi + +MAGIC_CMD=$lt_cv_path_MAGIC_CMD +if test -n "$MAGIC_CMD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 +$as_echo "$MAGIC_CMD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + else + MAGIC_CMD=: + fi +fi + + fi + ;; +esac + +# Use C for the default configuration in the libtool script + +lt_save_CC=$CC +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +objext=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}' + + + + + + + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC + +# Save the default compiler, since it gets overwritten when the other +# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. +compiler_DEFAULT=$CC + +# save warnings/boilerplate of simple test code +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$RM conftest* + +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$RM -r conftest* + + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +if test -n "$compiler"; then + +lt_prog_compiler_no_builtin_flag= + +if test yes = "$GCC"; then + case $cc_basename in + nvcc*) + lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; + *) + lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; + esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } +if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_rtti_exceptions=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="-fno-rtti -fno-exceptions" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_rtti_exceptions=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 +$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } + +if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then + lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" +else + : +fi + +fi + + + + + + + lt_prog_compiler_wl= +lt_prog_compiler_pic= +lt_prog_compiler_static= + + + if test yes = "$GCC"; then + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_static='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + lt_prog_compiler_pic='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static='$wl-static' + ;; + esac + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic=-Kconform_pic + fi + ;; + + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + lt_prog_compiler_wl='-Xlinker ' + if test -n "$lt_prog_compiler_pic"; then + lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl='-Wl,' + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + case $cc_basename in + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + esac + ;; + + mingw* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static='$wl-static' + ;; + esac + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static='$wl-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + # old Intel for x86_64, which still supported -KPIC. + ecc*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='--shared' + lt_prog_compiler_static='--static' + ;; + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='' + ;; + *Sun\ F* | *Sun*Fortran*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; + *Intel*\ [CF]*Compiler*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + *Portland\ Group*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static='-non_shared' + ;; + + solaris*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + lt_prog_compiler_wl='-Qoption ld ';; + *) + lt_prog_compiler_wl='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl='-Qoption ld ' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic='-Kconform_pic' + lt_prog_compiler_static='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_can_build_shared=no + ;; + + uts4*) + lt_prog_compiler_pic='-pic' + lt_prog_compiler_static='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared=no + ;; + esac + fi + +case $host_os in + # For platforms that do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic= + ;; + *) + lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" + ;; +esac + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +$as_echo_n "checking for $compiler option to produce PIC... " >&6; } +if ${lt_cv_prog_compiler_pic+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic=$lt_prog_compiler_pic +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 +$as_echo "$lt_cv_prog_compiler_pic" >&6; } +lt_prog_compiler_pic=$lt_cv_prog_compiler_pic + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } +if ${lt_cv_prog_compiler_pic_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_pic_works=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes + fi + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 +$as_echo "$lt_cv_prog_compiler_pic_works" >&6; } + +if test yes = "$lt_cv_prog_compiler_pic_works"; then + case $lt_prog_compiler_pic in + "" | " "*) ;; + *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; + esac +else + lt_prog_compiler_pic= + lt_prog_compiler_can_build_shared=no +fi + +fi + + + + + + + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if ${lt_cv_prog_compiler_static_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_static_works=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes + fi + else + lt_cv_prog_compiler_static_works=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 +$as_echo "$lt_cv_prog_compiler_static_works" >&6; } + +if test yes = "$lt_cv_prog_compiler_static_works"; then + : +else + lt_prog_compiler_static= +fi + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 +$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } +if ${lt_cv_prog_compiler_c_o+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler_c_o=no + $RM -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + lt_cv_prog_compiler_c_o=yes + fi + fi + chmod u+w . 2>&5 + $RM conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files + $RM out/* && rmdir out + cd .. + $RM -r conftest + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 +$as_echo "$lt_cv_prog_compiler_c_o" >&6; } + + + + +hard_links=nottested +if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then + # do not overwrite the value of need_locks provided by the user + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 +$as_echo_n "checking if we can lock with hard links... " >&6; } + hard_links=yes + $RM conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 +$as_echo "$hard_links" >&6; } + if test no = "$hard_links"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 +$as_echo "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} + need_locks=warn + fi +else + need_locks=no +fi + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } + + runpath_var= + allow_undefined_flag= + always_export_symbols=no + archive_cmds= + archive_expsym_cmds= + compiler_needs_object=no + enable_shared_with_static_runtimes=no + export_dynamic_flag_spec= + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + hardcode_automatic=no + hardcode_direct=no + hardcode_direct_absolute=no + hardcode_libdir_flag_spec= + hardcode_libdir_separator= + hardcode_minus_L=no + hardcode_shlibpath_var=unsupported + inherit_rpath=no + link_all_deplibs=unknown + module_cmds= + module_expsym_cmds= + old_archive_from_new_cmds= + old_archive_from_expsyms_cmds= + thread_safe_flag_spec= + whole_archive_flag_spec= + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + include_expsyms= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ' (' and ')$', so one must not match beginning or + # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', + # as well as any symbol that contains 'd'. + exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. + extract_expsyms_cmds= + + case $host_os in + cygwin* | mingw* | pw32* | cegcc*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test yes != "$GCC"; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd* | bitrig*) + with_gnu_ld=no + ;; + esac + + ld_shlibs=yes + + # On some targets, GNU ld is compatible enough with the native linker + # that we're better off using the native interface for both. + lt_use_gnu_ld_interface=no + if test yes = "$with_gnu_ld"; then + case $host_os in + aix*) + # The AIX port of GNU ld has always aspired to compatibility + # with the native linker. However, as the warning in the GNU ld + # block says, versions before 2.19.5* couldn't really create working + # shared libraries, regardless of the interface used. + case `$LD -v 2>&1` in + *\ \(GNU\ Binutils\)\ 2.19.5*) ;; + *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; + *\ \(GNU\ Binutils\)\ [3-9]*) ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + ;; + *) + lt_use_gnu_ld_interface=yes + ;; + esac + fi + + if test yes = "$lt_use_gnu_ld_interface"; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='$wl' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + export_dynamic_flag_spec='$wl--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then + whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' + else + whole_archive_flag_spec= + fi + supports_anon_versioning=no + case `$LD -v | $SED -e 's/(^)\+)\s\+//' 2>&1` in + *GNU\ gold*) supports_anon_versioning=yes ;; + *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix[3-9]*) + # On AIX/PPC, the GNU linker is very broken + if test ia64 != "$host_cpu"; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.19, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to install binutils +*** 2.20 or above, or modify your PATH so that a non-GNU linker is found. +*** You will then need to restart the configuration process. + +_LT_EOF + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + beos*) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach <jrb3@best.com> says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, + # as there is no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + export_dynamic_flag_spec='$wl--export-all-symbols' + allow_undefined_flag=unsupported + always_export_symbols=no + enable_shared_with_static_runtimes=yes + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' + exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + + if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file, use it as + # is; otherwise, prepend EXPORTS... + archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + ld_shlibs=no + fi + ;; + + haiku*) + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + link_all_deplibs=yes + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + shrext_cmds=.dll + archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + enable_shared_with_static_runtimes=yes + ;; + + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + export_dynamic_flag_spec='$wl-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) + tmp_diet=no + if test linux-dietlibc = "$host_os"; then + case $cc_basename in + diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) + esac + fi + if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ + && test no = "$tmp_diet" + then + tmp_addflag=' $pic_flag' + tmp_sharedflag='-shared' + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group f77 and f90 compilers + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + lf95*) # Lahey Fortran 8.1 + whole_archive_flag_spec= + tmp_sharedflag='--shared' ;; + nagfor*) # NAGFOR 5.3 + tmp_sharedflag='-Wl,-shared' ;; + xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) + tmp_sharedflag='-qmkshrobj' + tmp_addflag= ;; + nvcc*) # Cuda Compiler Driver 2.2 + whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + compiler_needs_object=yes + ;; + esac + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' + compiler_needs_object=yes + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + esac + archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + + if test yes = "$supports_anon_versioning"; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' + fi + + case $cc_basename in + tcc*) + export_dynamic_flag_spec='-rdynamic' + ;; + xlf* | bgf* | bgxlf* | mpixlf*) + # IBM XL Fortran 10.1 on PPC cannot create shared libs itself + whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' + if test yes = "$supports_anon_versioning"; then + archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + echo "local: *; };" >> $output_objdir/$libname.ver~ + $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' + fi + ;; + esac + else + ld_shlibs=no + fi + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test no = "$ld_shlibs"; then + runpath_var= + hardcode_libdir_flag_spec= + export_dynamic_flag_spec= + whole_archive_flag_spec= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix[4-9]*) + if test ia64 = "$host_cpu"; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag= + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to GNU nm, but means don't demangle to AIX nm. + # Without the "-l" option, or with the "-B" option, AIX nm treats + # weak defined symbols like other global defined symbols, whereas + # GNU nm marks them as "W". + # While the 'weak' keyword is ignored in the Export File, we need + # it in the Import File for the 'aix-soname' feature, so we have + # to replace the "-B" option with "-P" for AIX nm. + if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then + export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' + else + export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # have runtime linking enabled, and use it for executables. + # For shared libraries, we enable/disable runtime linking + # depending on the kind of the shared library created - + # when "with_aix_soname,aix_use_runtimelinking" is: + # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables + # "aix,yes" lib.so shared, rtl:yes, for executables + # lib.a static archive + # "both,no" lib.so.V(shr.o) shared, rtl:yes + # lib.a(lib.so.V) shared, rtl:no, for executables + # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a(lib.so.V) shared, rtl:no + # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables + # lib.a static archive + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) + for ld_flag in $LDFLAGS; do + if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then + aix_use_runtimelinking=yes + break + fi + done + if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then + # With aix-soname=svr4, we create the lib.so.V shared archives only, + # so we don't have lib.a shared libs to link our executables. + # We have to force runtime linking in this case. + aix_use_runtimelinking=yes + LDFLAGS="$LDFLAGS -Wl,-brtl" + fi + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + archive_cmds='' + hardcode_direct=yes + hardcode_direct_absolute=yes + hardcode_libdir_separator=':' + link_all_deplibs=yes + file_list_spec='$wl-f,' + case $with_aix_soname,$aix_use_runtimelinking in + aix,*) ;; # traditional, no import file + svr4,* | *,yes) # use import file + # The Import File defines what to hardcode. + hardcode_direct=no + hardcode_direct_absolute=no + ;; + esac + + if test yes = "$GCC"; then + case $host_os in aix4.[012]|aix4.[012].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`$CC -print-prog-name=collect2` + if test -f "$collect2name" && + strings "$collect2name" | $GREP resolve_lib_name >/dev/null + then + # We have reworked collect2 + : + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + ;; + esac + shared_flag='-shared' + if test yes = "$aix_use_runtimelinking"; then + shared_flag="$shared_flag "'$wl-G' + fi + # Need to ensure runtime linking is disabled for the traditional + # shared library, or the linker may eventually find shared libraries + # /with/ Import File - we do not want to mix them. + shared_flag_aix='-shared' + shared_flag_svr4='-shared $wl-G' + else + # not using gcc + if test ia64 = "$host_cpu"; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test yes = "$aix_use_runtimelinking"; then + shared_flag='$wl-G' + else + shared_flag='$wl-bM:SRE' + fi + shared_flag_aix='$wl-bM:SRE' + shared_flag_svr4='$wl-G' + fi + fi + + export_dynamic_flag_spec='$wl-bexpall' + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + always_export_symbols=yes + if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + allow_undefined_flag='-berok' + # Determine the default libpath from the value encoded in an + # empty executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" + archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag + else + if test ia64 = "$host_cpu"; then + hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib' + allow_undefined_flag="-z nodefs" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an + # empty executable. + if test set = "${lt_cv_aix_libpath+set}"; then + aix_libpath=$lt_cv_aix_libpath +else + if ${lt_cv_aix_libpath_+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + + lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\([^ ]*\) *$/\1/ + p + } + }' + lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + # Check for a 64-bit object if we didn't find anything. + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` + fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + if test -z "$lt_cv_aix_libpath_"; then + lt_cv_aix_libpath_=/usr/lib:/lib + fi + +fi + + aix_libpath=$lt_cv_aix_libpath_ +fi + + hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + no_undefined_flag=' $wl-bernotok' + allow_undefined_flag=' $wl-berok' + if test yes = "$with_gnu_ld"; then + # We only use this code for GNU lds that support --whole-archive. + whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive' + else + # Exported symbols can be pulled into shared objects from archives + whole_archive_flag_spec='$convenience' + fi + archive_cmds_need_lc=yes + archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' + # -brtl affects multiple linker settings, -berok does not and is overridden later + compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' + if test svr4 != "$with_aix_soname"; then + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' + fi + if test aix != "$with_aix_soname"; then + archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' + else + # used by -dlpreopen to get the symbols + archive_expsym_cmds="$archive_expsym_cmds"'~$MV $output_objdir/$realname.d/$soname $output_objdir' + fi + archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d' + fi + fi + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='' + ;; + m68k) + archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + ;; + esac + ;; + + bsdi[45]*) + export_dynamic_flag_spec=-rdynamic + ;; + + cygwin* | mingw* | pw32* | cegcc*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + case $cc_basename in + cl*) + # Native MSVC + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + always_export_symbols=yes + file_list_spec='@' + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then + cp "$export_symbols" "$output_objdir/$soname.def"; + echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; + else + $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; + fi~ + $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + linknames=' + # The linker will not automatically build a static lib if we build a DLL. + # _LT_TAGVAR(old_archive_from_new_cmds, )='true' + enable_shared_with_static_runtimes=yes + exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' + # Don't use ranlib + old_postinstall_cmds='chmod 644 $oldlib' + postlink_cmds='lt_outputfile="@OUTPUT@"~ + lt_tool_outputfile="@TOOL_OUTPUT@"~ + case $lt_outputfile in + *.exe|*.EXE) ;; + *) + lt_outputfile=$lt_outputfile.exe + lt_tool_outputfile=$lt_tool_outputfile.exe + ;; + esac~ + if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then + $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; + $RM "$lt_outputfile.manifest"; + fi' + ;; + *) + # Assume MSVC wrapper + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=.dll + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' + enable_shared_with_static_runtimes=yes + ;; + esac + ;; + + darwin* | rhapsody*) + + + archive_cmds_need_lc=no + hardcode_direct=no + hardcode_automatic=yes + hardcode_shlibpath_var=unsupported + if test yes = "$lt_cv_ld_force_load"; then + whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' + + else + whole_archive_flag_spec='' + fi + link_all_deplibs=yes + allow_undefined_flag=$_lt_dar_allow_undefined + case $cc_basename in + ifort*|nagfor*) _lt_dar_can_shared=yes ;; + *) _lt_dar_can_shared=$GCC ;; + esac + if test yes = "$_lt_dar_can_shared"; then + output_verbose_link_cmd=func_echo_all + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" + archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + module_expsym_cmds="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" + + else + ld_shlibs=no + fi + + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + # 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 $deplibs $linker_flags /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2.*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9*) + if test yes = "$GCC"; then + archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + else + archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' + fi + hardcode_libdir_flag_spec='$wl+b $wl$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + export_dynamic_flag_spec='$wl-E' + ;; + + hpux10*) + if test yes,no = "$GCC,$with_gnu_ld"; then + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec='$wl+b $wl$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='$wl-E' + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + + hpux11*) + if test yes,no = "$GCC,$with_gnu_ld"; then + case $host_cpu in + hppa*64*) + archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + + # Older versions of the 11.00 compiler do not understand -b yet + # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 +$as_echo_n "checking if $CC understands -b... " >&6; } +if ${lt_cv_prog_compiler__b+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_prog_compiler__b=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -b" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler__b=yes + fi + else + lt_cv_prog_compiler__b=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 +$as_echo "$lt_cv_prog_compiler__b" >&6; } + +if test yes = "$lt_cv_prog_compiler__b"; then + archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' +else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' +fi + + ;; + esac + fi + if test no = "$with_gnu_ld"; then + hardcode_libdir_flag_spec='$wl+b $wl$libdir' + hardcode_libdir_separator=: + + case $host_cpu in + hppa*64*|ia64*) + hardcode_direct=no + hardcode_shlibpath_var=no + ;; + *) + hardcode_direct=yes + hardcode_direct_absolute=yes + export_dynamic_flag_spec='$wl-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test yes = "$GCC"; then + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + # Try to use the -exported_symbol ld option, if it does not + # work, assume that -exports_file does not work either and + # implicitly export all symbols. + # This should be the same for all languages, so no per-tag cache variable. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 +$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } +if ${lt_cv_irix_exported_symbol+:} false; then : + $as_echo_n "(cached) " >&6 +else + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int foo (void) { return 0; } +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + lt_cv_irix_exported_symbol=yes +else + lt_cv_irix_exported_symbol=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 +$as_echo "$lt_cv_irix_exported_symbol" >&6; } + if test yes = "$lt_cv_irix_exported_symbol"; then + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' + fi + else + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + hardcode_libdir_separator=: + inherit_rpath=yes + link_all_deplibs=yes + ;; + + linux*) + case $cc_basename in + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + ld_shlibs=yes + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + newsos6) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + hardcode_libdir_separator=: + hardcode_shlibpath_var=no + ;; + + *nto* | *qnx*) + ;; + + openbsd* | bitrig*) + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + hardcode_shlibpath_var=no + hardcode_direct_absolute=yes + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + export_dynamic_flag_spec='$wl-E' + else + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='$wl-rpath,$libdir' + fi + else + ld_shlibs=no + fi + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + shrext_cmds=.dll + archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ + $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ + $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ + $ECHO EXPORTS >> $output_objdir/$libname.def~ + prefix_cmds="$SED"~ + if test EXPORTS = "`$SED 1q $export_symbols`"; then + prefix_cmds="$prefix_cmds -e 1d"; + fi~ + prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ + cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ + $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ + emximp -o $lib $output_objdir/$libname.def' + old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + enable_shared_with_static_runtimes=yes + ;; + + osf3*) + if test yes = "$GCC"; then + allow_undefined_flag=' $wl-expect_unresolved $wl\*' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + fi + archive_cmds_need_lc='no' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + hardcode_libdir_separator=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test yes = "$GCC"; then + allow_undefined_flag=' $wl-expect_unresolved $wl\*' + archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' + archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' + + # Both c and cxx compiler support -rpath directly + hardcode_libdir_flag_spec='-rpath $libdir' + fi + archive_cmds_need_lc='no' + hardcode_libdir_separator=: + ;; + + solaris*) + no_undefined_flag=' -z defs' + if test yes = "$GCC"; then + wlarc='$wl' + archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + else + case `$CC -V 2>&1` in + *"Compilers 5.0"*) + wlarc='' + archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' + ;; + *) + wlarc='$wl' + archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ + $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' + ;; + esac + fi + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + # The compiler driver will combine and reorder linker options, + # but understands '-z linker_flag'. GCC discards it without '$wl', + # but is careful enough not to reorder. + # Supported since Solaris 2.6 (maybe 2.5.1?) + if test yes = "$GCC"; then + whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' + else + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' + fi + ;; + esac + link_all_deplibs=yes + ;; + + sunos4*) + if test sequent = "$host_vendor"; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + case $host_vendor in + sni) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' + reload_cmds='$CC -r -o $output$reload_objs' + hardcode_direct=no + ;; + motorola) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag='$wl-z,text' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We CANNOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag='$wl-z,text' + allow_undefined_flag='$wl-z,nodefs' + archive_cmds_need_lc=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='$wl-R,$libdir' + hardcode_libdir_separator=':' + link_all_deplibs=yes + export_dynamic_flag_spec='$wl-Bexport' + runpath_var='LD_RUN_PATH' + + if test yes = "$GCC"; then + archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + *) + ld_shlibs=no + ;; + esac + + if test sni = "$host_vendor"; then + case $host in + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + export_dynamic_flag_spec='$wl-Blargedynsym' + ;; + esac + fi + fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 +$as_echo "$ld_shlibs" >&6; } +test no = "$ld_shlibs" && can_build_shared=no + +with_gnu_ld=$with_gnu_ld + + + + + + + + + + + + + + + +# +# Do we need to explicitly link libc? +# +case "x$archive_cmds_need_lc" in +x|xyes) + # Assume -lc should be added + archive_cmds_need_lc=yes + + if test yes,yes = "$GCC,$enable_shared"; then + case $archive_cmds in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 +$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } +if ${lt_cv_archive_cmds_need_lc+:} false; then : + $as_echo_n "(cached) " >&6 +else + $RM conftest* + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$lt_prog_compiler_wl + pic_flag=$lt_prog_compiler_pic + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$allow_undefined_flag + allow_undefined_flag= + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 + (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } + then + lt_cv_archive_cmds_need_lc=no + else + lt_cv_archive_cmds_need_lc=yes + fi + allow_undefined_flag=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $RM conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 +$as_echo "$lt_cv_archive_cmds_need_lc" >&6; } + archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc + ;; + esac + fi + ;; +esac + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 +$as_echo_n "checking dynamic linker characteristics... " >&6; } + +if test yes = "$GCC"; then + case $host_os in + darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; + *) lt_awk_arg='/^libraries:/' ;; + esac + case $host_os in + mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;; + *) lt_sed_strip_eq='s|=/|/|g' ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` + case $lt_search_path_spec in + *\;*) + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` + ;; + *) + lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` + ;; + esac + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary... + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + # ...but if some path component already ends with the multilib dir we assume + # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). + case "$lt_multi_os_dir; $lt_search_path_spec " in + "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) + lt_multi_os_dir= + ;; + esac + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" + elif test -n "$lt_multi_os_dir"; then + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' +BEGIN {RS = " "; FS = "/|\n";} { + lt_foo = ""; + lt_count = 0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo = "/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } +}'` + # AWK program above erroneously prepends '/' to C:/dos/paths + # for these hosts. + case $host_os in + mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + $SED 's|/\([A-Za-z]:\)|\1|g'` ;; + esac + sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=.so +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + + + +case $host_os in +aix3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='$libname$release$shared_ext$major' + ;; + +aix[4-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test ia64 = "$host_cpu"; then + # AIX 5 supports IA64 + library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line '#! .'. This would cause the generated library to + # depend on '.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[01] | aix4.[01].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # Using Import Files as archive members, it is possible to support + # filename-based versioning of shared library archives on AIX. While + # this would work for both with and without runtime linking, it will + # prevent static linking of such archives. So we do filename-based + # shared library versioning with .so extension only, which is used + # when both runtime linking and shared linking is enabled. + # Unfortunately, runtime linking may impact performance, so we do + # not want this to be the default eventually. Also, we use the + # versioned .so libs for executables only if there is the -brtl + # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. + # To allow for filename-based versioning support, we need to create + # libNAME.so.V as an archive file, containing: + # *) an Import File, referring to the versioned filename of the + # archive as well as the shared archive member, telling the + # bitwidth (32 or 64) of that shared object, and providing the + # list of exported symbols of that shared object, eventually + # decorated with the 'weak' keyword + # *) the shared object with the F_LOADONLY flag set, to really avoid + # it being seen by the linker. + # At run time we better use the real file rather than another symlink, + # but for link time we create the symlink libNAME.so -> libNAME.so.V + + case $with_aix_soname,$aix_use_runtimelinking in + # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + aix,yes) # traditional libtool + dynamic_linker='AIX unversionable lib.so' + # If using run time linking (on AIX 4.2 or later) use lib<name>.so + # instead of lib<name>.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + aix,no) # traditional AIX only + dynamic_linker='AIX lib.a(lib.so.V)' + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + ;; + svr4,*) # full svr4 only + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,yes) # both, prefer svr4 + dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" + library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' + # unpreferred sharedlib libNAME.a needs extra handling + postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' + postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' + # We do not specify a path in Import Files, so LIBPATH fires. + shlibpath_overrides_runpath=yes + ;; + *,no) # both, prefer aix + dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" + library_names_spec='$libname$release.a $libname.a' + soname_spec='$libname$release$shared_ext$major' + # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling + postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' + postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' + ;; + esac + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + case $host_cpu in + powerpc) + # Since July 2007 AmigaOS4 officially supports .so libraries. + # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + ;; + m68k) + 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=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $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' + ;; + esac + ;; + +beos*) + library_names_spec='$libname$shared_ext' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[45]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32* | cegcc*) + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + + case $GCC,$cc_basename in + yes,*) + # gcc + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" + ;; + mingw* | cegcc*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + ;; + esac + dynamic_linker='Win32 ld.exe' + ;; + + *,cl*) + # Native MSVC + libname_spec='$name' + soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + library_names_spec='$libname.dll.lib' + + case $build_os in + mingw*) + sys_lib_search_path_spec= + lt_save_ifs=$IFS + IFS=';' + for lt_path in $LIB + do + IFS=$lt_save_ifs + # Let DOS variable expansion print the short 8.3 style file name. + lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` + sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" + done + IFS=$lt_save_ifs + # Convert to MSYS style. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + ;; + cygwin*) + # Convert to unix form, then to dos form, then back to unix form + # but this time dos style (no spaces!) so that the unix form looks + # like /cygdrive/c/PROGRA~1:/cygdr... + sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` + sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` + sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + ;; + *) + sys_lib_search_path_spec=$LIB + if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then + # It is most probably a Windows format PATH. + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + # FIXME: find the short name or the path components, as spaces are + # common. (e.g. "Program Files" -> "PROGRA~1") + ;; + esac + + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + shlibpath_overrides_runpath=yes + dynamic_linker='Win32 link.exe' + ;; + + *) + # Assume MSVC wrapper + library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' + dynamic_linker='Win32 ld.exe' + ;; + esac + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' + soname_spec='$libname$release$major$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[23].*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2.*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[01]* | freebsdelf3.[01]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +haiku*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + dynamic_linker="$host_os runtime_loader" + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LIBRARY_PATH + shlibpath_overrides_runpath=no + sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + if test 32 = "$HPUX_IA64_MODE"; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + sys_lib_dlsearch_path_spec=/usr/lib/hpux32 + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + sys_lib_dlsearch_path_spec=/usr/lib/hpux64 + fi + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555, ... + postinstall_cmds='chmod 555 $lib' + # or fails outright, so override atomically: + install_override_mode=555 + ;; + +interix[3-9]*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test yes = "$lt_cv_prog_gnu_ld"; then + version_type=linux # correct to gnu/linux during the next big refactor + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" + sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +linux*android*) + version_type=none # Android doesn't support versioned libraries. + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + dynamic_linker='Android linker' + # Don't embed -rpath directories since the linker doesn't support them. + hardcode_libdir_flag_spec='-L$libdir' + ;; + +# This must be glibc/ELF. +linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + + # Some binutils ld are patched to set DT_RUNPATH + if ${lt_cv_shlibpath_overrides_runpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + lt_cv_shlibpath_overrides_runpath=no + save_LDFLAGS=$LDFLAGS + save_libdir=$libdir + eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ + LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : + lt_cv_shlibpath_overrides_runpath=yes +fi +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + libdir=$save_libdir + +fi + + shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath + + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Ideally, we could use ldconfig to report *all* directores which are + # searched for libraries, however this is still not possible. Aside from not + # being certain /sbin/ldconfig is available, command + # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, + # even though it is searched at run-time. Try to do the best guess by + # appending ld.so.conf contents (and includes) to the search path. + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +*nto* | *qnx*) + version_type=qnx + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='ldqnx.so' + ;; + +openbsd* | bitrig*) + version_type=sunos + sys_lib_dlsearch_path_spec=/usr/lib + need_lib_prefix=no + if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then + need_version=no + else + need_version=yes + fi + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +os2*) + libname_spec='$name' + version_type=windows + shrext_cmds=.dll + need_version=no + need_lib_prefix=no + # OS/2 can only load a DLL with a base name of 8 characters or less. + soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; + v=$($ECHO $release$versuffix | tr -d .-); + n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); + $ECHO $n$v`$shared_ext' + library_names_spec='${libname}_dll.$libext' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=BEGINLIBPATH + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $RM \$dlpath' + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='$libname$release$shared_ext$major' + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + +rdos*) + dynamic_linker=no + ;; + +solaris*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test yes = "$with_gnu_ld"; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec; then + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' + soname_spec='$libname$shared_ext.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=sco + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + if test yes = "$with_gnu_ld"; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +tpf*) + # TPF is a cross-target only. Preferred cross-host = GNU/Linux. + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +uts4*) + version_type=linux # correct to gnu/linux during the next big refactor + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +$as_echo "$dynamic_linker" >&6; } +test no = "$dynamic_linker" && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test yes = "$GCC"; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then + sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec +fi + +if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then + sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec +fi + +# remember unaugmented sys_lib_dlsearch_path content for libtool script decls... +configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec + +# ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code +func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" + +# to be used as default LT_SYS_LIBRARY_PATH value in generated libtool +configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 +$as_echo_n "checking how to hardcode library paths into programs... " >&6; } +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || + test -n "$runpath_var" || + test yes = "$hardcode_automatic"; then + + # We can hardcode non-existent directories. + if test no != "$hardcode_direct" && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" && + test no != "$hardcode_minus_L"; 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 +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 +$as_echo "$hardcode_action" >&6; } + +if test relink = "$hardcode_action" || + test yes = "$inherit_rpath"; then + # Fast installation is not supported + enable_fast_install=no +elif test yes = "$shlibpath_overrides_runpath" || + test no = "$enable_shared"; then + # Fast installation is not necessary + enable_fast_install=needless +fi + + + + + + + if test yes != "$enable_dlopen"; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen=load_add_on + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32* | cegcc*) + lt_cv_dlopen=LoadLibrary + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl +else + + lt_cv_dlopen=dyld + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + +fi + + ;; + + tpf*) + # Don't try to run any link tests for TPF. We know it's impossible + # because TPF is a cross-compiler, and we know how we open DSOs. + lt_cv_dlopen=dlopen + lt_cv_dlopen_libs= + lt_cv_dlopen_self=no + ;; + + *) + ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" +if test "x$ac_cv_func_shl_load" = xyes; then : + lt_cv_dlopen=shl_load +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 +$as_echo_n "checking for shl_load in -ldld... " >&6; } +if ${ac_cv_lib_dld_shl_load+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char shl_load (); +int +main () +{ +return shl_load (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_shl_load=yes +else + ac_cv_lib_dld_shl_load=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 +$as_echo "$ac_cv_lib_dld_shl_load" >&6; } +if test "x$ac_cv_lib_dld_shl_load" = xyes; then : + lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld +else + ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" +if test "x$ac_cv_func_dlopen" = xyes; then : + lt_cv_dlopen=dlopen +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 +$as_echo_n "checking for dlopen in -lsvld... " >&6; } +if ${ac_cv_lib_svld_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsvld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_svld_dlopen=yes +else + ac_cv_lib_svld_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 +$as_echo "$ac_cv_lib_svld_dlopen" >&6; } +if test "x$ac_cv_lib_svld_dlopen" = xyes; then : + lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 +$as_echo_n "checking for dld_link in -ldld... " >&6; } +if ${ac_cv_lib_dld_dld_link+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldld $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dld_link (); +int +main () +{ +return dld_link (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dld_dld_link=yes +else + ac_cv_lib_dld_dld_link=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 +$as_echo "$ac_cv_lib_dld_dld_link" >&6; } +if test "x$ac_cv_lib_dld_dld_link" = xyes; then : + lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld +fi + + +fi + + +fi + + +fi + + +fi + + +fi + + ;; + esac + + if test no = "$lt_cv_dlopen"; then + enable_dlopen=no + else + enable_dlopen=yes + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS=$CPPFLAGS + test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS=$LDFLAGS + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS=$LIBS + LIBS="$lt_cv_dlopen_libs $LIBS" + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 +$as_echo_n "checking whether a program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test yes = "$cross_compiling"; then : + lt_cv_dlopen_self=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include <dlfcn.h> +#endif + +#include <stdio.h> + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisibility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 +$as_echo "$lt_cv_dlopen_self" >&6; } + + if test yes = "$lt_cv_dlopen_self"; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 +$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } +if ${lt_cv_dlopen_self_static+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test yes = "$cross_compiling"; then : + lt_cv_dlopen_self_static=cross +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<_LT_EOF +#line $LINENO "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include <dlfcn.h> +#endif + +#include <stdio.h> + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +/* When -fvisibility=hidden is used, assume the code has been annotated + correspondingly for the symbols needed. */ +#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) +int fnord () __attribute__((visibility("default"))); +#endif + +int fnord () { return 42; } +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else + { + if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + else puts (dlerror ()); + } + /* dlclose (self); */ + } + else + puts (dlerror ()); + + return status; +} +_LT_EOF + if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 + (eval $ac_link) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then + (./conftest; exit; ) >&5 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; + esac + else : + # compilation failed + lt_cv_dlopen_self_static=no + fi +fi +rm -fr conftest* + + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 +$as_echo "$lt_cv_dlopen_self_static" >&6; } + fi + + CPPFLAGS=$save_CPPFLAGS + LDFLAGS=$save_LDFLAGS + LIBS=$save_LIBS + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + + + + + + + + + + + + + + + + + +striplib= +old_striplib= +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 +$as_echo_n "checking whether stripping libraries is possible... " >&6; } +if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP"; then + striplib="$STRIP -x" + old_striplib="$STRIP -S" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + ;; + esac +fi + + + + + + + + + + + + + # Report what library types will actually be built + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 +$as_echo_n "checking if libtool supports shared libraries... " >&6; } + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 +$as_echo "$can_build_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 +$as_echo_n "checking whether to build shared libraries... " >&6; } + test no = "$can_build_shared" && enable_shared=no + + # On AIX, shared libraries and static libraries use the same namespace, and + # are all built from PIC. + case $host_os in + aix3*) + test yes = "$enable_shared" && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + + aix[4-9]*) + if test ia64 != "$host_cpu"; then + case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in + yes,aix,yes) ;; # shared object as lib.so file only + yes,svr4,*) ;; # shared object as lib.so archive member only + yes,*) enable_static=no ;; # shared object in lib.a archive as well + esac + fi + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 +$as_echo "$enable_shared" >&6; } + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 +$as_echo_n "checking whether to build static libraries... " >&6; } + # Make sure either enable_shared or enable_static is yes. + test yes = "$enable_shared" || enable_static=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 +$as_echo "$enable_static" >&6; } + + + + +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +CC=$lt_save_CC + + + + + + + + + + + + + + + + ac_config_commands="$ac_config_commands libtool" + + + + +# Only expand once: + + +# From configure.ac Revision: 4.34 . +config_start_time=`date +%s 2>/dev/null` +# ---------------------------------------------------------------------- +# Substitute VERSION vars here, so that they can be used by the Makefile +# ---------------------------------------------------------------------- + + + + + + +AO_TEMPLATE_VERSION=`expr '(' $AO_CURRENT '*' 4096 ')' + $AO_REVISION` + + + + + +cat >>confdefs.h <<_ACEOF +#define AO_CURRENT $AO_CURRENT +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define AO_REVISION $AO_REVISION +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define AO_AGE $AO_AGE +_ACEOF + +# ---------------------------------------------------------------------- +# Set up the environment to configure the snprintv subpackage using +# this version of AutoGen (as opposed to any installed version). +# ---------------------------------------------------------------------- +ag_srcdir=`\cd $srcdir && pwd` +if test x$ag_srcdir != x && test -d $ag_srcdir; then + : +else + ag_srcdir=.. +fi + +# ---------------------------------------------------------------------- +# If `configure' is invoked (in)directly via `make', ensure that it +# encounters no `make' conflicts. Ignore error if shell does not have +# unset, but at least set these to empty values. +# ---------------------------------------------------------------------- +MFLAGS= +MAKEFLAGS= +MAKELEVEL= +unset MFLAGS MAKEFLAGS MAKELEVEL 2>/dev/null + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if malloc debugging is wanted" >&5 +$as_echo_n "checking if malloc debugging is wanted... " >&6; } + +# Check whether --with-dmalloc was given. +if test "${with_dmalloc+set}" = set; then : + withval=$with_dmalloc; if test "$withval" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define WITH_DMALLOC 1" >>confdefs.h + + LIBS="$LIBS -ldmalloc" + LDFLAGS="$LDFLAGS -g" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + +# ---------------------------------------------------------------------- +# check for various programs used during the build. +# ---------------------------------------------------------------------- + case $ac_cv_prog_cc_stdc in #( + no) : + ac_cv_prog_cc_c99=no; ac_cv_prog_cc_c89=no ;; #( + *) : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C99" >&5 +$as_echo_n "checking for $CC option to accept ISO C99... " >&6; } +if ${ac_cv_prog_cc_c99+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c99=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdarg.h> +#include <stdbool.h> +#include <stdlib.h> +#include <wchar.h> +#include <stdio.h> + +// Check varargs macros. These examples are taken from C99 6.10.3.5. +#define debug(...) fprintf (stderr, __VA_ARGS__) +#define showlist(...) puts (#__VA_ARGS__) +#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) +static void +test_varargs_macros (void) +{ + int x = 1234; + int y = 5678; + debug ("Flag"); + debug ("X = %d\n", x); + showlist (The first, second, and third items.); + report (x>y, "x is %d but y is %d", x, y); +} + +// Check long long types. +#define BIG64 18446744073709551615ull +#define BIG32 4294967295ul +#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) +#if !BIG_OK + your preprocessor is broken; +#endif +#if BIG_OK +#else + your preprocessor is broken; +#endif +static long long int bignum = -9223372036854775807LL; +static unsigned long long int ubignum = BIG64; + +struct incomplete_array +{ + int datasize; + double data[]; +}; + +struct named_init { + int number; + const wchar_t *name; + double average; +}; + +typedef const char *ccp; + +static inline int +test_restrict (ccp restrict text) +{ + // See if C++-style comments work. + // Iterate through items via the restricted pointer. + // Also check for declarations in for loops. + for (unsigned int i = 0; *(text+i) != '\0'; ++i) + continue; + return 0; +} + +// Check varargs and va_copy. +static void +test_varargs (const char *format, ...) +{ + va_list args; + va_start (args, format); + va_list args_copy; + va_copy (args_copy, args); + + const char *str; + int number; + float fnumber; + + while (*format) + { + switch (*format++) + { + case 's': // string + str = va_arg (args_copy, const char *); + break; + case 'd': // int + number = va_arg (args_copy, int); + break; + case 'f': // float + fnumber = va_arg (args_copy, double); + break; + default: + break; + } + } + va_end (args_copy); + va_end (args); +} + +int +main () +{ + + // Check bool. + _Bool success = false; + + // Check restrict. + if (test_restrict ("String literal") == 0) + success = true; + char *restrict newvar = "Another string"; + + // Check varargs. + test_varargs ("s, d' f .", "string", 65, 34.234); + test_varargs_macros (); + + // Check flexible array members. + struct incomplete_array *ia = + malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); + ia->datasize = 10; + for (int i = 0; i < ia->datasize; ++i) + ia->data[i] = i * 1.234; + + // Check named initializers. + struct named_init ni = { + .number = 34, + .name = L"Test wide string", + .average = 543.34343, + }; + + ni.number = 58; + + int dynamic_array[ni.number]; + dynamic_array[ni.number - 1] = 543; + + // work around unused variable warnings + return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x' + || dynamic_array[ni.number - 1] != 543); + + ; + return 0; +} +_ACEOF +for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc99 +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c99=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c99" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c99" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c99" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 +$as_echo "$ac_cv_prog_cc_c99" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c99" != xno; then : + ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99 +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if ${ac_cv_prog_cc_c89+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdarg.h> +#include <stdio.h> +struct stat; +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg +fi +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : + ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89 +else + ac_cv_prog_cc_stdc=no +fi + +fi + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO Standard C" >&5 +$as_echo_n "checking for $CC option to accept ISO Standard C... " >&6; } + if ${ac_cv_prog_cc_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +fi + + case $ac_cv_prog_cc_stdc in #( + no) : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; #( + '') : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; #( + *) : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_stdc" >&5 +$as_echo "$ac_cv_prog_cc_stdc" >&6; } ;; +esac + + + + + + + + + + ac_fn_c_check_decl "$LINENO" "clearerr_unlocked" "ac_cv_have_decl_clearerr_unlocked" "$ac_includes_default" +if test "x$ac_cv_have_decl_clearerr_unlocked" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_CLEARERR_UNLOCKED $ac_have_decl +_ACEOF + + + + ac_fn_c_check_decl "$LINENO" "feof_unlocked" "ac_cv_have_decl_feof_unlocked" "$ac_includes_default" +if test "x$ac_cv_have_decl_feof_unlocked" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_FEOF_UNLOCKED $ac_have_decl +_ACEOF + + + + ac_fn_c_check_decl "$LINENO" "ferror_unlocked" "ac_cv_have_decl_ferror_unlocked" "$ac_includes_default" +if test "x$ac_cv_have_decl_ferror_unlocked" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_FERROR_UNLOCKED $ac_have_decl +_ACEOF + + + + ac_fn_c_check_decl "$LINENO" "fflush_unlocked" "ac_cv_have_decl_fflush_unlocked" "$ac_includes_default" +if test "x$ac_cv_have_decl_fflush_unlocked" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_FFLUSH_UNLOCKED $ac_have_decl +_ACEOF + + + + ac_fn_c_check_decl "$LINENO" "fgets_unlocked" "ac_cv_have_decl_fgets_unlocked" "$ac_includes_default" +if test "x$ac_cv_have_decl_fgets_unlocked" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_FGETS_UNLOCKED $ac_have_decl +_ACEOF + + + + ac_fn_c_check_decl "$LINENO" "fputc_unlocked" "ac_cv_have_decl_fputc_unlocked" "$ac_includes_default" +if test "x$ac_cv_have_decl_fputc_unlocked" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_FPUTC_UNLOCKED $ac_have_decl +_ACEOF + + + + ac_fn_c_check_decl "$LINENO" "fputs_unlocked" "ac_cv_have_decl_fputs_unlocked" "$ac_includes_default" +if test "x$ac_cv_have_decl_fputs_unlocked" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_FPUTS_UNLOCKED $ac_have_decl +_ACEOF + + + + ac_fn_c_check_decl "$LINENO" "fread_unlocked" "ac_cv_have_decl_fread_unlocked" "$ac_includes_default" +if test "x$ac_cv_have_decl_fread_unlocked" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_FREAD_UNLOCKED $ac_have_decl +_ACEOF + + + + ac_fn_c_check_decl "$LINENO" "fwrite_unlocked" "ac_cv_have_decl_fwrite_unlocked" "$ac_includes_default" +if test "x$ac_cv_have_decl_fwrite_unlocked" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_FWRITE_UNLOCKED $ac_have_decl +_ACEOF + + + + ac_fn_c_check_decl "$LINENO" "getc_unlocked" "ac_cv_have_decl_getc_unlocked" "$ac_includes_default" +if test "x$ac_cv_have_decl_getc_unlocked" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_GETC_UNLOCKED $ac_have_decl +_ACEOF + + + + ac_fn_c_check_decl "$LINENO" "getchar_unlocked" "ac_cv_have_decl_getchar_unlocked" "$ac_includes_default" +if test "x$ac_cv_have_decl_getchar_unlocked" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_GETCHAR_UNLOCKED $ac_have_decl +_ACEOF + + + + ac_fn_c_check_decl "$LINENO" "putc_unlocked" "ac_cv_have_decl_putc_unlocked" "$ac_includes_default" +if test "x$ac_cv_have_decl_putc_unlocked" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_PUTC_UNLOCKED $ac_have_decl +_ACEOF + + + + ac_fn_c_check_decl "$LINENO" "putchar_unlocked" "ac_cv_have_decl_putchar_unlocked" "$ac_includes_default" +if test "x$ac_cv_have_decl_putchar_unlocked" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_PUTCHAR_UNLOCKED $ac_have_decl +_ACEOF + + + + +$as_echo "#define USE_UNLOCKED_IO 1" >>confdefs.h + + + + + + : + + + + + + + : + + + + + + + : + + + + + + + : + + + + + + + : + + + + + + + : + + + + + + + : + + + + + + + : + + + + + + + : + + + + + + + : + + + + + + + : + + + + + + + : + + + + + + + : + + + + + + + + + +# Extract the first word of "texi2html", so it can be a program name with args. +set dummy texi2html; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_TEXI2HTML+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$TEXI2HTML"; then + ac_cv_prog_TEXI2HTML="$TEXI2HTML" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_TEXI2HTML="texi2html" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_TEXI2HTML" && ac_cv_prog_TEXI2HTML=":" +fi +fi +TEXI2HTML=$ac_cv_prog_TEXI2HTML +if test -n "$TEXI2HTML"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $TEXI2HTML" >&5 +$as_echo "$TEXI2HTML" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5 +$as_echo_n "checking for an ANSI C-conforming const... " >&6; } +if ${ac_cv_c_const+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main () +{ + +#ifndef __cplusplus + /* Ultrix mips cc rejects this sort of thing. */ + typedef int charset[2]; + const charset cs = { 0, 0 }; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *pcpcc; + char **ppc; + /* 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"; + pcpcc = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++pcpcc; + ppc = (char**) pcpcc; + pcpcc = (char const *const *) ppc; + { /* SCO 3.2v4 cc rejects this sort of thing. */ + char tx; + char *t = &tx; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + if (s) return 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 sort of thing, saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; } bx; + struct s *b = &bx; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + if (!foo) return 0; + } + return !cs[0] && !zero.x; +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_const=yes +else + ac_cv_c_const=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5 +$as_echo "$ac_cv_c_const" >&6; } +if test $ac_cv_c_const = no; then + +$as_echo "#define const /**/" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 +$as_echo_n "checking for inline... " >&6; } +if ${ac_cv_c_inline+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __cplusplus +typedef int foo_t; +static $ac_kw foo_t static_foo () {return 0; } +$ac_kw foo_t foo () {return 0; } +#endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_inline=$ac_kw +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test "$ac_cv_c_inline" != no && break +done + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 +$as_echo "$ac_cv_c_inline" >&6; } + +case $ac_cv_c_inline in + inline | yes) ;; + *) + case $ac_cv_c_inline in + no) ac_val=;; + *) ac_val=$ac_cv_c_inline;; + esac + cat >>confdefs.h <<_ACEOF +#ifndef __cplusplus +#define inline $ac_val +#endif +_ACEOF + ;; +esac + +# ---------------------------------------------------------------------- +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 +$as_echo_n "checking for dlopen in -ldl... " >&6; } +if ${ac_cv_lib_dl_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ldl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_dl_dlopen=yes +else + ac_cv_lib_dl_dlopen=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 +$as_echo "$ac_cv_lib_dl_dlopen" >&6; } +if test "x$ac_cv_lib_dl_dlopen" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBDL 1 +_ACEOF + + LIBS="-ldl $LIBS" + +fi + +# ---------------------------------------------------------------------- +ac_fn_c_check_type "$LINENO" "mode_t" "ac_cv_type_mode_t" "$ac_includes_default" +if test "x$ac_cv_type_mode_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define mode_t int +_ACEOF + +fi + +ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default" +if test "x$ac_cv_type_pid_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define pid_t int +_ACEOF + +fi + +ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" +if test "x$ac_cv_type_size_t" = xyes; then : + +else + +cat >>confdefs.h <<_ACEOF +#define size_t unsigned int +_ACEOF + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uid_t in sys/types.h" >&5 +$as_echo_n "checking for uid_t in sys/types.h... " >&6; } +if ${ac_cv_type_uid_t+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "uid_t" >/dev/null 2>&1; then : + ac_cv_type_uid_t=yes +else + ac_cv_type_uid_t=no +fi +rm -f conftest* + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_uid_t" >&5 +$as_echo "$ac_cv_type_uid_t" >&6; } +if test $ac_cv_type_uid_t = no; then + +$as_echo "#define uid_t int" >>confdefs.h + + +$as_echo "#define gid_t int" >>confdefs.h + +fi + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for long double with more range or precision than double" >&5 +$as_echo_n "checking for long double with more range or precision than double... " >&6; } +if ${ac_cv_type_long_double_wider+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <float.h> + long double const a[] = + { + 0.0L, DBL_MIN, DBL_MAX, DBL_EPSILON, + LDBL_MIN, LDBL_MAX, LDBL_EPSILON + }; + long double + f (long double x) + { + return ((x + (unsigned long int) 10) * (-1 / x) + a[0] + + (x ? f (x) : 'c')); + } + +int +main () +{ +static int test_array [1 - 2 * !((0 < ((DBL_MAX_EXP < LDBL_MAX_EXP) + + (DBL_MANT_DIG < LDBL_MANT_DIG) + - (LDBL_MAX_EXP < DBL_MAX_EXP) + - (LDBL_MANT_DIG < DBL_MANT_DIG))) + && (int) LDBL_EPSILON == 0 + )]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_type_long_double_wider=yes +else + ac_cv_type_long_double_wider=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_long_double_wider" >&5 +$as_echo "$ac_cv_type_long_double_wider" >&6; } + if test $ac_cv_type_long_double_wider = yes; then + +$as_echo "#define HAVE_LONG_DOUBLE_WIDER 1" >>confdefs.h + + fi + + ac_cv_c_long_double=$ac_cv_type_long_double_wider + if test $ac_cv_c_long_double = yes; then + +$as_echo "#define HAVE_LONG_DOUBLE 1" >>confdefs.h + + fi + +if test x$ac_cv_type_long_double = xno; then + snv_long_double=double +else + snv_long_double='long double' +fi + +cat >>confdefs.h <<_ACEOF +#define SNV_LONG_DOUBLE $snv_long_double +_ACEOF + +ac_fn_c_check_type "$LINENO" "long long" "ac_cv_type_long_long" "$ac_includes_default" +if test "x$ac_cv_type_long_long" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_LONG_LONG 1 +_ACEOF + + +fi +ac_fn_c_check_type "$LINENO" "uintmax_t" "ac_cv_type_uintmax_t" "$ac_includes_default" +if test "x$ac_cv_type_uintmax_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_UINTMAX_T 1 +_ACEOF + + +fi +ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" +if test "x$ac_cv_type_size_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_SIZE_T 1 +_ACEOF + + +fi +ac_fn_c_check_type "$LINENO" "wchar_t" "ac_cv_type_wchar_t" "$ac_includes_default" +if test "x$ac_cv_type_wchar_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_WCHAR_T 1 +_ACEOF + + +fi + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of char*" >&5 +$as_echo_n "checking size of char*... " >&6; } +if ${ac_cv_sizeof_charp+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (char*))" "ac_cv_sizeof_charp" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_charp" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (char*) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_charp=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_charp" >&5 +$as_echo "$ac_cv_sizeof_charp" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_CHARP $ac_cv_sizeof_charp +_ACEOF + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int" >&5 +$as_echo_n "checking size of int... " >&6; } +if ${ac_cv_sizeof_int+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_int" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (int) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_int=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5 +$as_echo "$ac_cv_sizeof_int" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_INT $ac_cv_sizeof_int +_ACEOF + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5 +$as_echo_n "checking size of long... " >&6; } +if ${ac_cv_sizeof_long+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_long" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (long) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_long=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5 +$as_echo "$ac_cv_sizeof_long" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_LONG $ac_cv_sizeof_long +_ACEOF + + +# The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of short" >&5 +$as_echo_n "checking size of short... " >&6; } +if ${ac_cv_sizeof_short+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (short))" "ac_cv_sizeof_short" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_short" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (short) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_short=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_short" >&5 +$as_echo "$ac_cv_sizeof_short" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_SHORT $ac_cv_sizeof_short +_ACEOF + + +# ---------------------------------------------------------------------- + +# ---------------------------------------------------------------------- +# Do all our own macros +# ---------------------------------------------------------------------- + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for unsigned long long int" >&5 +$as_echo_n "checking for unsigned long long int... " >&6; } +if ${ac_cv_type_unsigned_long_long_int+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_type_unsigned_long_long_int=yes + if test "x${ac_cv_prog_cc_c99-no}" = xno; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + /* For now, do not test the preprocessor; as of 2007 there are too many + implementations with broken preprocessors. Perhaps this can + be revisited in 2012. In the meantime, code should not expect + #if to work with literals wider than 32 bits. */ + /* Test literals. */ + long long int ll = 9223372036854775807ll; + long long int nll = -9223372036854775807LL; + unsigned long long int ull = 18446744073709551615ULL; + /* Test constant expressions. */ + typedef int a[((-9223372036854775807LL < 0 && 0 < 9223372036854775807ll) + ? 1 : -1)]; + typedef int b[(18446744073709551615ULL <= (unsigned long long int) -1 + ? 1 : -1)]; + int i = 63; +int +main () +{ +/* Test availability of runtime routines for shift and division. */ + long long int llmax = 9223372036854775807ll; + unsigned long long int ullmax = 18446744073709551615ull; + return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i) + | (llmax / ll) | (llmax % ll) + | (ull << 63) | (ull >> 63) | (ull << i) | (ull >> i) + | (ullmax / ull) | (ullmax % ull)); + ; + return 0; +} + +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + +else + ac_cv_type_unsigned_long_long_int=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_unsigned_long_long_int" >&5 +$as_echo "$ac_cv_type_unsigned_long_long_int" >&6; } + if test $ac_cv_type_unsigned_long_long_int = yes; then + +$as_echo "#define HAVE_UNSIGNED_LONG_LONG_INT 1" >>confdefs.h + + fi + + + stat_nsec_found=no + ac_fn_c_check_member "$LINENO" "struct stat" "st_mtim" "ac_cv_member_struct_stat_st_mtim" "#include <sys/stat.h> +" +if test "x$ac_cv_member_struct_stat_st_mtim" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_STAT_ST_MTIM 1 +_ACEOF + +stat_nsec_found=yes +fi +ac_fn_c_check_member "$LINENO" "struct stat" "st_mtimensec" "ac_cv_member_struct_stat_st_mtimensec" "#include <sys/stat.h> +" +if test "x$ac_cv_member_struct_stat_st_mtimensec" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_STAT_ST_MTIMENSEC 1 +_ACEOF + +stat_nsec_found=yes +fi +ac_fn_c_check_member "$LINENO" "struct stat" "st_mtimespec" "ac_cv_member_struct_stat_st_mtimespec" "#include <sys/stat.h> +" +if test "x$ac_cv_member_struct_stat_st_mtimespec" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_STAT_ST_MTIMESPEC 1 +_ACEOF + +stat_nsec_found=yes +fi + + for ac_func in strchr strlcpy snprintf dlopen utimensat clock_gettime +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing copysign" >&5 +$as_echo_n "checking for library containing copysign... " >&6; } +if ${ac_cv_search_copysign+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char copysign (); +int +main () +{ +return copysign (); + ; + return 0; +} +_ACEOF +for ac_lib in '' m; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_copysign=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_copysign+:} false; then : + break +fi +done +if ${ac_cv_search_copysign+:} false; then : + +else + ac_cv_search_copysign=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_copysign" >&5 +$as_echo "$ac_cv_search_copysign" >&6; } +ac_res=$ac_cv_search_copysign +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +$as_echo "#define HAVE_COPYSIGN 1" >>confdefs.h + +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing copysignl" >&5 +$as_echo_n "checking for library containing copysignl... " >&6; } +if ${ac_cv_search_copysignl+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char copysignl (); +int +main () +{ +return copysignl (); + ; + return 0; +} +_ACEOF +for ac_lib in '' m; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_copysignl=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_copysignl+:} false; then : + break +fi +done +if ${ac_cv_search_copysignl+:} false; then : + +else + ac_cv_search_copysignl=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_copysignl" >&5 +$as_echo "$ac_cv_search_copysignl" >&6; } +ac_res=$ac_cv_search_copysignl +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +$as_echo "#define HAVE_COPYSIGNL 1" >>confdefs.h + +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing modfl" >&5 +$as_echo_n "checking for library containing modfl... " >&6; } +if ${ac_cv_search_modfl+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char modfl (); +int +main () +{ +return modfl (); + ; + return 0; +} +_ACEOF +for ac_lib in '' m; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_modfl=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_modfl+:} false; then : + break +fi +done +if ${ac_cv_search_modfl+:} false; then : + +else + ac_cv_search_modfl=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_modfl" >&5 +$as_echo "$ac_cv_search_modfl" >&6; } +ac_res=$ac_cv_search_modfl +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +$as_echo "#define HAVE_MODFL 1" >>confdefs.h + +fi + + + # ---------------------------------------------------------------------- + # Check for the functions needed from libgen and libdl + # ---------------------------------------------------------------------- + + if test X$ac_cv_func_pathfind = Xyes; then + NEED_PATHFIND_TRUE= + NEED_PATHFIND_FALSE='#' +else + NEED_PATHFIND_TRUE='#' + NEED_PATHFIND_FALSE= +fi + + if test X$ac_cv_func_dlopen = Xyes + then DYNAMIC_AG=-export-dynamic + else DYNAMIC_AG="" + fi + + + for ac_header in libio.h ctype.h assert.h sys/resource.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + ac_fn_c_check_decl "$LINENO" "sigsetjmp" "ac_cv_have_decl_sigsetjmp" "#include <setjmp.h> +" +if test "x$ac_cv_have_decl_sigsetjmp" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_SIGSETJMP $ac_have_decl +_ACEOF + + ac_fn_c_check_decl "$LINENO" "sys_siglist" "ac_cv_have_decl_sys_siglist" "#include <signal.h> +/* NetBSD declares sys_siglist in unistd.h. */ +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif + +" +if test "x$ac_cv_have_decl_sys_siglist" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_SYS_SIGLIST $ac_have_decl +_ACEOF + + + for ac_func in putenv getdate_r utimes futimes +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 +$as_echo_n "checking for inline... " >&6; } +if ${ac_cv_c_inline+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifndef __cplusplus +typedef int foo_t; +static $ac_kw foo_t static_foo () {return 0; } +$ac_kw foo_t foo () {return 0; } +#endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_c_inline=$ac_kw +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test "$ac_cv_c_inline" != no && break +done + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5 +$as_echo "$ac_cv_c_inline" >&6; } + +case $ac_cv_c_inline in + inline | yes) ;; + *) + case $ac_cv_c_inline in + no) ac_val=;; + *) ac_val=$ac_cv_c_inline;; + esac + cat >>confdefs.h <<_ACEOF +#ifndef __cplusplus +#define inline $ac_val +#endif +_ACEOF + ;; +esac + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for long long int" >&5 +$as_echo_n "checking for long long int... " >&6; } +if ${ac_cv_type_long_long_int+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_cv_type_long_long_int=yes + if test "x${ac_cv_prog_cc_c99-no}" = xno; then + ac_cv_type_long_long_int=$ac_cv_type_unsigned_long_long_int + if test $ac_cv_type_long_long_int = yes; then + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <limits.h> + #ifndef LLONG_MAX + # define HALF \ + (1LL << (sizeof (long long int) * CHAR_BIT - 2)) + # define LLONG_MAX (HALF - 1 + HALF) + #endif +int +main () +{ +long long int n = 1; + int i; + for (i = 0; ; i++) + { + long long int m = n << i; + if (m >> i != n) + return 1; + if (LLONG_MAX / 2 < m) + break; + } + return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_type_long_long_int=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + fi + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_long_long_int" >&5 +$as_echo "$ac_cv_type_long_long_int" >&6; } + if test $ac_cv_type_long_long_int = yes; then + +$as_echo "#define HAVE_LONG_LONG_INT 1" >>confdefs.h + + fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if ${ac_cv_path_GREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_GREP" || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if ${ac_cv_path_EGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_EGREP" || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 +$as_echo_n "checking for fgrep... " >&6; } +if ${ac_cv_path_FGREP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 + then ac_cv_path_FGREP="$GREP -F" + else + if test -z "$FGREP"; then + ac_path_FGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in fgrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_FGREP" || continue +# Check for GNU ac_path_FGREP and select it if it is found. + # Check for GNU $ac_path_FGREP +case `"$ac_path_FGREP" --version 2>&1` in +*GNU*) + ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'FGREP' >> "conftest.nl" + "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_FGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_FGREP="$ac_path_FGREP" + ac_path_FGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_FGREP_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_FGREP"; then + as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 + fi +else + ac_cv_path_FGREP=$FGREP +fi + + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 +$as_echo "$ac_cv_path_FGREP" >&6; } + FGREP="$ac_cv_path_FGREP" + + + + + + + + + + +if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. +set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +PKG_CONFIG=$ac_cv_path_PKG_CONFIG +if test -n "$PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 +$as_echo "$PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_path_PKG_CONFIG"; then + ac_pt_PKG_CONFIG=$PKG_CONFIG + # Extract the first word of "pkg-config", so it can be a program name with args. +set dummy pkg-config; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $ac_pt_PKG_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + ;; +esac +fi +ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG +if test -n "$ac_pt_PKG_CONFIG"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 +$as_echo "$ac_pt_PKG_CONFIG" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_pt_PKG_CONFIG" = x; then + PKG_CONFIG="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + PKG_CONFIG=$ac_pt_PKG_CONFIG + fi +else + PKG_CONFIG="$ac_cv_path_PKG_CONFIG" +fi + +fi +if test -n "$PKG_CONFIG"; then + _pkg_min_version=0.9.0 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 +$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; } + if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + PKG_CONFIG="" + fi +fi + _guile_versions_to_search="2.2 2.0 1.8" + if test -n "$GUILE_EFFECTIVE_VERSION"; then + _guile_tmp="" + for v in $_guile_versions_to_search; do + if test "$v" = "$GUILE_EFFECTIVE_VERSION"; then + _guile_tmp=$v + fi + done + if test -z "$_guile_tmp"; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "searching for guile development files for versions $_guile_versions_to_search, but previously found $GUILE version $GUILE_EFFECTIVE_VERSION +See \`config.log' for more details" "$LINENO" 5; } + fi + _guile_versions_to_search=$GUILE_EFFECTIVE_VERSION + fi + GUILE_EFFECTIVE_VERSION="" + _guile_errors="" + for v in $_guile_versions_to_search; do + if test -z "$GUILE_EFFECTIVE_VERSION"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for guile $v" >&5 +$as_echo "$as_me: checking for guile $v" >&6;} + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"guile-\$v\""; } >&5 + ($PKG_CONFIG --exists --print-errors "guile-$v") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + GUILE_EFFECTIVE_VERSION=$v +fi + fi + done + + if test -z "$GUILE_EFFECTIVE_VERSION"; then + as_fn_error $? " +No Guile development packages were found. + +Please verify that you have Guile installed. If you installed Guile +from a binary distribution, please verify that you have also installed +the development packages. If you installed it yourself, you might need +to adjust your PKG_CONFIG_PATH; see the pkg-config man page for more. +" "$LINENO" 5 + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: found guile $GUILE_EFFECTIVE_VERSION" >&5 +$as_echo "$as_me: found guile $GUILE_EFFECTIVE_VERSION" >&6;} + + + + +# Check whether --with-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 + +# Prepare PATH_SEPARATOR. +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + # Determine PATH_SEPARATOR by trying to find /bin/sh in a PATH which + # contains only /bin. Note that ksh looks also at the FPATH variable, + # so we have to set that as well for the test. + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ + && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 \ + || PATH_SEPARATOR=';' + } +fi + +if test -n "$LD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld" >&5 +$as_echo_n "checking for ld... " >&6; } +elif test "$GCC" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 +$as_echo_n "checking for ld used by $CC... " >&6; } +elif test "$with_gnu_ld" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 +$as_echo_n "checking for GNU ld... " >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 +$as_echo_n "checking for non-GNU ld... " >&6; } +fi +if test -n "$LD"; then + # Let the user override the test with a path. + : +else + if ${acl_cv_path_LD+:} false; then : + $as_echo_n "(cached) " >&6 +else + + acl_cv_path_LD= # Final result of this test + ac_prog=ld # Program to search in $PATH + if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + acl_output=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + acl_output=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $acl_output in + # Accept absolute paths. + [\\/]* | ?:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the pathname of ld + acl_output=`echo "$acl_output" | sed 's%\\\\%/%g'` + while echo "$acl_output" | grep "$re_direlt" > /dev/null 2>&1; do + acl_output=`echo $acl_output | sed "s%$re_direlt%/%"` + done + # Got the pathname. No search in PATH is needed. + acl_cv_path_LD="$acl_output" + ac_prog= + ;; + "") + # If it fails, then pretend we aren't using GCC. + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac + fi + if test -n "$ac_prog"; then + # Search for $ac_prog in $PATH. + acl_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$acl_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + acl_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$acl_cv_path_LD" -v 2>&1 </dev/null` in + *GNU* | *'with BFD'*) + test "$with_gnu_ld" != no && break + ;; + *) + test "$with_gnu_ld" != yes && break + ;; + esac + fi + done + IFS="$acl_save_ifs" + fi + case $host in + *-*-aix*) + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined __powerpc64__ || defined _ARCH_PPC64 + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # The compiler produces 64-bit code. Add option '-b64' so that the + # linker groks 64-bit object files. + case "$acl_cv_path_LD " in + *" -b64 "*) ;; + *) acl_cv_path_LD="$acl_cv_path_LD -b64" ;; + esac + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + sparc64-*-netbsd*) + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined __sparcv9 || defined __arch64__ + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + +else + # The compiler produces 32-bit code. Add option '-m elf32_sparc' + # so that the linker groks 32-bit object files. + case "$acl_cv_path_LD " in + *" -m elf32_sparc "*) ;; + *) acl_cv_path_LD="$acl_cv_path_LD -m elf32_sparc" ;; + esac + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + esac + +fi + + LD="$acl_cv_path_LD" +fi +if test -n "$LD"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5 +$as_echo "$LD" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 +$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } +if ${acl_cv_prog_gnu_ld+:} false; then : + $as_echo_n "(cached) " >&6 +else + # I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 </dev/null` in +*GNU* | *'with BFD'*) + acl_cv_prog_gnu_ld=yes + ;; +*) + acl_cv_prog_gnu_ld=no + ;; +esac +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acl_cv_prog_gnu_ld" >&5 +$as_echo "$acl_cv_prog_gnu_ld" >&6; } +with_gnu_ld=$acl_cv_prog_gnu_ld + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shared library run path origin" >&5 +$as_echo_n "checking for shared library run path origin... " >&6; } +if ${acl_cv_rpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + + CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \ + ${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh + . ./conftest.sh + rm -f ./conftest.sh + acl_cv_rpath=done + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acl_cv_rpath" >&5 +$as_echo "$acl_cv_rpath" >&6; } + wl="$acl_cv_wl" + acl_libext="$acl_cv_libext" + acl_shlibext="$acl_cv_shlibext" + acl_libname_spec="$acl_cv_libname_spec" + acl_library_names_spec="$acl_cv_library_names_spec" + acl_hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec" + acl_hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator" + acl_hardcode_direct="$acl_cv_hardcode_direct" + acl_hardcode_minus_L="$acl_cv_hardcode_minus_L" + # Check whether --enable-rpath was given. +if test "${enable_rpath+set}" = set; then : + enableval=$enable_rpath; : +else + enable_rpath=yes +fi + + + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#ifdef _MSC_VER +MicrosoftCompiler +#endif + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "MicrosoftCompiler" >/dev/null 2>&1; then : + gl_asmext='asm' + gl_c_asm_opt='-c -Fa' + +else + gl_asmext='s' + gl_c_asm_opt='-S' + +fi +rm -f conftest* + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking host CPU and C ABI" >&5 +$as_echo_n "checking host CPU and C ABI... " >&6; } +if ${gl_cv_host_cpu_c_abi+:} false; then : + $as_echo_n "(cached) " >&6 +else + case "$host_cpu" in + + i[4567]86 ) + gl_cv_host_cpu_c_abi=i386 + ;; + + x86_64 ) + # On x86_64 systems, the C compiler may be generating code in one of + # these ABIs: + # - 64-bit instruction set, 64-bit pointers, 64-bit 'long': x86_64. + # - 64-bit instruction set, 64-bit pointers, 32-bit 'long': x86_64 + # with native Windows (mingw, MSVC). + # - 64-bit instruction set, 32-bit pointers, 32-bit 'long': x86_64-x32. + # - 32-bit instruction set, 32-bit pointers, 32-bit 'long': i386. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if (defined __x86_64__ || defined __amd64__ \ + || defined _M_X64 || defined _M_AMD64) + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined __ILP32__ || defined _ILP32 + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gl_cv_host_cpu_c_abi=x86_64-x32 +else + gl_cv_host_cpu_c_abi=x86_64 +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + gl_cv_host_cpu_c_abi=i386 +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + + alphaev[4-8] | alphaev56 | alphapca5[67] | alphaev6[78] ) + gl_cv_host_cpu_c_abi=alpha + ;; + + arm* | aarch64 ) + # Assume arm with EABI. + # On arm64 systems, the C compiler may be generating code in one of + # these ABIs: + # - aarch64 instruction set, 64-bit pointers, 64-bit 'long': arm64. + # - aarch64 instruction set, 32-bit pointers, 32-bit 'long': arm64-ilp32. + # - 32-bit instruction set, 32-bit pointers, 32-bit 'long': arm or armhf. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __aarch64__ + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined __ILP32__ || defined _ILP32 + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gl_cv_host_cpu_c_abi=arm64-ilp32 +else + gl_cv_host_cpu_c_abi=arm64 +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + # Don't distinguish little-endian and big-endian arm, since they + # don't require different machine code for simple operations and + # since the user can distinguish them through the preprocessor + # defines __ARMEL__ vs. __ARMEB__. + # But distinguish arm which passes floating-point arguments and + # return values in integer registers (r0, r1, ...) - this is + # gcc -mfloat-abi=soft or gcc -mfloat-abi=softfp - from arm which + # passes them in float registers (s0, s1, ...) and double registers + # (d0, d1, ...) - this is gcc -mfloat-abi=hard. GCC 4.6 or newer + # sets the preprocessor defines __ARM_PCS (for the first case) and + # __ARM_PCS_VFP (for the second case), but older GCC does not. + echo 'double ddd; void func (double dd) { ddd = dd; }' > conftest.c + # Look for a reference to the register d0 in the .s file. + { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $gl_c_asm_opt conftest.c' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; } >/dev/null 2>&1 + if LC_ALL=C grep 'd0,' conftest.$gl_asmext >/dev/null; then + gl_cv_host_cpu_c_abi=armhf + else + gl_cv_host_cpu_c_abi=arm + fi + rm -f conftest* + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + + hppa1.0 | hppa1.1 | hppa2.0* | hppa64 ) + # On hppa, the C compiler may be generating 32-bit code or 64-bit + # code. In the latter case, it defines _LP64 and __LP64__. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __LP64__ + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gl_cv_host_cpu_c_abi=hppa64 +else + gl_cv_host_cpu_c_abi=hppa +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + + ia64* ) + # On ia64 on HP-UX, the C compiler may be generating 64-bit code or + # 32-bit code. In the latter case, it defines _ILP32. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef _ILP32 + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gl_cv_host_cpu_c_abi=ia64-ilp32 +else + gl_cv_host_cpu_c_abi=ia64 +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + + mips* ) + # We should also check for (_MIPS_SZPTR == 64), but gcc keeps this + # at 32. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined _MIPS_SZLONG && (_MIPS_SZLONG == 64) + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gl_cv_host_cpu_c_abi=mips64 +else + # In the n32 ABI, _ABIN32 is defined, _ABIO32 is not defined (but + # may later get defined by <sgidefs.h>), and _MIPS_SIM == _ABIN32. + # In the 32 ABI, _ABIO32 is defined, _ABIN32 is not defined (but + # may later get defined by <sgidefs.h>), and _MIPS_SIM == _ABIO32. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if (_MIPS_SIM == _ABIN32) + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gl_cv_host_cpu_c_abi=mipsn32 +else + gl_cv_host_cpu_c_abi=mips +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + + powerpc* ) + # Different ABIs are in use on AIX vs. Mac OS X vs. Linux,*BSD. + # No need to distinguish them here; the caller may distinguish + # them based on the OS. + # On powerpc64 systems, the C compiler may still be generating + # 32-bit code. And on powerpc-ibm-aix systems, the C compiler may + # be generating 64-bit code. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined __powerpc64__ || defined _ARCH_PPC64 + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + # On powerpc64, there are two ABIs on Linux: The AIX compatible + # one and the ELFv2 one. The latter defines _CALL_ELF=2. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined _CALL_ELF && _CALL_ELF == 2 + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gl_cv_host_cpu_c_abi=powerpc64-elfv2 +else + gl_cv_host_cpu_c_abi=powerpc64 +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +else + gl_cv_host_cpu_c_abi=powerpc +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + + rs6000 ) + gl_cv_host_cpu_c_abi=powerpc + ;; + + riscv32 | riscv64 ) + # There are 2 architectures (with variants): rv32* and rv64*. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if __riscv_xlen == 64 + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + cpu=riscv64 +else + cpu=riscv32 +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + # There are 6 ABIs: ilp32, ilp32f, ilp32d, lp64, lp64f, lp64d. + # Size of 'long' and 'void *': + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined __LP64__ + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + main_abi=lp64 +else + main_abi=ilp32 +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + # Float ABIs: + # __riscv_float_abi_double: + # 'float' and 'double' are passed in floating-point registers. + # __riscv_float_abi_single: + # 'float' are passed in floating-point registers. + # __riscv_float_abi_soft: + # No values are passed in floating-point registers. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined __riscv_float_abi_double + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + float_abi=d +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined __riscv_float_abi_single + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + float_abi=f +else + float_abi='' +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + gl_cv_host_cpu_c_abi="${cpu}-${main_abi}${float_abi}" + ;; + + s390* ) + # On s390x, the C compiler may be generating 64-bit (= s390x) code + # or 31-bit (= s390) code. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined __LP64__ || defined __s390x__ + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gl_cv_host_cpu_c_abi=s390x +else + gl_cv_host_cpu_c_abi=s390 +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + + sparc | sparc64 ) + # UltraSPARCs running Linux have `uname -m` = "sparc64", but the + # C compiler still generates 32-bit code. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#if defined __sparcv9 || defined __arch64__ + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gl_cv_host_cpu_c_abi=sparc64 +else + gl_cv_host_cpu_c_abi=sparc +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ;; + + *) + gl_cv_host_cpu_c_abi="$host_cpu" + ;; + esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_host_cpu_c_abi" >&5 +$as_echo "$gl_cv_host_cpu_c_abi" >&6; } + + HOST_CPU=`echo "$gl_cv_host_cpu_c_abi" | sed -e 's/-.*//'` + HOST_CPU_C_ABI="$gl_cv_host_cpu_c_abi" + + + + # This was + # AC_DEFINE_UNQUOTED([__${HOST_CPU}__]) + # AC_DEFINE_UNQUOTED([__${HOST_CPU_C_ABI}__]) + # earlier, but KAI C++ 3.2d doesn't like this. + sed -e 's/-/_/g' >> confdefs.h <<EOF +#ifndef __${HOST_CPU}__ +#define __${HOST_CPU}__ 1 +#endif +#ifndef __${HOST_CPU_C_ABI}__ +#define __${HOST_CPU_C_ABI}__ 1 +#endif +EOF + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the common suffixes of directories in the library search path" >&5 +$as_echo_n "checking for the common suffixes of directories in the library search path... " >&6; } +if ${acl_cv_libdirstems+:} false; then : + $as_echo_n "(cached) " >&6 +else + acl_libdirstem=lib + acl_libdirstem2= + case "$host_os" in + solaris*) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for 64-bit host" >&5 +$as_echo_n "checking for 64-bit host... " >&6; } +if ${gl_cv_solaris_64bit+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef _LP64 + int ok; + #else + error fail + #endif + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gl_cv_solaris_64bit=yes +else + gl_cv_solaris_64bit=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_solaris_64bit" >&5 +$as_echo "$gl_cv_solaris_64bit" >&6; } + if test $gl_cv_solaris_64bit = yes; then + acl_libdirstem=lib/64 + case "$host_cpu" in + sparc*) acl_libdirstem2=lib/sparcv9 ;; + i*86 | x86_64) acl_libdirstem2=lib/amd64 ;; + esac + fi + ;; + *) + case "$gl_cv_host_cpu_c_abi" in + i386 | arm | armhf | arm64-ilp32 | hppa | ia64-ilp32 | mips | mipsn32 | powerpc | s390 | sparc) + ;; + *) # x86_64 | arm64 | hppa64 | ia64 | mips64 | powerpc64* | s390x | sparc64 | ... + searchpath=`(if test -f /usr/bin/gcc \ + && LC_ALL=C /usr/bin/gcc -print-search-dirs >/dev/null 2>/dev/null; then \ + LC_ALL=C /usr/bin/gcc -print-search-dirs; \ + else \ + LC_ALL=C $CC -print-search-dirs; \ + fi) 2>/dev/null \ + | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'` + if test -n "$searchpath"; then + acl_save_IFS="${IFS= }"; IFS=":" + for searchdir in $searchpath; do + if test -d "$searchdir"; then + case "$searchdir" in + */lib64/ | */lib64 ) acl_libdirstem=lib64 ;; + */../ | */.. ) + # Better ignore directories of this form. They are misleading. + ;; + *) searchdir=`cd "$searchdir" && pwd` + case "$searchdir" in + */lib64 ) acl_libdirstem=lib64 ;; + esac ;; + esac + fi + done + IFS="$acl_save_IFS" + fi + ;; + esac + ;; + esac + test -n "$acl_libdirstem2" || acl_libdirstem2="$acl_libdirstem" + acl_cv_libdirstems="$acl_libdirstem,$acl_libdirstem2" + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acl_cv_libdirstems" >&5 +$as_echo "$acl_cv_libdirstems" >&6; } + # Decompose acl_cv_libdirstems into acl_libdirstem and acl_libdirstem2. + acl_libdirstem=`echo "$acl_cv_libdirstems" | sed -e 's/,.*//'` + acl_libdirstem2=`echo "$acl_cv_libdirstems" | sed -e '/,/s/.*,//'` + + + + ac_header_dirent=no +for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do + as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh` +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5 +$as_echo_n "checking for $ac_hdr that defines DIR... " >&6; } +if eval \${$as_ac_Header+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/types.h> +#include <$ac_hdr> + +int +main () +{ +if ((DIR *) 0) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$as_ac_Header=yes" +else + eval "$as_ac_Header=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$as_ac_Header + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1 +_ACEOF + +ac_header_dirent=$ac_hdr; break +fi + +done +# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. +if test $ac_header_dirent = dirent.h; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 +$as_echo_n "checking for library containing opendir... " >&6; } +if ${ac_cv_search_opendir+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char opendir (); +int +main () +{ +return opendir (); + ; + return 0; +} +_ACEOF +for ac_lib in '' dir; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_opendir=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_opendir+:} false; then : + break +fi +done +if ${ac_cv_search_opendir+:} false; then : + +else + ac_cv_search_opendir=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 +$as_echo "$ac_cv_search_opendir" >&6; } +ac_res=$ac_cv_search_opendir +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5 +$as_echo_n "checking for library containing opendir... " >&6; } +if ${ac_cv_search_opendir+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char opendir (); +int +main () +{ +return opendir (); + ; + return 0; +} +_ACEOF +for ac_lib in '' x; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_opendir=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_opendir+:} false; then : + break +fi +done +if ${ac_cv_search_opendir+:} false; then : + +else + ac_cv_search_opendir=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5 +$as_echo "$ac_cv_search_opendir" >&6; } +ac_res=$ac_cv_search_opendir +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +fi + + + # ================= + # AC_CHECK_HEADERS + # ================= + for ac_header in \ + sys/mman.h sys/param.h sys/poll.h sys/procset.h \ + sys/select.h sys/socket.h sys/stropts.h sys/time.h \ + sys/un.h sys/wait.h dlfcn.h errno.h \ + fcntl.h libgen.h libintl.h memory.h \ + netinet/in.h setjmp.h stdbool.h sysexits.h \ + unistd.h utime.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + for ac_header in stdarg.h varargs.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + lo_have_arg_hdr=true;break +else + lo_have_arg_hdr=false +fi + +done + + + for ac_header in string.h strings.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + lo_have_str_hdr=true;break +else + lo_have_str_hdr=false +fi + +done + + + for ac_header in limits.h sys/limits.h values.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + lo_have_lim_hdr=true;break +else + lo_have_lim_hdr=false +fi + +done + + + for ac_header in inttypes.h stdint.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + lo_have_typ_hdr=true;break +else + lo_have_typ_hdr=false +fi + +done + + + + case "$host_os" in + cygwin*) + STDNORETURN_H='stdnoreturn.h' + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working stdnoreturn.h" >&5 +$as_echo_n "checking for working stdnoreturn.h... " >&6; } +if ${gl_cv_header_working_stdnoreturn_h+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdlib.h> + #include <stdnoreturn.h> + /* Do not check for 'noreturn' after the return type. + C11 allows it, but it's rarely done that way + and circa-2012 bleeding-edge GCC rejects it when given + -Werror=old-style-declaration. */ + noreturn void foo1 (void) { exit (0); } + _Noreturn void foo2 (void) { exit (0); } + int testit (int argc, char **argv) + { + if (argc & 1) + return 0; + (argv[0][0] ? foo1 : foo2) (); + } + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gl_cv_header_working_stdnoreturn_h=yes +else + gl_cv_header_working_stdnoreturn_h=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_header_working_stdnoreturn_h" >&5 +$as_echo "$gl_cv_header_working_stdnoreturn_h" >&6; } + if test $gl_cv_header_working_stdnoreturn_h = yes; then + STDNORETURN_H='' + else + STDNORETURN_H='stdnoreturn.h' + fi + ;; + esac + + if test -n "$STDNORETURN_H"; then + GL_GENERATE_STDNORETURN_H_TRUE= + GL_GENERATE_STDNORETURN_H_FALSE='#' +else + GL_GENERATE_STDNORETURN_H_TRUE='#' + GL_GENERATE_STDNORETURN_H_FALSE= +fi + + + + # ---------------------------------------------------------------------- + # check for various programs used during the build. + # On OS/X, "wchar.h" needs "runetype.h" to work properly. + # ---------------------------------------------------------------------- + for ac_header in runetype.h wchar.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" " + $ac_includes_default + #if HAVE_RUNETYPE_H + # include <runetype.h> + #endif + +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + # Check whether --enable-nls was given. +if test "${enable_nls+set}" = set; then : + enableval=$enable_nls; +fi + + if test "x$enable_nls" != "xno" && \ + test "X${ac_cv_header_libintl_h}" = Xyes; then : + + +$as_echo "#define ENABLE_NLS 1" >>confdefs.h + +fi + + # -------------------------------------------- + # Verify certain entries from AC_CHECK_HEADERS + # -------------------------------------------- + ${lo_have_arg_hdr} || \ + as_fn_error $? "you must have stdarg.h or varargs.h on your system" "$LINENO" 5 + + ${lo_have_str_hdr} || \ + as_fn_error $? "you must have string.h or strings.h on your system" "$LINENO" 5 + + ${lo_have_lim_hdr} || \ + as_fn_error $? "you must have one of limits.h, sys/limits.h or values.h" "$LINENO" 5 + + ${lo_have_typ_hdr} || \ + as_fn_error $? "you must have inttypes.h or stdint.h on your system" "$LINENO" 5 + + for f in sys_types sys_param sys_stat string errno stdlib memory setjmp + do eval as_ac_var=\${ac_cv_header_${f}_h} + test "X${as_ac_var}" = Xyes || { + as_fn_error $? "you must have ${f}.h on your system" "$LINENO" 5 + } + done + test "X${ac_cv_header_inttypes_h-no}" = Xyes || \ + echo '#include <stdint.h>' > inttypes.h + + # ---------------------------------------------------------------------- + # Checks for typedefs + # ---------------------------------------------------------------------- + ac_fn_c_check_type "$LINENO" "wchar_t" "ac_cv_type_wchar_t" "$ac_includes_default" +if test "x$ac_cv_type_wchar_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_WCHAR_T 1 +_ACEOF + + +fi + + ac_fn_c_check_type "$LINENO" "wint_t" "ac_cv_type_wint_t" " + $ac_includes_default + #if HAVE_RUNETYPE_H + # include <runetype.h> + #endif + #if HAVE_WCHAR_H + # include <wchar.h> + #endif + +" +if test "x$ac_cv_type_wint_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_WINT_T 1 +_ACEOF + + +fi + + ac_fn_c_check_type "$LINENO" "int8_t" "ac_cv_type_int8_t" "$ac_includes_default" +if test "x$ac_cv_type_int8_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_INT8_T 1 +_ACEOF + + +fi +ac_fn_c_check_type "$LINENO" "uint8_t" "ac_cv_type_uint8_t" "$ac_includes_default" +if test "x$ac_cv_type_uint8_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_UINT8_T 1 +_ACEOF + + +fi +ac_fn_c_check_type "$LINENO" "int16_t" "ac_cv_type_int16_t" "$ac_includes_default" +if test "x$ac_cv_type_int16_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_INT16_T 1 +_ACEOF + + +fi +ac_fn_c_check_type "$LINENO" "uint16_t" "ac_cv_type_uint16_t" "$ac_includes_default" +if test "x$ac_cv_type_uint16_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_UINT16_T 1 +_ACEOF + + +fi +ac_fn_c_check_type "$LINENO" "int32_t" "ac_cv_type_int32_t" "$ac_includes_default" +if test "x$ac_cv_type_int32_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_INT32_T 1 +_ACEOF + + +fi +ac_fn_c_check_type "$LINENO" "uint32_t" "ac_cv_type_uint32_t" "$ac_includes_default" +if test "x$ac_cv_type_uint32_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_UINT32_T 1 +_ACEOF + + +fi +ac_fn_c_check_type "$LINENO" "intptr_t" "ac_cv_type_intptr_t" "$ac_includes_default" +if test "x$ac_cv_type_intptr_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_INTPTR_T 1 +_ACEOF + + +fi +ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "$ac_includes_default" +if test "x$ac_cv_type_uintptr_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_UINTPTR_T 1 +_ACEOF + + +fi +ac_fn_c_check_type "$LINENO" "uint_t" "ac_cv_type_uint_t" "$ac_includes_default" +if test "x$ac_cv_type_uint_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_UINT_T 1 +_ACEOF + + +fi +ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default" +if test "x$ac_cv_type_pid_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_PID_T 1 +_ACEOF + + +fi +ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default" +if test "x$ac_cv_type_size_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_SIZE_T 1 +_ACEOF + + +fi +ac_fn_c_check_type "$LINENO" "ptrdiff_t" "ac_cv_type_ptrdiff_t" "$ac_includes_default" +if test "x$ac_cv_type_ptrdiff_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_PTRDIFF_T 1 +_ACEOF + + +fi + + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of char *" >&5 +$as_echo_n "checking size of char *... " >&6; } +if ${ac_cv_sizeof_char_p+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (char *))" "ac_cv_sizeof_char_p" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_char_p" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (char *) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_char_p=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_char_p" >&5 +$as_echo "$ac_cv_sizeof_char_p" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_CHAR_P $ac_cv_sizeof_char_p +_ACEOF + + + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int" >&5 +$as_echo_n "checking size of int... " >&6; } +if ${ac_cv_sizeof_int+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_int" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (int) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_int=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5 +$as_echo "$ac_cv_sizeof_int" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_INT $ac_cv_sizeof_int +_ACEOF + + + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5 +$as_echo_n "checking size of long... " >&6; } +if ${ac_cv_sizeof_long+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_long" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (long) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_long=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5 +$as_echo "$ac_cv_sizeof_long" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_LONG $ac_cv_sizeof_long +_ACEOF + + + # The cast to long int works around a bug in the HP C Compiler +# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of short" >&5 +$as_echo_n "checking size of short... " >&6; } +if ${ac_cv_sizeof_short+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (short))" "ac_cv_sizeof_short" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_short" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (short) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_short=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_short" >&5 +$as_echo "$ac_cv_sizeof_short" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_SHORT $ac_cv_sizeof_short +_ACEOF + + + + # ------------ + # AC_CHECK_LIB + # ------------ + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pathfind in -lgen" >&5 +$as_echo_n "checking for pathfind in -lgen... " >&6; } +if ${ac_cv_lib_gen_pathfind+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lgen $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char pathfind (); +int +main () +{ +return pathfind (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_gen_pathfind=yes +else + ac_cv_lib_gen_pathfind=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gen_pathfind" >&5 +$as_echo "$ac_cv_lib_gen_pathfind" >&6; } +if test "x$ac_cv_lib_gen_pathfind" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBGEN 1 +_ACEOF + + LIBS="-lgen $LIBS" + +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gettext in -lintl" >&5 +$as_echo_n "checking for gettext in -lintl... " >&6; } +if ${ac_cv_lib_intl_gettext+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lintl $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char gettext (); +int +main () +{ +return gettext (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_intl_gettext=yes +else + ac_cv_lib_intl_gettext=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_intl_gettext" >&5 +$as_echo "$ac_cv_lib_intl_gettext" >&6; } +if test "x$ac_cv_lib_intl_gettext" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBINTL 1 +_ACEOF + + LIBS="-lintl $LIBS" + +fi + + for ac_func in vprintf +do : + ac_fn_c_check_func "$LINENO" "vprintf" "ac_cv_func_vprintf" +if test "x$ac_cv_func_vprintf" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_VPRINTF 1 +_ACEOF + +ac_fn_c_check_func "$LINENO" "_doprnt" "ac_cv_func__doprnt" +if test "x$ac_cv_func__doprnt" = xyes; then : + +$as_echo "#define HAVE_DOPRNT 1" >>confdefs.h + +fi + +fi +done + + + for ac_header in vfork.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "vfork.h" "ac_cv_header_vfork_h" "$ac_includes_default" +if test "x$ac_cv_header_vfork_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_VFORK_H 1 +_ACEOF + +fi + +done + +for ac_func in fork vfork +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +if test "x$ac_cv_func_fork" = xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working fork" >&5 +$as_echo_n "checking for working fork... " >&6; } +if ${ac_cv_func_fork_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + ac_cv_func_fork_works=cross +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ + + /* By Ruediger Kuhlmann. */ + return fork () < 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_func_fork_works=yes +else + ac_cv_func_fork_works=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_fork_works" >&5 +$as_echo "$ac_cv_func_fork_works" >&6; } + +else + ac_cv_func_fork_works=$ac_cv_func_fork +fi +if test "x$ac_cv_func_fork_works" = xcross; then + case $host in + *-*-amigaos* | *-*-msdosdjgpp*) + # Override, as these systems have only a dummy fork() stub + ac_cv_func_fork_works=no + ;; + *) + ac_cv_func_fork_works=yes + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&5 +$as_echo "$as_me: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&2;} +fi +ac_cv_func_vfork_works=$ac_cv_func_vfork +if test "x$ac_cv_func_vfork" = xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working vfork" >&5 +$as_echo_n "checking for working vfork... " >&6; } +if ${ac_cv_func_vfork_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + ac_cv_func_vfork_works=cross +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Thanks to Paul Eggert for this test. */ +$ac_includes_default +#include <sys/wait.h> +#ifdef HAVE_VFORK_H +# include <vfork.h> +#endif +/* On some sparc systems, changes by the child to local and incoming + argument registers are propagated back to the parent. The compiler + is told about this with #include <vfork.h>, but some compilers + (e.g. gcc -O) don't grok <vfork.h>. Test for this by using a + static variable whose address is put into a register that is + clobbered by the vfork. */ +static void +#ifdef __cplusplus +sparc_address_test (int arg) +# else +sparc_address_test (arg) int arg; +#endif +{ + static pid_t child; + if (!child) { + child = vfork (); + if (child < 0) { + perror ("vfork"); + _exit(2); + } + if (!child) { + arg = getpid(); + write(-1, "", 0); + _exit (arg); + } + } +} + +int +main () +{ + pid_t parent = getpid (); + pid_t child; + + sparc_address_test (0); + + child = vfork (); + + if (child == 0) { + /* Here is another test for sparc vfork register problems. This + test uses lots of local variables, at least as many local + variables as main has allocated so far including compiler + temporaries. 4 locals are enough for gcc 1.40.3 on a Solaris + 4.1.3 sparc, but we use 8 to be safe. A buggy compiler should + reuse the register of parent for one of the local variables, + since it will think that parent can't possibly be used any more + in this routine. Assigning to the local variable will thus + munge parent in the parent process. */ + pid_t + p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(), + p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid(); + /* Convince the compiler that p..p7 are live; otherwise, it might + use the same hardware register for all 8 local variables. */ + if (p != p1 || p != p2 || p != p3 || p != p4 + || p != p5 || p != p6 || p != p7) + _exit(1); + + /* On some systems (e.g. IRIX 3.3), vfork doesn't separate parent + from child file descriptors. If the child closes a descriptor + before it execs or exits, this munges the parent's descriptor + as well. Test for this by closing stdout in the child. */ + _exit(close(fileno(stdout)) != 0); + } else { + int status; + struct stat st; + + while (wait(&status) != child) + ; + return ( + /* Was there some problem with vforking? */ + child < 0 + + /* Did the child fail? (This shouldn't happen.) */ + || status + + /* Did the vfork/compiler bug occur? */ + || parent != getpid() + + /* Did the file descriptor bug occur? */ + || fstat(fileno(stdout), &st) != 0 + ); + } +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_func_vfork_works=yes +else + ac_cv_func_vfork_works=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_vfork_works" >&5 +$as_echo "$ac_cv_func_vfork_works" >&6; } + +fi; +if test "x$ac_cv_func_fork_works" = xcross; then + ac_cv_func_vfork_works=$ac_cv_func_vfork + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&5 +$as_echo "$as_me: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&2;} +fi + +if test "x$ac_cv_func_vfork_works" = xyes; then + +$as_echo "#define HAVE_WORKING_VFORK 1" >>confdefs.h + +else + +$as_echo "#define vfork fork" >>confdefs.h + +fi +if test "x$ac_cv_func_fork_works" = xyes; then + +$as_echo "#define HAVE_WORKING_FORK 1" >>confdefs.h + +fi + + for ac_func in mmap canonicalize_file_name snprintf strdup strchr \ + strrchr strsignal fchmod fstat chmod +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +$as_echo_n "checking for a sed that does not truncate output... " >&6; } +if ${ac_cv_path_SED+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + as_fn_executable_p "$ac_path_SED" || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +$as_echo "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + + while : + do + test -x "$POSIX_SHELL" && break + POSIX_SHELL=`which bash` + test -x "$POSIX_SHELL" && break + POSIX_SHELL=`which dash` + test -x "$POSIX_SHELL" && break + POSIX_SHELL=/usr/xpg4/bin/sh + test -x "$POSIX_SHELL" && break + POSIX_SHELL=`/bin/sh -c ' + exec 2>/dev/null + if ! true ; then exit 1 ; fi + echo /bin/sh'` + test -x "$POSIX_SHELL" && break + as_fn_error $? "cannot locate a working POSIX shell" "$LINENO" 5 + done + +cat >>confdefs.h <<_ACEOF +#define POSIX_SHELL "${POSIX_SHELL}" +_ACEOF + + + + + + # Check to see if shell scripts are desired. + + # Check whether --enable-shell was given. +if test "${enable_shell+set}" = set; then : + enableval=$enable_shell; ag_cv_enable_shell=${enable_shell} +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether shell scripts are desired" >&5 +$as_echo_n "checking whether shell scripts are desired... " >&6; } +if ${ag_cv_enable_shell+:} false; then : + $as_echo_n "(cached) " >&6 +else + ag_cv_enable_shell=yes +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ag_cv_enable_shell" >&5 +$as_echo "$ag_cv_enable_shell" >&6; } + +fi + # end of AC_ARG_ENABLE + if test "X${ag_cv_enable_shell}" != Xno + then + for ac_header in vfork.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "vfork.h" "ac_cv_header_vfork_h" "$ac_includes_default" +if test "x$ac_cv_header_vfork_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_VFORK_H 1 +_ACEOF + +fi + +done + +for ac_func in fork vfork +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + +if test "x$ac_cv_func_fork" = xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working fork" >&5 +$as_echo_n "checking for working fork... " >&6; } +if ${ac_cv_func_fork_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + ac_cv_func_fork_works=cross +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ + + /* By Ruediger Kuhlmann. */ + return fork () < 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_func_fork_works=yes +else + ac_cv_func_fork_works=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_fork_works" >&5 +$as_echo "$ac_cv_func_fork_works" >&6; } + +else + ac_cv_func_fork_works=$ac_cv_func_fork +fi +if test "x$ac_cv_func_fork_works" = xcross; then + case $host in + *-*-amigaos* | *-*-msdosdjgpp*) + # Override, as these systems have only a dummy fork() stub + ac_cv_func_fork_works=no + ;; + *) + ac_cv_func_fork_works=yes + ;; + esac + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&5 +$as_echo "$as_me: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&2;} +fi +ac_cv_func_vfork_works=$ac_cv_func_vfork +if test "x$ac_cv_func_vfork" = xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working vfork" >&5 +$as_echo_n "checking for working vfork... " >&6; } +if ${ac_cv_func_vfork_works+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "$cross_compiling" = yes; then : + ac_cv_func_vfork_works=cross +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Thanks to Paul Eggert for this test. */ +$ac_includes_default +#include <sys/wait.h> +#ifdef HAVE_VFORK_H +# include <vfork.h> +#endif +/* On some sparc systems, changes by the child to local and incoming + argument registers are propagated back to the parent. The compiler + is told about this with #include <vfork.h>, but some compilers + (e.g. gcc -O) don't grok <vfork.h>. Test for this by using a + static variable whose address is put into a register that is + clobbered by the vfork. */ +static void +#ifdef __cplusplus +sparc_address_test (int arg) +# else +sparc_address_test (arg) int arg; +#endif +{ + static pid_t child; + if (!child) { + child = vfork (); + if (child < 0) { + perror ("vfork"); + _exit(2); + } + if (!child) { + arg = getpid(); + write(-1, "", 0); + _exit (arg); + } + } +} + +int +main () +{ + pid_t parent = getpid (); + pid_t child; + + sparc_address_test (0); + + child = vfork (); + + if (child == 0) { + /* Here is another test for sparc vfork register problems. This + test uses lots of local variables, at least as many local + variables as main has allocated so far including compiler + temporaries. 4 locals are enough for gcc 1.40.3 on a Solaris + 4.1.3 sparc, but we use 8 to be safe. A buggy compiler should + reuse the register of parent for one of the local variables, + since it will think that parent can't possibly be used any more + in this routine. Assigning to the local variable will thus + munge parent in the parent process. */ + pid_t + p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(), + p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid(); + /* Convince the compiler that p..p7 are live; otherwise, it might + use the same hardware register for all 8 local variables. */ + if (p != p1 || p != p2 || p != p3 || p != p4 + || p != p5 || p != p6 || p != p7) + _exit(1); + + /* On some systems (e.g. IRIX 3.3), vfork doesn't separate parent + from child file descriptors. If the child closes a descriptor + before it execs or exits, this munges the parent's descriptor + as well. Test for this by closing stdout in the child. */ + _exit(close(fileno(stdout)) != 0); + } else { + int status; + struct stat st; + + while (wait(&status) != child) + ; + return ( + /* Was there some problem with vforking? */ + child < 0 + + /* Did the child fail? (This shouldn't happen.) */ + || status + + /* Did the vfork/compiler bug occur? */ + || parent != getpid() + + /* Did the file descriptor bug occur? */ + || fstat(fileno(stdout), &st) != 0 + ); + } +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_func_vfork_works=yes +else + ac_cv_func_vfork_works=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_vfork_works" >&5 +$as_echo "$ac_cv_func_vfork_works" >&6; } + +fi; +if test "x$ac_cv_func_fork_works" = xcross; then + ac_cv_func_vfork_works=$ac_cv_func_vfork + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&5 +$as_echo "$as_me: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&2;} +fi + +if test "x$ac_cv_func_vfork_works" = xyes; then + +$as_echo "#define HAVE_WORKING_VFORK 1" >>confdefs.h + +else + +$as_echo "#define vfork fork" >>confdefs.h + +fi +if test "x$ac_cv_func_fork_works" = xyes; then + +$as_echo "#define HAVE_WORKING_FORK 1" >>confdefs.h + +fi + + fi + + + + # Check to see if using shell scripts. + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether using shell scripts" >&5 +$as_echo_n "checking whether using shell scripts... " >&6; } + if ${ag_cv_test_do_shell+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ag_cv_test_do_shell=`exec 2> /dev/null +test "x$ac_cv_func_fork_works" != xyes && \\ + test "x$ac_cv_func_vfork_works" != xyes && exit 1 +test "x$ag_cv_enable_shell" = xyes || exit 1 +echo yes` + if test $? -ne 0 || test -z "$ag_cv_test_do_shell" + then ag_cv_test_do_shell=no + fi + +fi + # end of CACHE_VAL of ag_cv_test_do_shell + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ag_cv_test_do_shell}" >&5 +$as_echo "${ag_cv_test_do_shell}" >&6; } + if test "X${ag_cv_test_do_shell}" != Xno + then + + + +$as_echo "#define SHELL_ENABLED 1" >>confdefs.h + +OPTS_TESTDIR=test +AGEN5_TESTS='$(SHELL_TESTS) $(NOSHELL_TESTS)' + else + OPTS_TESTDIR= +AGEN5_TESTS='$(NOSHELL_TESTS)' + fi + if test "X${ag_cv_test_do_shell}" != Xno; then + DO_SHELL_CMDS_TRUE= + DO_SHELL_CMDS_FALSE='#' +else + DO_SHELL_CMDS_TRUE='#' + DO_SHELL_CMDS_FALSE= +fi + + + + + # Check to see if statically link autogen to libopts. + + # Check whether --enable-static-autogen was given. +if test "${enable_static_autogen+set}" = set; then : + enableval=$enable_static_autogen; ag_cv_enable_static_autogen=${enable_static_autogen} +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether statically link autogen to libopts" >&5 +$as_echo_n "checking whether statically link autogen to libopts... " >&6; } +if ${ag_cv_enable_static_autogen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ag_cv_enable_static_autogen=no +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ag_cv_enable_static_autogen" >&5 +$as_echo "$ag_cv_enable_static_autogen" >&6; } + +fi + # end of AC_ARG_ENABLE + if test "X${ag_cv_enable_static_autogen}" != Xno + then + +$as_echo "#define STATIC_AUTOGEN_ENABLED 1" >>confdefs.h + + AG_STATIC_AUTOGEN="-static" + else + AG_STATIC_AUTOGEN='' + fi + + + + + # Check to see if setjmp() links okay. + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether setjmp() links okay" >&5 +$as_echo_n "checking whether setjmp() links okay... " >&6; } + if ${ag_cv_link_setjmp+:} false; then : + $as_echo_n "(cached) " >&6 +else + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <setjmp.h> +int +main () +{ +jmp_buf bf; +if (setjmp(bf)) + return 0; +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ag_cv_link_setjmp=yes +else + ag_cv_link_setjmp=no + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext # end of AC_LINK_IFELSE + +fi + # end of AC_CACHE_VAL for ag_cv_link_setjmp + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ag_cv_link_setjmp}" >&5 +$as_echo "${ag_cv_link_setjmp}" >&6; } + if test "X${ag_cv_link_setjmp}" != Xno + then + +$as_echo "#define HAVE_WORKING_SETJMP 1" >>confdefs.h + + fi + + + + # Check to see if __attribute__((format_arg(n))) works. + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether __attribute__((format_arg(n))) works" >&5 +$as_echo_n "checking whether __attribute__((format_arg(n))) works... " >&6; } + if ${ag_cv_compile_format_arg+:} false; then : + $as_echo_n "(cached) " >&6 +else + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdio.h> +char const * foo(char const * fmt, int v) __attribute__((format_arg(1))); +int +main () +{ + int i = 0; + printf(foo("argc is %d\n", i), i); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ag_cv_compile_format_arg=yes +else + ag_cv_compile_format_arg=no + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # end of AC_COMPILE_IFELSE + +fi + # end of AC_CACHE_VAL for ag_cv_compile_format_arg + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ag_cv_compile_format_arg}" >&5 +$as_echo "${ag_cv_compile_format_arg}" >&6; } + if test "X${ag_cv_compile_format_arg}" != Xno + then + format_arg_expansion="__attribute__((format_arg(_a)))" + else + format_arg_expansion="" + fi + +cat >>confdefs.h <<_ACEOF +#define ATTRIBUTE_FORMAT_ARG(_a) ${format_arg_expansion} +_ACEOF + + + + + # Check to see if sigsetjmp() links okay. + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether sigsetjmp() links okay" >&5 +$as_echo_n "checking whether sigsetjmp() links okay... " >&6; } + if ${ag_cv_link_sigsetjmp+:} false; then : + $as_echo_n "(cached) " >&6 +else + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <setjmp.h> +int +main () +{ +sigjmp_buf bf; +if (sigsetjmp(bf,0)) + return 0; +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ag_cv_link_sigsetjmp=yes +else + ag_cv_link_sigsetjmp=no + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext # end of AC_LINK_IFELSE + +fi + # end of AC_CACHE_VAL for ag_cv_link_sigsetjmp + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ag_cv_link_sigsetjmp}" >&5 +$as_echo "${ag_cv_link_sigsetjmp}" >&6; } + if test "X${ag_cv_link_sigsetjmp}" != Xno + then + +$as_echo "#define HAVE_WORKING_SIGSETJMP 1" >>confdefs.h + + fi + + + + # Check to see if a working libxml2 can be found. + + +# Check whether --with-libxml2 was given. +if test "${with_libxml2+set}" = set; then : + withval=$with_libxml2; ag_cv_with_libxml2_root=${with_libxml2} +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether with-libxml2 was specified" >&5 +$as_echo_n "checking whether with-libxml2 was specified... " >&6; } +if ${ag_cv_with_libxml2_root+:} false; then : + $as_echo_n "(cached) " >&6 +else + ag_cv_with_libxml2_root=no +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ag_cv_with_libxml2_root" >&5 +$as_echo "$ag_cv_with_libxml2_root" >&6; } + +fi + # end of AC_ARG_WITH libxml2 + + if test "${with_libxml2+set}" = set && \ + test "X${withval}" = Xno + then ## disabled by request + ag_cv_with_libxml2_root=no + ag_cv_with_libxml2_cflags=no + ag_cv_with_libxml2_libs=no + else + + +# Check whether --with-libxml2-cflags was given. +if test "${with_libxml2_cflags+set}" = set; then : + withval=$with_libxml2_cflags; ag_cv_with_libxml2_cflags=${with_libxml2_cflags} +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether with-libxml2-cflags was specified" >&5 +$as_echo_n "checking whether with-libxml2-cflags was specified... " >&6; } +if ${ag_cv_with_libxml2_cflags+:} false; then : + $as_echo_n "(cached) " >&6 +else + ag_cv_with_libxml2_cflags=no +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ag_cv_with_libxml2_cflags" >&5 +$as_echo "$ag_cv_with_libxml2_cflags" >&6; } + +fi + # end of AC_ARG_WITH libxml2-cflags + + +# Check whether --with-libxml2-libs was given. +if test "${with_libxml2_libs+set}" = set; then : + withval=$with_libxml2_libs; ag_cv_with_libxml2_libs=${with_libxml2_libs} +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether with-libxml2-libs was specified" >&5 +$as_echo_n "checking whether with-libxml2-libs was specified... " >&6; } +if ${ag_cv_with_libxml2_libs+:} false; then : + $as_echo_n "(cached) " >&6 +else + ag_cv_with_libxml2_libs=no +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ag_cv_with_libxml2_libs" >&5 +$as_echo "$ag_cv_with_libxml2_libs" >&6; } + +fi + # end of AC_ARG_WITH libxml2-libs + + case "X${ag_cv_with_libxml2_cflags}" in + Xyes|Xno|X ) + case "X${ag_cv_with_libxml2_root}" in + Xyes|Xno|X ) ag_cv_with_libxml2_cflags=no ;; + * ) ag_cv_with_libxml2_cflags=-I${ag_cv_with_libxml2_root}/include ;; + esac + esac + case "X${ag_cv_with_libxml2_libs}" in + Xyes|Xno|X ) + case "X${ag_cv_with_libxml2_root}" in + Xyes|Xno|X ) ag_cv_with_libxml2_libs=no ;; + * ) ag_cv_with_libxml2_libs="-L${ag_cv_with_libxml2_root}/lib -lxml2" ;; + esac + esac + ag_save_CPPFLAGS="${CPPFLAGS}" + ag_save_LIBS="${LIBS}" + case "X${ag_cv_with_libxml2_cflags}" in + Xyes|Xno|X ) + f=`xml2-config --cflags 2>/dev/null` || f='' + test -n "${f}" && ag_cv_with_libxml2_cflags="${f}" && \ + { $as_echo "$as_me:${as_lineno-$LINENO}: xml2-config used for CFLAGS: $f" >&5 +$as_echo "$as_me: xml2-config used for CFLAGS: $f" >&6;} ;; + esac + case "X${ag_cv_with_libxml2_libs}" in + Xyes|Xno|X ) + f=`xml2-config --libs 2>/dev/null` || f='' + test -n "${f}" && ag_cv_with_libxml2_libs="${f}" && \ + { $as_echo "$as_me:${as_lineno-$LINENO}: xml2-config used for LIBS: $f" >&5 +$as_echo "$as_me: xml2-config used for LIBS: $f" >&6;} ;; + esac + case "X${ag_cv_with_libxml2_cflags}" in + Xyes|Xno|X ) + ag_cv_with_libxml2_cflags="" ;; + * ) CPPFLAGS="${CPPFLAGS} ${ag_cv_with_libxml2_cflags}" ;; + esac + case "X${ag_cv_with_libxml2_libs}" in + Xyes|Xno|X ) + LIBS="${LIBS} -lxml2" + ag_cv_with_libxml2_libs="-lxml2" ;; + * ) + LIBS="${LIBS} ${ag_cv_with_libxml2_libs}" ;; + esac + LIBXML2_CFLAGS="" + LIBXML2_LIBS="" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether libxml2 can be linked with" >&5 +$as_echo_n "checking whether libxml2 can be linked with... " >&6; } + if ${ag_cv_with_libxml2+:} false; then : + $as_echo_n "(cached) " >&6 +else + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <libxml/parser.h> +#include <libxml/tree.h> + +int main () { +xmlDocPtr p = xmlParseFile( "mumble.xml" ); } +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ag_cv_with_libxml2=yes +else + ag_cv_with_libxml2=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext # end of AC_LINK_IFELSE + +fi + # end of AC_CACHE_VAL for ag_cv_with_libxml2 + fi ## disabled by request + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ag_cv_with_libxml2}" >&5 +$as_echo "${ag_cv_with_libxml2}" >&6; } + + + if test "X${ag_cv_with_libxml2}" != Xno + then + LIBXML2_CFLAGS="${ag_cv_with_libxml2_cflags}" + LIBXML2_LIBS="${ag_cv_with_libxml2_libs}" + CPPFLAGS="${ag_save_CPPFLAGS}" + LIBS="${ag_save_LIBS}" + + else + CPPFLAGS="${ag_save_CPPFLAGS}" + LIBS="${ag_save_LIBS}" + LIBXML2_CFLAGS='' + LIBXML2_LIBS='' + fi + + if test "X${ag_cv_with_libxml2}" != Xno; then + HAVE_XML_LIB_TRUE= + HAVE_XML_LIB_FALSE='#' +else + HAVE_XML_LIB_TRUE='#' + HAVE_XML_LIB_FALSE= +fi + + + + + # Check to see if sysinfo(2) is Solaris. + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether sysinfo(2) is Solaris" >&5 +$as_echo_n "checking whether sysinfo(2) is Solaris... " >&6; } + if ${ag_cv_run_solaris_sysinfo+:} false; then : + $as_echo_n "(cached) " >&6 +else + + if test "$cross_compiling" = yes; then : + ag_cv_run_solaris_sysinfo=no + +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/systeminfo.h> +int main() { char z[ 256 ]; +long sz = sysinfo(SI_SYSNAME, z, sizeof(z)); +return (sz > 0) ? 0 : 1; } +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ag_cv_run_solaris_sysinfo=yes +else + ag_cv_run_solaris_sysinfo=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + # end of RUN_IFELSE + +fi + # end of AC_CACHE_VAL for ag_cv_run_solaris_sysinfo + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ag_cv_run_solaris_sysinfo}" >&5 +$as_echo "${ag_cv_run_solaris_sysinfo}" >&6; } + if test "X${ag_cv_run_solaris_sysinfo}" != Xno + then + +$as_echo "#define HAVE_SOLARIS_SYSINFO 1" >>confdefs.h + + fi + + + + # Check to see if specify an autogen timeout. + + # Check whether --enable-timeout was given. +if test "${enable_timeout+set}" = set; then : + enableval=$enable_timeout; ag_cv_enable_timeout=${enable_timeout} +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether specify an autogen timeout" >&5 +$as_echo_n "checking whether specify an autogen timeout... " >&6; } +if ${ag_cv_enable_timeout+:} false; then : + $as_echo_n "(cached) " >&6 +else + ag_cv_enable_timeout=no +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ag_cv_enable_timeout" >&5 +$as_echo "$ag_cv_enable_timeout" >&6; } + +fi + # end of AC_ARG_ENABLE + if test "X${ag_cv_enable_timeout}" != Xno + then + +$as_echo "#define TIMEOUT_ENABLED 1" >>confdefs.h + + AG_TIMEOUT="${ag_cv_enable_timeout}" + else + AG_TIMEOUT='' + fi + + + + + # Check to see if strcspn matches prototype and works. + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether strcspn matches prototype and works" >&5 +$as_echo_n "checking whether strcspn matches prototype and works... " >&6; } + if ${ag_cv_run_strcspn+:} false; then : + $as_echo_n "(cached) " >&6 +else + + if test "$cross_compiling" = yes; then : + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot run test program while cross compiling +See \`config.log' for more details" "$LINENO" 5; } +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <string.h> +int main (int argc, char ** argv) { + char zRej[] = reject; + char zAcc[] = "a-ok-eject"; + return strcspn( zAcc, zRej ) - 5; +} + ag_cv_run_strcspn=yes +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ag_cv_run_strcspn=no +else + ag_cv_run_strcspn=no + +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + # end of RUN_IFELSE + +fi + # end of AC_CACHE_VAL for ag_cv_run_strcspn + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ag_cv_run_strcspn}" >&5 +$as_echo "${ag_cv_run_strcspn}" >&6; } + if test "X${ag_cv_run_strcspn}" != Xno + then + +$as_echo "#define HAVE_STRCSPN 1" >>confdefs.h + + else + COMPATOBJ="$COMPATOBJ strcspn.lo" + fi + + + + # Check to see if uname(2) is POSIX. + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether uname(2) is POSIX" >&5 +$as_echo_n "checking whether uname(2) is POSIX... " >&6; } + if ${ag_cv_run_uname_syscall+:} false; then : + $as_echo_n "(cached) " >&6 +else + + if test "$cross_compiling" = yes; then : + ag_cv_run_uname_syscall=no + +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <sys/utsname.h> +int main() { struct utsname unm; +return uname( &unm ); } +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ag_cv_run_uname_syscall=yes +else + ag_cv_run_uname_syscall=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + # end of RUN_IFELSE + +fi + # end of AC_CACHE_VAL for ag_cv_run_uname_syscall + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ag_cv_run_uname_syscall}" >&5 +$as_echo "${ag_cv_run_uname_syscall}" >&6; } + if test "X${ag_cv_run_uname_syscall}" != Xno + then + +$as_echo "#define HAVE_UNAME_SYSCALL 1" >>confdefs.h + + fi + + + + # Check to see if runtime library dirs can be specified. + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether runtime library dirs can be specified" >&5 +$as_echo_n "checking whether runtime library dirs can be specified... " >&6; } + if ${ag_cv_test_ldflags+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ag_cv_test_ldflags=`exec 2> /dev/null +echo 'int main() { return 0; }' > conftest.$ac_ext +libs="${LIBS}" +LIBS="${LIBS} -Wl,-R/tmp" +if (eval $ac_link) > /dev/null 2>&1 +then echo '-Wl,-R${libdir}' ; rm -f conftest* ; exit 0 ; fi +LIBS="${libs} -R/tmp" +if (eval $ac_link) > /dev/null 2>&1 +then echo '-R${libdir}' ; rm -f conftest* ; exit 0 ; fi +rm -f conftest* ; exit 1` + if test $? -ne 0 || test -z "$ag_cv_test_ldflags" + then ag_cv_test_ldflags=no + fi + +fi + # end of CACHE_VAL of ag_cv_test_ldflags + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ag_cv_test_ldflags}" >&5 +$as_echo "${ag_cv_test_ldflags}" >&6; } + if test "X${ag_cv_test_ldflags}" != Xno + then + AG_LDFLAGS="${ag_cv_test_ldflags}" + else + AG_LDFLAGS='' + fi + + + + + # Check to see if wanting autogen debugging. + + # Check whether --enable-debug was given. +if test "${enable_debug+set}" = set; then : + enableval=$enable_debug; ag_cv_enable_debug=${enable_debug} +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether wanting autogen debugging" >&5 +$as_echo_n "checking whether wanting autogen debugging... " >&6; } +if ${ag_cv_enable_debug+:} false; then : + $as_echo_n "(cached) " >&6 +else + ag_cv_enable_debug=no +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ag_cv_enable_debug" >&5 +$as_echo "$ag_cv_enable_debug" >&6; } + +fi + # end of AC_ARG_ENABLE + if test "X${ag_cv_enable_debug}" != Xno + then + +$as_echo "#define DEBUG_ENABLED 1" >>confdefs.h + + +$as_echo "#define DEBUG_ENABLED 1" >>confdefs.h + + f=`which dmalloc 2>/dev/null` + test -n "$f" && LIBS="${LIBS} -ldmalloc" + fi + + + + # Check to see if name of the packager of this software is supplied. + + +# Check whether --with-packager was given. +if test "${with_packager+set}" = set; then : + withval=$with_packager; ag_cv_with_group_packager=${with_packager} +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether name of the packager of this software is supplied" >&5 +$as_echo_n "checking whether name of the packager of this software is supplied... " >&6; } +if ${ag_cv_with_group_packager+:} false; then : + $as_echo_n "(cached) " >&6 +else + ag_cv_with_group_packager=no +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ag_cv_with_group_packager" >&5 +$as_echo "$ag_cv_with_group_packager" >&6; } + +fi + # end of AC_ARG_WITH + if test "X${ag_cv_with_group_packager}" != Xno + then + +cat >>confdefs.h <<_ACEOF +#define WITH_PACKAGER "${withval}" +_ACEOF + + fi + +# Check whether --with-packager-version was given. +if test "${with_packager_version+set}" = set; then : + withval=$with_packager_version; ag_cv_with_group_packager_version=${with_packager_version} +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether packager-specific version information is supplied" >&5 +$as_echo_n "checking whether packager-specific version information is supplied... " >&6; } +if ${ag_cv_with_group_packager_version+:} false; then : + $as_echo_n "(cached) " >&6 +else + ag_cv_with_group_packager_version=no +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ag_cv_with_group_packager_version" >&5 +$as_echo "$ag_cv_with_group_packager_version" >&6; } + +fi + # end of AC_ARG_WITH + if test "X${ag_cv_with_group_packager_version}" != Xno + then + +cat >>confdefs.h <<_ACEOF +#define WITH_PACKAGER_VERSION "${withval}" +_ACEOF + + fi + +# Check whether --with-packager-bug-reports was given. +if test "${with_packager_bug_reports+set}" = set; then : + withval=$with_packager_bug_reports; ag_cv_with_group_packager_bug_reports=${with_packager_bug_reports} +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether bug reporting URI/e-mail/etc. is supplied" >&5 +$as_echo_n "checking whether bug reporting URI/e-mail/etc. is supplied... " >&6; } +if ${ag_cv_with_group_packager_bug_reports+:} false; then : + $as_echo_n "(cached) " >&6 +else + ag_cv_with_group_packager_bug_reports=no +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ag_cv_with_group_packager_bug_reports" >&5 +$as_echo "$ag_cv_with_group_packager_bug_reports" >&6; } + +fi + # end of AC_ARG_WITH + if test "X${ag_cv_with_group_packager_bug_reports}" != Xno + then + +cat >>confdefs.h <<_ACEOF +#define WITH_PACKAGER_BUG_REPORTS "${withval}" +_ACEOF + + fi + if test "X$with_packager" != "X" || \ + test "X$with_packager_version$with_packager_bug_reports" = "X" + then : + else + + as_fn_error $? "--with-packager-{bug-reports,version} require --with-packager" "$LINENO" 5 + fi + + + + +if test X${INVOKE_AG_MACROS_LAST_done} != Xyes ; then + + +pkg_failed=no +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GUILE" >&5 +$as_echo_n "checking for GUILE... " >&6; } + +if test -n "$GUILE_CFLAGS"; then + pkg_cv_GUILE_CFLAGS="$GUILE_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"guile-\$GUILE_EFFECTIVE_VERSION\""; } >&5 + ($PKG_CONFIG --exists --print-errors "guile-$GUILE_EFFECTIVE_VERSION") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_GUILE_CFLAGS=`$PKG_CONFIG --cflags "guile-$GUILE_EFFECTIVE_VERSION" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$GUILE_LIBS"; then + pkg_cv_GUILE_LIBS="$GUILE_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"guile-\$GUILE_EFFECTIVE_VERSION\""; } >&5 + ($PKG_CONFIG --exists --print-errors "guile-$GUILE_EFFECTIVE_VERSION") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_GUILE_LIBS=`$PKG_CONFIG --libs "guile-$GUILE_EFFECTIVE_VERSION" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + GUILE_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "guile-$GUILE_EFFECTIVE_VERSION" 2>&1` + else + GUILE_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "guile-$GUILE_EFFECTIVE_VERSION" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$GUILE_PKG_ERRORS" >&5 + + as_fn_error $? "Package requirements (guile-$GUILE_EFFECTIVE_VERSION) were not met: + +$GUILE_PKG_ERRORS + +Consider adjusting the PKG_CONFIG_PATH environment variable if you +installed software in a non-standard prefix. + +Alternatively, you may set the environment variables GUILE_CFLAGS +and GUILE_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details." "$LINENO" 5 +elif test $pkg_failed = untried; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it +is in your PATH or set the PKG_CONFIG environment variable to the full +path to pkg-config. + +Alternatively, you may set the environment variables GUILE_CFLAGS +and GUILE_LIBS to avoid the need to call pkg-config. +See the pkg-config man page for more details. + +To get pkg-config, see <http://pkg-config.freedesktop.org/>. +See \`config.log' for more details" "$LINENO" 5; } +else + GUILE_CFLAGS=$pkg_cv_GUILE_CFLAGS + GUILE_LIBS=$pkg_cv_GUILE_LIBS + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +fi + + + GUILE_LDFLAGS=$GUILE_LIBS + + + + + GUILE_LIBS= + if test "$enable_rpath" != no; then + if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then + rpathdirs= + next= + for opt in $GUILE_LDFLAGS; do + if test -n "$next"; then + dir="$next" + if test "X$dir" != "X/usr/$acl_libdirstem" \ + && test "X$dir" != "X/usr/$acl_libdirstem2"; then + rpathdirs="$rpathdirs $dir" + fi + next= + else + case $opt in + -L) next=yes ;; + -L*) dir=`echo "X$opt" | sed -e 's,^X-L,,'` + if test "X$dir" != "X/usr/$acl_libdirstem" \ + && test "X$dir" != "X/usr/$acl_libdirstem2"; then + rpathdirs="$rpathdirs $dir" + fi + next= ;; + *) next= ;; + esac + fi + done + if test "X$rpathdirs" != "X"; then + if test -n """"; then + for dir in $rpathdirs; do + GUILE_LIBS="${GUILE_LIBS}${GUILE_LIBS:+ }-R$dir" + done + else + if test -n "$acl_hardcode_libdir_separator"; then + alldirs= + for dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$dir" + done + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + GUILE_LIBS="$flag" + else + for dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$dir" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + GUILE_LIBS="${GUILE_LIBS}${GUILE_LIBS:+ }$flag" + done + fi + fi + fi + fi + fi + + + GUILE_LIBS="$GUILE_LDFLAGS $GUILE_LIBS" + + + + GUILE_LTLIBS= + if test "$enable_rpath" != no; then + if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then + rpathdirs= + next= + for opt in $GUILE_LDFLAGS; do + if test -n "$next"; then + dir="$next" + if test "X$dir" != "X/usr/$acl_libdirstem" \ + && test "X$dir" != "X/usr/$acl_libdirstem2"; then + rpathdirs="$rpathdirs $dir" + fi + next= + else + case $opt in + -L) next=yes ;; + -L*) dir=`echo "X$opt" | sed -e 's,^X-L,,'` + if test "X$dir" != "X/usr/$acl_libdirstem" \ + && test "X$dir" != "X/usr/$acl_libdirstem2"; then + rpathdirs="$rpathdirs $dir" + fi + next= ;; + *) next= ;; + esac + fi + done + if test "X$rpathdirs" != "X"; then + if test -n ""yes""; then + for dir in $rpathdirs; do + GUILE_LTLIBS="${GUILE_LTLIBS}${GUILE_LTLIBS:+ }-R$dir" + done + else + if test -n "$acl_hardcode_libdir_separator"; then + alldirs= + for dir in $rpathdirs; do + alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$dir" + done + acl_save_libdir="$libdir" + libdir="$alldirs" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + GUILE_LTLIBS="$flag" + else + for dir in $rpathdirs; do + acl_save_libdir="$libdir" + libdir="$dir" + eval flag=\"$acl_hardcode_libdir_flag_spec\" + libdir="$acl_save_libdir" + GUILE_LTLIBS="${GUILE_LTLIBS}${GUILE_LTLIBS:+ }$flag" + done + fi + fi + fi + fi + fi + + + GUILE_LTLIBS="$GUILE_LDFLAGS $GUILE_LTLIBS" + + + + + + + + test -x "${PKG_CONFIG}" || { + test -z "${PKG_CONFIG}" && PKG_CONFIG=pkg-config + f=`command -v ${PKG_CONFIG}` + test -x "${f}" && PKG_CONFIG="$f" + } + # Grab the first "-I" option that works + # + ag_gv=`gdir=\`${PKG_CONFIG} --cflags-only-I \ + guile-${GUILE_EFFECTIVE_VERSION} | \ + sed 's/ *-I/ /g'\` + test ${#gdir} -gt 1 || gdir=/usr/include + for d in $gdir + do test -f "$d/libguile/version.h" && gdir=$d && break + done + gdir=\`awk '/SCM_MICRO_VERSION/{ print $3 }' \ + "${gdir}/libguile/version.h"\` + test -n "$gdir" || exit 1 + IFS=' .' + set -- ${GUILE_EFFECTIVE_VERSION} + printf '%u%02u%03u' ${1} ${2} ${gdir} + ` + + test -n "$ag_gv" || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 1 "cannot determine Guile version +See \`config.log' for more details" "$LINENO" 5; } + test ${ag_gv} -ge 200000 || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "cannot use pre-2.0 Guile +See \`config.log' for more details" "$LINENO" 5; } + +cat >>confdefs.h <<_ACEOF +#define GUILE_VERSION ${ag_gv} +_ACEOF + + + + # Check to see if a reg expr header is specified. + + +# Check whether --with-regex-header was given. +if test "${with_regex_header+set}" = set; then : + withval=$with_regex_header; libopts_cv_with_regex_header=${with_regex_header} +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a reg expr header is specified" >&5 +$as_echo_n "checking whether a reg expr header is specified... " >&6; } +if ${libopts_cv_with_regex_header+:} false; then : + $as_echo_n "(cached) " >&6 +else + libopts_cv_with_regex_header=no +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libopts_cv_with_regex_header" >&5 +$as_echo "$libopts_cv_with_regex_header" >&6; } + +fi + # end of AC_ARG_WITH + if test "X${libopts_cv_with_regex_header}" != Xno + then + cat >>confdefs.h <<_ACEOF +#define REGEX_HEADER <${libopts_cv_with_regex_header}> +_ACEOF + + else + +$as_echo "#define REGEX_HEADER <regex.h>" >>confdefs.h + + fi + + + + # Check to see if a working libregex can be found. + + +# Check whether --with-libregex was given. +if test "${with_libregex+set}" = set; then : + withval=$with_libregex; libopts_cv_with_libregex_root=${with_libregex} +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether with-libregex was specified" >&5 +$as_echo_n "checking whether with-libregex was specified... " >&6; } +if ${libopts_cv_with_libregex_root+:} false; then : + $as_echo_n "(cached) " >&6 +else + libopts_cv_with_libregex_root=no +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libopts_cv_with_libregex_root" >&5 +$as_echo "$libopts_cv_with_libregex_root" >&6; } + +fi + # end of AC_ARG_WITH libregex + + if test "${with_libregex+set}" = set && \ + test "X${withval}" = Xno + then ## disabled by request + libopts_cv_with_libregex_root=no + libopts_cv_with_libregex_cflags=no + libopts_cv_with_libregex_libs=no + else + + +# Check whether --with-libregex-cflags was given. +if test "${with_libregex_cflags+set}" = set; then : + withval=$with_libregex_cflags; libopts_cv_with_libregex_cflags=${with_libregex_cflags} +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether with-libregex-cflags was specified" >&5 +$as_echo_n "checking whether with-libregex-cflags was specified... " >&6; } +if ${libopts_cv_with_libregex_cflags+:} false; then : + $as_echo_n "(cached) " >&6 +else + libopts_cv_with_libregex_cflags=no +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libopts_cv_with_libregex_cflags" >&5 +$as_echo "$libopts_cv_with_libregex_cflags" >&6; } + +fi + # end of AC_ARG_WITH libregex-cflags + + +# Check whether --with-libregex-libs was given. +if test "${with_libregex_libs+set}" = set; then : + withval=$with_libregex_libs; libopts_cv_with_libregex_libs=${with_libregex_libs} +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether with-libregex-libs was specified" >&5 +$as_echo_n "checking whether with-libregex-libs was specified... " >&6; } +if ${libopts_cv_with_libregex_libs+:} false; then : + $as_echo_n "(cached) " >&6 +else + libopts_cv_with_libregex_libs=no +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libopts_cv_with_libregex_libs" >&5 +$as_echo "$libopts_cv_with_libregex_libs" >&6; } + +fi + # end of AC_ARG_WITH libregex-libs + + case "X${libopts_cv_with_libregex_cflags}" in + Xyes|Xno|X ) + case "X${libopts_cv_with_libregex_root}" in + Xyes|Xno|X ) libopts_cv_with_libregex_cflags=no ;; + * ) libopts_cv_with_libregex_cflags=-I${libopts_cv_with_libregex_root}/include ;; + esac + esac + case "X${libopts_cv_with_libregex_libs}" in + Xyes|Xno|X ) + case "X${libopts_cv_with_libregex_root}" in + Xyes|Xno|X ) libopts_cv_with_libregex_libs=no ;; + * ) libopts_cv_with_libregex_libs="-L${libopts_cv_with_libregex_root}/lib -lregex" ;; + esac + esac + libopts_save_CPPFLAGS="${CPPFLAGS}" + libopts_save_LIBS="${LIBS}" + case "X${libopts_cv_with_libregex_cflags}" in + Xyes|Xno|X ) + libopts_cv_with_libregex_cflags="" ;; + * ) CPPFLAGS="${CPPFLAGS} ${libopts_cv_with_libregex_cflags}" ;; + esac + case "X${libopts_cv_with_libregex_libs}" in + Xyes|Xno|X ) + libopts_cv_with_libregex_libs="" ;; + * ) + LIBS="${LIBS} ${libopts_cv_with_libregex_libs}" ;; + esac + LIBREGEX_CFLAGS="" + LIBREGEX_LIBS="" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether libregex functions properly" >&5 +$as_echo_n "checking whether libregex functions properly... " >&6; } + if ${libopts_cv_with_libregex+:} false; then : + $as_echo_n "(cached) " >&6 +else + + if test "$cross_compiling" = yes; then : + libopts_cv_with_libregex=no +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include REGEX_HEADER +static regex_t re; +void comp_re(char const * pzPat) { + int res = regcomp( &re, pzPat, REG_EXTENDED|REG_ICASE|REG_NEWLINE ); + if (res == 0) return; + exit( res ); } +int main() { + regmatch_t m[2]; + comp_re( "^.*\$" ); + comp_re( "()|no.*" ); + comp_re( "." ); + if (regexec( &re, "X", 2, m, 0 ) != 0) return 1; + if ((m[0].rm_so != 0) || (m[0].rm_eo != 1)) { + fputs( "error: regex -->.<-- did not match\n", stderr ); + return 1; + } + return 0; } +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + libopts_cv_with_libregex=yes +else + libopts_cv_with_libregex=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + # end of AC_RUN_IFELSE + +fi + # end of AC_CACHE_VAL for libopts_cv_with_libregex + fi ## disabled by request + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${libopts_cv_with_libregex}" >&5 +$as_echo "${libopts_cv_with_libregex}" >&6; } + if test "X${libopts_cv_with_libregex}" != Xno + then + +$as_echo "#define WITH_LIBREGEX 1" >>confdefs.h + + else + CPPFLAGS="${libopts_save_CPPFLAGS}" + LIBS="${libopts_save_LIBS}" + libopts_cv_with_libregex_root=no +libopts_cv_with_libregex_cflags=no +libopts_cv_with_libregex_libs=no +libopts_cv_with_libregex=no + fi + + + + # Check to see if pathfind(3) works. + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pathfind(3) works" >&5 +$as_echo_n "checking whether pathfind(3) works... " >&6; } + if ${libopts_cv_run_pathfind+:} false; then : + $as_echo_n "(cached) " >&6 +else + + if test "$cross_compiling" = yes; then : + libopts_cv_run_pathfind=no + +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <string.h> +#include <stdlib.h> +int main (int argc, char ** argv) { + char * pz = pathfind( getenv( "PATH" ), "sh", "x" ); + return (pz == 0) ? 1 : 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + libopts_cv_run_pathfind=yes +else + libopts_cv_run_pathfind=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + # end of RUN_IFELSE + +fi + # end of AC_CACHE_VAL for libopts_cv_run_pathfind + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${libopts_cv_run_pathfind}" >&5 +$as_echo "${libopts_cv_run_pathfind}" >&6; } + if test "X${libopts_cv_run_pathfind}" != Xno + then + +$as_echo "#define HAVE_PATHFIND 1" >>confdefs.h + + fi + + + + # Check to see if /dev/zero is readable device. + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether /dev/zero is readable device" >&5 +$as_echo_n "checking whether /dev/zero is readable device... " >&6; } + if ${libopts_cv_test_dev_zero+:} false; then : + $as_echo_n "(cached) " >&6 +else + + libopts_cv_test_dev_zero=`exec 2> /dev/null +dzero=\`ls -lL /dev/zero | egrep ^c......r\` +test -z "${dzero}" && exit 1 +echo ${dzero}` + if test $? -ne 0 || test -z "$libopts_cv_test_dev_zero" + then libopts_cv_test_dev_zero=no + fi + +fi + # end of CACHE_VAL of libopts_cv_test_dev_zero + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${libopts_cv_test_dev_zero}" >&5 +$as_echo "${libopts_cv_test_dev_zero}" >&6; } + if test "X${libopts_cv_test_dev_zero}" != Xno + then + +$as_echo "#define HAVE_DEV_ZERO 1" >>confdefs.h + + fi + + + + # Check to see if we have a functional realpath(3C). + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we have a functional realpath(3C)" >&5 +$as_echo_n "checking whether we have a functional realpath(3C)... " >&6; } + if ${libopts_cv_run_realpath+:} false; then : + $as_echo_n "(cached) " >&6 +else + + if test "$cross_compiling" = yes; then : + libopts_cv_run_realpath=no + +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <limits.h> +#include <stdlib.h> +int main (int argc, char ** argv) { +#ifndef PATH_MAX +choke me!! +#else + char zPath[PATH_MAX+1]; +#endif + char *pz = realpath(argv[0], zPath); + return (pz == zPath) ? 0 : 1; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + libopts_cv_run_realpath=yes +else + libopts_cv_run_realpath=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + # end of RUN_IFELSE + +fi + # end of AC_CACHE_VAL for libopts_cv_run_realpath + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${libopts_cv_run_realpath}" >&5 +$as_echo "${libopts_cv_run_realpath}" >&6; } + if test "X${libopts_cv_run_realpath}" != Xno + then + +$as_echo "#define HAVE_REALPATH 1" >>confdefs.h + + fi + + + + # Check to see if strftime() works. + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether strftime() works" >&5 +$as_echo_n "checking whether strftime() works... " >&6; } + if ${libopts_cv_run_strftime+:} false; then : + $as_echo_n "(cached) " >&6 +else + + if test "$cross_compiling" = yes; then : + libopts_cv_run_strftime=no + +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <time.h> +#include <string.h> +char t_buf[ 64 ]; +int main() { + static char const z[] = "Thursday Aug 28 240"; + struct tm tm; + tm.tm_sec = 36; /* seconds after the minute [0, 61] */ + tm.tm_min = 44; /* minutes after the hour [0, 59] */ + tm.tm_hour = 12; /* hour since midnight [0, 23] */ + tm.tm_mday = 28; /* day of the month [1, 31] */ + tm.tm_mon = 7; /* months since January [0, 11] */ + tm.tm_year = 86; /* years since 1900 */ + tm.tm_wday = 4; /* days since Sunday [0, 6] */ + tm.tm_yday = 239; /* days since January 1 [0, 365] */ + tm.tm_isdst = 1; /* flag for daylight savings time */ + strftime( t_buf, sizeof( t_buf ), "%A %b %d %j", &tm ); + return (strcmp( t_buf, z ) != 0); } +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + libopts_cv_run_strftime=yes +else + libopts_cv_run_strftime=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + # end of RUN_IFELSE + +fi + # end of AC_CACHE_VAL for libopts_cv_run_strftime + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${libopts_cv_run_strftime}" >&5 +$as_echo "${libopts_cv_run_strftime}" >&6; } + if test "X${libopts_cv_run_strftime}" != Xno + then + +$as_echo "#define HAVE_STRFTIME 1" >>confdefs.h + + fi + + + + # Check to see if fopen accepts "b" mode. + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether fopen accepts \"b\" mode" >&5 +$as_echo_n "checking whether fopen accepts \"b\" mode... " >&6; } + if ${libopts_cv_run_fopen_binary+:} false; then : + $as_echo_n "(cached) " >&6 +else + + if test "$cross_compiling" = yes; then : + libopts_cv_run_fopen_binary=no + +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdio.h> +int main (int argc, char ** argv) { +FILE * fp = fopen("conftest.$ac_ext", "rb"); +return (fp == NULL) ? 1 : fclose(fp); } +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + libopts_cv_run_fopen_binary=yes +else + libopts_cv_run_fopen_binary=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + # end of RUN_IFELSE + +fi + # end of AC_CACHE_VAL for libopts_cv_run_fopen_binary + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${libopts_cv_run_fopen_binary}" >&5 +$as_echo "${libopts_cv_run_fopen_binary}" >&6; } + if test "X${libopts_cv_run_fopen_binary}" != Xno + then + +$as_echo "#define FOPEN_BINARY_FLAG \"b\"" >>confdefs.h + + else + +$as_echo "#define FOPEN_BINARY_FLAG \"\"" >>confdefs.h + + fi + + + + # Check to see if fopen accepts "t" mode. + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether fopen accepts \"t\" mode" >&5 +$as_echo_n "checking whether fopen accepts \"t\" mode... " >&6; } + if ${libopts_cv_run_fopen_text+:} false; then : + $as_echo_n "(cached) " >&6 +else + + if test "$cross_compiling" = yes; then : + libopts_cv_run_fopen_text=no + +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdio.h> +int main (int argc, char ** argv) { +FILE * fp = fopen("conftest.$ac_ext", "rt"); +return (fp == NULL) ? 1 : fclose(fp); } +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + libopts_cv_run_fopen_text=yes +else + libopts_cv_run_fopen_text=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + # end of RUN_IFELSE + +fi + # end of AC_CACHE_VAL for libopts_cv_run_fopen_text + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${libopts_cv_run_fopen_text}" >&5 +$as_echo "${libopts_cv_run_fopen_text}" >&6; } + if test "X${libopts_cv_run_fopen_text}" != Xno + then + +$as_echo "#define FOPEN_TEXT_FLAG \"t\"" >>confdefs.h + + else + +$as_echo "#define FOPEN_TEXT_FLAG \"\"" >>confdefs.h + + fi + + + + # Check to see if not wanting optional option args. + + # Check whether --enable-optional-args was given. +if test "${enable_optional_args+set}" = set; then : + enableval=$enable_optional_args; libopts_cv_enable_optional_args=${enable_optional_args} +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether not wanting optional option args" >&5 +$as_echo_n "checking whether not wanting optional option args... " >&6; } +if ${libopts_cv_enable_optional_args+:} false; then : + $as_echo_n "(cached) " >&6 +else + libopts_cv_enable_optional_args=yes +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libopts_cv_enable_optional_args" >&5 +$as_echo "$libopts_cv_enable_optional_args" >&6; } + +fi + # end of AC_ARG_ENABLE + if test "X${libopts_cv_enable_optional_args}" = Xno + then + +$as_echo "#define NO_OPTIONAL_OPT_ARGS 1" >>confdefs.h + + fi + + + + + + test "X${ac_cv_header_sys_wait_h}" = Xyes || \ + as_fn_error $? "you must have sys/wait.h on your system" "$LINENO" 5 + + for ac_func in fopencookie funopen +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + break +fi +done + + case "${ac_cv_func_fopencookie}${ac_cv_func_funopen}" in + *yes* ) + +$as_echo "#define ENABLE_FMEMOPEN 1" >>confdefs.h + + ;; + esac + + # Note that BSD does not typedef these in its headers, but instead + # calls for them to be identical in signature to read(2), write(2), + # lseek(2), and close(2). Newlib however does include typedefs + # in its stdio.h for these, and they do not match the signatures + # of the BSD implementation. So this test relies on the fact + # that any typedef will succeed for BSD, while only one that + # matches the existing definitions in stdio.h will succeed for + # a newlib system. + + if test "X${ac_cv_func_funopen}" = Xyes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cookie_function_t type" >&5 +$as_echo_n "checking for cookie_function_t type... " >&6; } +if ${ag_cv_cookie_function_t+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdio.h> + typedef int cookie_read_function_t (void *, char *, int); + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ag_cv_cookie_function_t="bsd" +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdio.h> + typedef ssize_t cookie_read_function_t (void *, char *, size_t); + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ag_cv_cookie_function_t="newlib" +else + as_fn_error $? "Unknown flavor of cookie_XXX_t types" "$LINENO" 5 +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ag_cv_cookie_function_t" >&5 +$as_echo "$ag_cv_cookie_function_t" >&6; } + fi + if test "X${ag_cv_cookie_function_t}" = Xbsd; then + +$as_echo "#define NEED_COOKIE_FUNCTION_TYPEDEFS 1" >>confdefs.h + + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for static inline" >&5 +$as_echo_n "checking for static inline... " >&6; } +if ${snv_cv_static_inline+:} false; then : + $as_echo_n "(cached) " >&6 +else + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +static inline foo(bar) int bar; { return bar; } +int +main () +{ +return foo(0); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + snv_cv_static_inline='static inline' +else + snv_cv_static_inline='static' +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $snv_cv_static_inline" >&5 +$as_echo "$snv_cv_static_inline" >&6; } + +cat >>confdefs.h <<_ACEOF +#define SNV_INLINE ${snv_cv_static_inline} +_ACEOF + + if test "X${libopts_cv_with_libregex}" = Xno + then + echo "A POSIX compliant regcomp/regexec routine is required. + These are required for AutoGen to work correctly. If you have + such a library present on your system, you must specify it by + setting the LIBS environment variable, e.g., \"LIBS='-lregex'\". + If you do not have such a library on your system, then you should + download and install, for example, the one from: + ftp://ftp.gnu.org/gnu/rx/" >&2 + as_fn_error $? "Cannot find working POSIX regex library" "$LINENO" 5 + fi + INVOKE_AG_MACROS_LAST_done=yes +fi + + +if ! test x$ag_cv_sys_siglist = xyes +then + if ! test x$ac_cv_func_strsignal = xyes + then + echo "WARNING: strsignal will use POSIX names and Linux signal numbers" + fi +fi >&2 +if test "X${ag_cv_link_sigsetjmp}" = Xno +then + as_fn_error $? "AutoGen requires sigsetjmp(3)" "$LINENO" 5 +fi + + + + case "$host_os" in + cygwin*) + STDNORETURN_H='stdnoreturn.h' + ;; + *) + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working stdnoreturn.h" >&5 +$as_echo_n "checking for working stdnoreturn.h... " >&6; } +if ${gl_cv_header_working_stdnoreturn_h+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <stdlib.h> + #include <stdnoreturn.h> + /* Do not check for 'noreturn' after the return type. + C11 allows it, but it's rarely done that way + and circa-2012 bleeding-edge GCC rejects it when given + -Werror=old-style-declaration. */ + noreturn void foo1 (void) { exit (0); } + _Noreturn void foo2 (void) { exit (0); } + int testit (int argc, char **argv) + { + if (argc & 1) + return 0; + (argv[0][0] ? foo1 : foo2) (); + } + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gl_cv_header_working_stdnoreturn_h=yes +else + gl_cv_header_working_stdnoreturn_h=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_header_working_stdnoreturn_h" >&5 +$as_echo "$gl_cv_header_working_stdnoreturn_h" >&6; } + if test $gl_cv_header_working_stdnoreturn_h = yes; then + STDNORETURN_H='' + else + STDNORETURN_H='stdnoreturn.h' + fi + ;; + esac + + if test -n "$STDNORETURN_H"; then + GL_GENERATE_STDNORETURN_H_TRUE= + GL_GENERATE_STDNORETURN_H_FALSE='#' +else + GL_GENERATE_STDNORETURN_H_TRUE='#' + GL_GENERATE_STDNORETURN_H_FALSE= +fi + + +# ---------------------------------------------------------------------- +# Do SNPRINTFV macros +# ---------------------------------------------------------------------- + + case $enable_snprintfv_convenience in + no) as_fn_error $? "this package needs a convenience snprintfv" "$LINENO" 5 ;; + "") enable_snprintfv_convenience=yes + ac_configure_args="$ac_configure_args --enable-snprintfv-convenience" ;; + esac + LIBSNPRINTFV='${top_builddir}/''snprintfv'/snprintfv/libsnprintfvc.la + INCSNPRINTFV='-I${top_builddir}/''snprintfv'' -I${top_srcdir}/''snprintfv' + + + + # ---------------------------------------------------------------------- + # Set up and process configure options + # ---------------------------------------------------------------------- + # Check whether --enable-snprintfv-install was given. +if test "${enable_snprintfv_install+set}" = set; then : + enableval=$enable_snprintfv_install; +fi + + if test x"${enable_snprintfv_install-no}" != xno; then + INSTALL_SNPRINTFV_TRUE= + INSTALL_SNPRINTFV_FALSE='#' +else + INSTALL_SNPRINTFV_TRUE='#' + INSTALL_SNPRINTFV_FALSE= +fi + + if test x"${enable_snprintfv_convenience-no}" != xno; then + CONVENIENCE_SNPRINTFV_TRUE= + CONVENIENCE_SNPRINTFV_FALSE='#' +else + CONVENIENCE_SNPRINTFV_TRUE='#' + CONVENIENCE_SNPRINTFV_FALSE= +fi + + if test x"${enable_subdir-no}" != xno; then + SUBDIR_SNPRINTFV_TRUE= + SUBDIR_SNPRINTFV_FALSE='#' +else + SUBDIR_SNPRINTFV_TRUE='#' + SUBDIR_SNPRINTFV_FALSE= +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if malloc debugging is wanted" >&5 +$as_echo_n "checking if malloc debugging is wanted... " >&6; } + +# Check whether --with-dmalloc was given. +if test "${with_dmalloc+set}" = set; then : + withval=$with_dmalloc; if test "$withval" = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +$as_echo "#define WITH_DMALLOC 1" >>confdefs.h + + LIBS="$LIBS -ldmalloc" + LDFLAGS="$LDFLAGS -g" +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + for ac_prog in gawk mawk 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 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + + + # ---------------------------------------------------------------------- + # check for various programs used during the build. + # On OS/X, "wchar.h" needs "runetype.h" to work properly. + # ---------------------------------------------------------------------- + for ac_header in runetype.h wchar.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" " + $ac_includes_default + #if HAVE_RUNETYPE_H + # include <runetype.h> + #endif + +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + case x$am_cv_prog_cc_stdc in + xno) + # Non ansi C => won't work with stdarg.h + ac_fn_c_check_header_mongrel "$LINENO" "varargs.h" "ac_cv_header_varargs_h" "$ac_includes_default" +if test "x$ac_cv_header_varargs_h" = xyes; then : + +fi + + + ;; + *) + case x$ac_cv_header_varargs_h in + xyes) + # Parent package is using varargs.h which is incompatible with + # stdarg.h, so we do the same. + ac_fn_c_check_header_mongrel "$LINENO" "varargs.h" "ac_cv_header_varargs_h" "$ac_includes_default" +if test "x$ac_cv_header_varargs_h" = xyes; then : + +fi + + + ;; + *) + # If stdarg.h is present define HAVE_STDARG_H, otherwise if varargs.h + # is present define HAVE_VARARGS_H. + for ac_header in stdarg.h varargs.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + break +fi + +done + + ;; + esac + ;; + esac + + case x$ac_cv_header_stdarg_h$ac_cv_header_varargs_h in + x*yes*) ;; + *) as_fn_error $? "Could not find either stdarg.h or varargs.h." "$LINENO" 5 ;; + esac + + # ---------------------------------------------------------------------- + # Checks for typedefs + # ---------------------------------------------------------------------- + ac_fn_c_check_type "$LINENO" "wchar_t" "ac_cv_type_wchar_t" "$ac_includes_default" +if test "x$ac_cv_type_wchar_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_WCHAR_T 1 +_ACEOF + + +fi + + ac_fn_c_check_type "$LINENO" "wint_t" "ac_cv_type_wint_t" " + $ac_includes_default + #if HAVE_RUNETYPE_H + # include <runetype.h> + #endif + #if HAVE_WCHAR_H + # include <wchar.h> + #endif + +" +if test "x$ac_cv_type_wint_t" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_WINT_T 1 +_ACEOF + + +fi + + ac_fn_c_check_type "$LINENO" "long double" "ac_cv_type_long_double" "$ac_includes_default" +if test "x$ac_cv_type_long_double" = xyes; then : + +cat >>confdefs.h <<_ACEOF +#define HAVE_LONG_DOUBLE 1 +_ACEOF + + +fi + + + # ---------------------------------------------------------------------- + # Checks for library calls + # ---------------------------------------------------------------------- + ac_fn_c_check_func "$LINENO" "strtoul" "ac_cv_func_strtoul" +if test "x$ac_cv_func_strtoul" = xyes; then : + $as_echo "#define HAVE_STRTOUL 1" >>confdefs.h + +else + case " $LIBOBJS " in + *" strtoul.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS strtoul.$ac_objext" + ;; +esac + +fi + +ac_fn_c_check_func "$LINENO" "ldexpl" "ac_cv_func_ldexpl" +if test "x$ac_cv_func_ldexpl" = xyes; then : + $as_echo "#define HAVE_LDEXPL 1" >>confdefs.h + +else + case " $LIBOBJS " in + *" ldexpl.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS ldexpl.$ac_objext" + ;; +esac + +fi + +ac_fn_c_check_func "$LINENO" "frexpl" "ac_cv_func_frexpl" +if test "x$ac_cv_func_frexpl" = xyes; then : + $as_echo "#define HAVE_FREXPL 1" >>confdefs.h + +else + case " $LIBOBJS " in + *" frexpl.$ac_objext "* ) ;; + *) LIBOBJS="$LIBOBJS frexpl.$ac_objext" + ;; +esac + +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for log in -lm" >&5 +$as_echo_n "checking for log in -lm... " >&6; } +if ${ac_cv_lib_m_log+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lm $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char log (); +int +main () +{ +return log (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_m_log=yes +else + ac_cv_lib_m_log=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_log" >&5 +$as_echo "$ac_cv_lib_m_log" >&6; } +if test "x$ac_cv_lib_m_log" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBM 1 +_ACEOF + + LIBS="-lm $LIBS" + +fi + + for ac_func in copysign copysignl +do : + as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" +if eval test \"x\$"$as_ac_var"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +# ---------------------------------------------------------------------- +# Generate the make files. +# ---------------------------------------------------------------------- +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 +$as_echo_n "checking whether ln -s works... " >&6; } +LN_S=$as_ln_s +if test "$LN_S" = "ln -s"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 +$as_echo "no, using $LN_S" >&6; } +fi + + +test -f ./snprintfv/snprintfv/snprintfv.h \ + && rm -f ./snprintfv/snprintfv.h \ + && ${LN_S} `pwd`/snprintfv/snprintfv/snprintfv.h ./snprintfv/ + +AGnam=autogen${ac_exeext} +GDnam=getdefs${ac_exeext} +CLnam=columns${ac_exeext} +if test "X$cross_compiling" = Xyes +then + AGexe=`which ${AGnam}` + GDexe=`which ${GDnam}` + CLexe=`which ${CLnam}` +else + AGexe=${ag_top_builddir}/agen5/${AGnam} + GDexe=${ag_top_builddir}/getdefs/${GDnam} + CLexe=${ag_top_builddir}/columns/${CLnam} +fi +M4_SRC=`cd $srcdir/config ; echo [a-z]*.m4` +ENABLE_STATIC=${enable_static} +config_end_time=`date +%s 2>/dev/null` +time_delta=`expr ${config_end_time} - ${config_start_time} 2>/dev/null` + +if test -z "${AG_TIMEOUT}" +then + if test -z "${time_delta}" + then time_delta=10 + elif test ${time_delta} -lt 5 + then time_delta=5 ; fi + + AG_TIMEOUT=${time_delta} +fi + + +cat >>confdefs.h <<_ACEOF +#define AG_DEFAULT_TIMEOUT ${AG_TIMEOUT} +_ACEOF + + + + + + + + + + + + + + +if test "$ag_top_srcdir" = "$ag_top_builddir" +then + INCLIST='-I${top_builddir} -I${top_srcdir}/autoopts' +else + INCLIST='-I${top_builddir} -I${top_srcdir}' + INCLIST="${INCLIST} -I\${top_builddir}/autoopts -I\${top_srcdir}/autoopts" +fi + +WARN_CFLAGS= +test "X${GCC}" = Xyes && { + CFLAGS="$CFLAGS -Wno-format-contains-nul -fno-strict-aliasing" + WARN_CFLAGS="$CFLAGS "`echo -Wall -Werror -Wcast-align -Wmissing-prototypes \ + -Wpointer-arith -Wshadow -Wstrict-prototypes -Wwrite-strings \ + -Wstrict-aliasing=3 -Wextra -Wno-cast-qual` +} +ac_config_headers="$ac_config_headers config.h:config-h.in" + + + + +ac_config_files="$ac_config_files autoopts/mk-autoopts-pc" + +ac_config_files="$ac_config_files autoopts/autoopts-config" + + +ac_config_files="$ac_config_files autoopts/tpl/tpl-config.tlib:autoopts/tpl/tpl-config-tlib.in" + +ac_config_files="$ac_config_files doc/auto_gen.tpl:doc/auto_gen-tpl.in" + +ac_config_files="$ac_config_files autoopts/test/defs config/mk-shdefs pkg/pkg-env Makefile agen5/Makefile agen5/test/Makefile autoopts/Makefile autoopts/test/Makefile columns/Makefile compat/Makefile doc/Makefile getdefs/Makefile getdefs/test/Makefile pkg/Makefile snprintfv/Makefile xml2ag/Makefile xml2ag/test/Makefile" + + +ac_config_commands="$ac_config_commands stamp-h" + +CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} +f=`${CONFIG_SHELL} -c 'echo true | ( + exec 2>/dev/null ; read -u0 line ; echo $line ; )'` +test X$f = Xtrue || CONFIG_SHELL=`command -v bash` + + +cat >>confdefs.h <<_ACEOF +#define CONFIG_SHELL $CONFIG_SHELL +_ACEOF + +cat >confcache <<\_ACEOF +# 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, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# 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. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) { eval $ac_var=; unset $ac_var;} ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes: double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \. + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + if test "x$cache_file" != "x/dev/null"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + if test ! -f "$cache_file" || test -h "$cache_file"; then + cat confcache >"$cache_file" + else + case $cache_file in #( + */* | ?:*) + mv -f confcache "$cache_file"$$ && + mv -f "$cache_file"$$ "$cache_file" ;; #( + *) + mv -f confcache "$cache_file" ;; + esac + fi + fi + else + { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +U= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" + as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 +$as_echo_n "checking that generated files are newer than configure... " >&6; } + if test -n "$am_sleep_pid"; then + # Hide warnings about reused PIDs. + wait $am_sleep_pid 2>/dev/null + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 +$as_echo "done" >&6; } + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' +else + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= +fi + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + as_fn_error $? "conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + as_fn_error $? "conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${NEED_PATHFIND_TRUE}" && test -z "${NEED_PATHFIND_FALSE}"; then + as_fn_error $? "conditional \"NEED_PATHFIND\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${DO_SHELL_CMDS_TRUE}" && test -z "${DO_SHELL_CMDS_FALSE}"; then + as_fn_error $? "conditional \"DO_SHELL_CMDS\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_XML_LIB_TRUE}" && test -z "${HAVE_XML_LIB_FALSE}"; then + as_fn_error $? "conditional \"HAVE_XML_LIB\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${GL_GENERATE_STDNORETURN_H_TRUE}" && test -z "${GL_GENERATE_STDNORETURN_H_FALSE}"; then + as_fn_error $? "conditional \"GL_GENERATE_STDNORETURN_H\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${GL_GENERATE_STDNORETURN_H_TRUE}" && test -z "${GL_GENERATE_STDNORETURN_H_FALSE}"; then + as_fn_error $? "conditional \"GL_GENERATE_STDNORETURN_H\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${INSTALL_SNPRINTFV_TRUE}" && test -z "${INSTALL_SNPRINTFV_FALSE}"; then + as_fn_error $? "conditional \"INSTALL_SNPRINTFV\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${CONVENIENCE_SNPRINTFV_TRUE}" && test -z "${CONVENIENCE_SNPRINTFV_FALSE}"; then + as_fn_error $? "conditional \"CONVENIENCE_SNPRINTFV\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${SUBDIR_SNPRINTFV_TRUE}" && test -z "${SUBDIR_SNPRINTFV_FALSE}"; then + as_fn_error $? "conditional \"SUBDIR_SNPRINTFV\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi + +: "${CONFIG_STATUS=./config.status}" +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +as_write_fail=0 +cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false + +SHELL=\${CONFIG_SHELL-$SHELL} +export SHELL +_ASEOF +cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 +## -------------------- ## +## M4sh Initialization. ## +## -------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in #( + *posix*) : + set -o posix ;; #( + *) : + ;; +esac +fi + + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +# Prefer a ksh shell builtin over an external printf program on Solaris, +# but without wasting forks for bash or zsh. +if test -z "$BASH_VERSION$ZSH_VERSION" \ + && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='print -r --' + as_echo_n='print -rn --' +elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in #( + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +as_myself= +case $0 in #(( + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break + done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + exit 1 +fi + +# Unset variables that we do not need and which cause bugs (e.g. in +# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" +# suppresses any "Segmentation fault" message there. '((' could +# trigger a bug in pdksh 5.2.14. +for as_var in BASH_ENV ENV MAIL MAILPATH +do eval test x\${$as_var+set} = xset \ + && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : +done +PS1='$ ' +PS2='> ' +## PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# CDPATH. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + + +# as_fn_error STATUS ERROR [LINENO LOG_FD] +# ---------------------------------------- +# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are +# provided, also output the error to LOG_FD, referencing LINENO. Then exit the +# script with STATUS, using 1 if that was 0. +as_fn_error () +{ + as_status=$1; test $as_status -eq 0 && as_status=1 + if test "$4"; then + as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 + fi + $as_echo "$as_me: error: $2" >&2 + as_fn_exit $as_status +} # as_fn_error + + +# as_fn_set_status STATUS +# ----------------------- +# Set $? to STATUS, without forking. +as_fn_set_status () +{ + return $1 +} # as_fn_set_status + +# as_fn_exit STATUS +# ----------------- +# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. +as_fn_exit () +{ + set +e + as_fn_set_status $1 + exit $1 +} # as_fn_exit + +# as_fn_unset VAR +# --------------- +# Portably unset VAR. +as_fn_unset () +{ + { eval $1=; unset $1;} +} +as_unset=as_fn_unset +# as_fn_append VAR VALUE +# ---------------------- +# Append the text in VALUE to the end of the definition contained in VAR. Take +# advantage of any shell optimizations that allow amortized linear growth over +# repeated appends, instead of the typical quadratic growth present in naive +# implementations. +if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : + eval 'as_fn_append () + { + eval $1+=\$2 + }' +else + as_fn_append () + { + eval $1=\$$1\$2 + } +fi # as_fn_append + +# as_fn_arith ARG... +# ------------------ +# Perform arithmetic evaluation on the ARGs, and store the result in the +# global $as_val. Take advantage of shells that can avoid forks. The arguments +# must be portable across $(()) and expr. +if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : + eval 'as_fn_arith () + { + as_val=$(( $* )) + }' +else + as_fn_arith () + { + as_val=`expr "$@" || test $? -eq 1` + } +fi # as_fn_arith + + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in #((((( +-n*) + case `echo 'xy\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + xy) ECHO_C='\c';; + *) echo `echo ksh88 bug on AIX 6.1` > /dev/null + ECHO_T=' ';; + esac;; +*) + ECHO_N='-n';; +esac + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -pR' + fi +else + as_ln_s='cp -pR' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + + +# as_fn_mkdir_p +# ------------- +# Create "$as_dir" as a directory, including parents if necessary. +as_fn_mkdir_p () +{ + + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || eval $as_mkdir_p || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" + + +} # as_fn_mkdir_p +if mkdir -p . 2>/dev/null; then + as_mkdir_p='mkdir -p "$as_dir"' +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + + +# as_fn_executable_p FILE +# ----------------------- +# Test if FILE is an executable regular file. +as_fn_executable_p () +{ + test -f "$1" && test -x "$1" +} # as_fn_executable_p +as_test_x='test -x' +as_executable_p=as_fn_executable_p + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 +## ----------------------------------- ## +## Main body of $CONFIG_STATUS script. ## +## ----------------------------------- ## +_ASEOF +test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# Save the log message, to keep $0 and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by GNU AutoGen $as_me 5.18.16, which was +generated by GNU Autoconf 2.69. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files and other configuration actions +from templates according to the current configuration. Unless the files +and actions are specified as TAGs, all are instantiated by default. + +Usage: $0 [OPTION]... [TAG]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + --config print configuration, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to <autogen-users@lists.sourceforge.net>. +GNU AutoGen home page: <http://www.gnu.org/software/autogen/>. +General help using GNU software: <http://www.gnu.org/gethelp/>." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" +ac_cs_version="\\ +GNU AutoGen config.status 5.18.16 +configured by $0, generated by GNU Autoconf 2.69, + with options \\"\$ac_cs_config\\" + +Copyright (C) 2012 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=?*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + --*=) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg= + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --config | --confi | --conf | --con | --co | --c ) + $as_echo "$ac_cs_config"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + '') as_fn_error $? "missing file argument" ;; + esac + as_fn_append CONFIG_FILES " '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + as_fn_append CONFIG_HEADERS " '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + as_fn_error $? "ambiguous option: \`$1' +Try \`$0 --help' for more information.";; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) as_fn_error $? "unrecognized option: \`$1' +Try \`$0 --help' for more information." ;; + + *) as_fn_append ac_config_targets " $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}" + + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +sed_quote_subst='$sed_quote_subst' +double_quote_subst='$double_quote_subst' +delay_variable_subst='$delay_variable_subst' +AS='`$ECHO "$AS" | $SED "$delay_single_quote_subst"`' +DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' +OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' +macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' +macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' +enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' +enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' +pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' +enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' +shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`' +SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' +ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' +PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' +host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' +host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' +host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' +build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' +build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' +build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' +SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' +Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' +GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' +EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' +FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' +LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' +NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' +LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' +max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' +ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' +exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' +lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' +lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' +lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' +lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' +lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' +reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' +reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' +deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' +file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' +file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' +want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' +sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' +AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' +AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' +archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' +STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' +RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' +old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' +old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' +lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' +CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' +CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' +compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' +GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' +lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`' +nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' +lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' +lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`' +objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' +MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' +lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' +lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' +need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' +MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' +DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' +NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' +LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' +OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' +OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' +libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' +shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' +extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' +enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' +export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' +whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' +compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' +old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' +old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' +archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' +archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' +module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' +module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' +with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' +allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' +no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' +hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' +hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' +hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' +hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' +hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' +hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' +inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' +link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' +always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' +export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' +exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' +include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' +prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' +postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' +file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' +variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' +need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' +need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' +version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' +runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' +shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' +libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' +library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' +soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' +install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' +postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' +postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' +finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' +finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' +hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' +sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' +configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`' +configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`' +hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' +enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' +enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' +old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' +striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' + +LTCC='$LTCC' +LTCFLAGS='$LTCFLAGS' +compiler='$compiler_DEFAULT' + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +\$1 +_LTECHO_EOF' +} + +# Quote evaled strings. +for var in AS \ +DLLTOOL \ +OBJDUMP \ +SHELL \ +ECHO \ +PATH_SEPARATOR \ +SED \ +GREP \ +EGREP \ +FGREP \ +LD \ +NM \ +LN_S \ +lt_SP2NL \ +lt_NL2SP \ +reload_flag \ +deplibs_check_method \ +file_magic_cmd \ +file_magic_glob \ +want_nocaseglob \ +sharedlib_from_linklib_cmd \ +AR \ +AR_FLAGS \ +archiver_list_spec \ +STRIP \ +RANLIB \ +CC \ +CFLAGS \ +compiler \ +lt_cv_sys_global_symbol_pipe \ +lt_cv_sys_global_symbol_to_cdecl \ +lt_cv_sys_global_symbol_to_import \ +lt_cv_sys_global_symbol_to_c_name_address \ +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ +lt_cv_nm_interface \ +nm_file_list_spec \ +lt_cv_truncate_bin \ +lt_prog_compiler_no_builtin_flag \ +lt_prog_compiler_pic \ +lt_prog_compiler_wl \ +lt_prog_compiler_static \ +lt_cv_prog_compiler_c_o \ +need_locks \ +MANIFEST_TOOL \ +DSYMUTIL \ +NMEDIT \ +LIPO \ +OTOOL \ +OTOOL64 \ +shrext_cmds \ +export_dynamic_flag_spec \ +whole_archive_flag_spec \ +compiler_needs_object \ +with_gnu_ld \ +allow_undefined_flag \ +no_undefined_flag \ +hardcode_libdir_flag_spec \ +hardcode_libdir_separator \ +exclude_expsyms \ +include_expsyms \ +file_list_spec \ +variables_saved_for_relink \ +libname_spec \ +library_names_spec \ +soname_spec \ +install_override_mode \ +finish_eval \ +old_striplib \ +striplib; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +# Double-quote double-evaled strings. +for var in reload_cmds \ +old_postinstall_cmds \ +old_postuninstall_cmds \ +old_archive_cmds \ +extract_expsyms_cmds \ +old_archive_from_new_cmds \ +old_archive_from_expsyms_cmds \ +archive_cmds \ +archive_expsym_cmds \ +module_cmds \ +module_expsym_cmds \ +export_symbols_cmds \ +prelink_cmds \ +postlink_cmds \ +postinstall_cmds \ +postuninstall_cmds \ +finish_cmds \ +sys_lib_search_path_spec \ +configure_time_dlsearch_path \ +configure_time_lt_sys_library_path; do + case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in + *[\\\\\\\`\\"\\\$]*) + eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes + ;; + *) + eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" + ;; + esac +done + +ac_aux_dir='$ac_aux_dir' + +# See if we are running on zsh, and set the options that allow our +# commands through without removal of \ escapes INIT. +if test -n "\${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST +fi + + + PACKAGE='$PACKAGE' + VERSION='$VERSION' + RM='$RM' + ofile='$ofile' + + + + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h:config-h.in" ;; + "autoopts/mk-autoopts-pc") CONFIG_FILES="$CONFIG_FILES autoopts/mk-autoopts-pc" ;; + "autoopts/autoopts-config") CONFIG_FILES="$CONFIG_FILES autoopts/autoopts-config" ;; + "autoopts/tpl/tpl-config.tlib") CONFIG_FILES="$CONFIG_FILES autoopts/tpl/tpl-config.tlib:autoopts/tpl/tpl-config-tlib.in" ;; + "doc/auto_gen.tpl") CONFIG_FILES="$CONFIG_FILES doc/auto_gen.tpl:doc/auto_gen-tpl.in" ;; + "autoopts/test/defs") CONFIG_FILES="$CONFIG_FILES autoopts/test/defs" ;; + "config/mk-shdefs") CONFIG_FILES="$CONFIG_FILES config/mk-shdefs" ;; + "pkg/pkg-env") CONFIG_FILES="$CONFIG_FILES pkg/pkg-env" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "agen5/Makefile") CONFIG_FILES="$CONFIG_FILES agen5/Makefile" ;; + "agen5/test/Makefile") CONFIG_FILES="$CONFIG_FILES agen5/test/Makefile" ;; + "autoopts/Makefile") CONFIG_FILES="$CONFIG_FILES autoopts/Makefile" ;; + "autoopts/test/Makefile") CONFIG_FILES="$CONFIG_FILES autoopts/test/Makefile" ;; + "columns/Makefile") CONFIG_FILES="$CONFIG_FILES columns/Makefile" ;; + "compat/Makefile") CONFIG_FILES="$CONFIG_FILES compat/Makefile" ;; + "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;; + "getdefs/Makefile") CONFIG_FILES="$CONFIG_FILES getdefs/Makefile" ;; + "getdefs/test/Makefile") CONFIG_FILES="$CONFIG_FILES getdefs/test/Makefile" ;; + "pkg/Makefile") CONFIG_FILES="$CONFIG_FILES pkg/Makefile" ;; + "snprintfv/Makefile") CONFIG_FILES="$CONFIG_FILES snprintfv/Makefile" ;; + "xml2ag/Makefile") CONFIG_FILES="$CONFIG_FILES xml2ag/Makefile" ;; + "xml2ag/test/Makefile") CONFIG_FILES="$CONFIG_FILES xml2ag/test/Makefile" ;; + "stamp-h") CONFIG_COMMANDS="$CONFIG_COMMANDS stamp-h" ;; + + *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= ac_tmp= + trap 'exit_status=$? + : "${ac_tmp:=$tmp}" + { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status +' 0 + trap 'as_fn_exit 1' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 +ac_tmp=$tmp + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=`echo X | tr X '\015'` +# On cygwin, bash can eat \r inside `` if the user requested igncr. +# But we know of no other shell where ac_cr would be empty at this +# point, so we can use a bashism as a fallback. +if test "x$ac_cr" = x; then + eval ac_cr=\$\'\\r\' +fi +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$ac_tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 +ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\)..*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\)..*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' <conf$$subs.awk | sed ' +/^[^""]/{ + N + s/\n// +} +' >>$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ + || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 +_ACEOF + +# VPATH may cause trouble with some makes, so we remove sole $(srcdir), +# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ +h +s/// +s/^/:/ +s/[ ]*$/:/ +s/:\$(srcdir):/:/g +s/:\${srcdir}:/:/g +s/:@srcdir@:/:/g +s/^:*// +s/:*$// +x +s/\(=[ ]*\).*/\1/ +G +s/\n// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$ac_tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_tt=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_tt"; then + break + elif $ac_last_try; then + as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' <confdefs.h | sed ' +s/'"$ac_delim"'/"\\\ +"/g' >>$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #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. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$ac_tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + as_fn_append ac_file_inputs " '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$ac_tmp/stdin" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + as_dir="$ac_dir"; as_fn_mkdir_p + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ + >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ + "$ac_tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined" >&2;} + + rm -f "$ac_tmp/stdin" + case $ac_file in + -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; + *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; + esac \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" + } >"$ac_tmp/config.h" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$ac_tmp/config.h" "$ac_file" \ + || as_fn_error $? "could not create $ac_file" "$LINENO" 5 + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ + || as_fn_error $? "could not create -" "$LINENO" 5 + fi +# Compute "$ac_file"'s index in $config_headers. +_am_arg="$ac_file" +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$_am_arg" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Older Autoconf quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + # TODO: see whether this extra hack can be removed once we start + # requiring Autoconf 2.70 or later. + case $CONFIG_FILES in #( + *\'*) : + eval set x "$CONFIG_FILES" ;; #( + *) : + set x $CONFIG_FILES ;; #( + *) : + ;; +esac + shift + # Used to flag and report bootstrapping failures. + am_rc=0 + for am_mf + do + # Strip MF so we end up with the name of the file. + am_mf=`$as_echo "$am_mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile which includes + # dependency-tracking related rules and includes. + # Grep'ing the whole file directly is not great: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ + || continue + am_dirpart=`$as_dirname -- "$am_mf" || +$as_expr X"$am_mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$am_mf" : 'X\(//\)[^/]' \| \ + X"$am_mf" : 'X\(//\)$' \| \ + X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$am_mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + am_filepart=`$as_basename -- "$am_mf" || +$as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \ + X"$am_mf" : 'X\(//\)$' \| \ + X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$am_mf" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { echo "$as_me:$LINENO: cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles" >&5 + (cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } || am_rc=$? + done + if test $am_rc -ne 0; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "Something went wrong bootstrapping makefile fragments + for automatic dependency tracking. Try re-running configure with the + '--disable-dependency-tracking' option to at least be able to build + the package (albeit without support for automatic dependency tracking). +See \`config.log' for more details" "$LINENO" 5; } + fi + { am_dirpart=; unset am_dirpart;} + { am_filepart=; unset am_filepart;} + { am_mf=; unset am_mf;} + { am_rc=; unset am_rc;} + rm -f conftest-deps.mk +} + ;; + "libtool":C) + + # See if we are running on zsh, and set the options that allow our + # commands through without removal of \ escapes. + if test -n "${ZSH_VERSION+set}"; then + setopt NO_GLOB_SUBST + fi + + cfgfile=${ofile}T + trap "$RM \"$cfgfile\"; exit 1" 1 2 15 + $RM "$cfgfile" + + cat <<_LT_EOF >> "$cfgfile" +#! $SHELL +# Generated automatically by $as_me ($PACKAGE) $VERSION +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# NOTE: Changes made to this file will be lost: look at ltmain.sh. + +# Provide generalized library-building support services. +# Written by Gordon Matzigkeit, 1996 + +# Copyright (C) 2014 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. + +# GNU Libtool 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 of the License, or +# (at your option) any later version. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program or library that is built +# using GNU Libtool, you may include this file under the same +# distribution terms that you use for the rest of that program. +# +# GNU Libtool is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + + +# The names of the tagged configurations supported by this script. +available_tags='' + +# Configured defaults for sys_lib_dlsearch_path munging. +: \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} + +# ### BEGIN LIBTOOL CONFIG + +# Assembler program. +AS=$lt_AS + +# DLL creation program. +DLLTOOL=$lt_DLLTOOL + +# Object dumper program. +OBJDUMP=$lt_OBJDUMP + +# Which release of libtool.m4 was used? +macro_version=$macro_version +macro_revision=$macro_revision + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# What type of objects to build. +pic_mode=$pic_mode + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# Shared archive member basename,for filename based shared library versioning on AIX. +shared_archive_member_spec=$shared_archive_member_spec + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# An echo program that protects backslashes. +ECHO=$lt_ECHO + +# The PATH separator for the build system. +PATH_SEPARATOR=$lt_PATH_SEPARATOR + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="\$SED -e 1s/^X//" + +# A grep program that handles long lines. +GREP=$lt_GREP + +# An ERE matcher. +EGREP=$lt_EGREP + +# A literal string matcher. +FGREP=$lt_FGREP + +# A BSD- or MS-compatible name lister. +NM=$lt_NM + +# Whether we need soft or hard links. +LN_S=$lt_LN_S + +# What is the maximum length of a command? +max_cmd_len=$max_cmd_len + +# Object file suffix (normally "o"). +objext=$ac_objext + +# Executable file suffix (normally ""). +exeext=$exeext + +# whether the shell understands "unset". +lt_unset=$lt_unset + +# turn spaces into newlines. +SP2NL=$lt_lt_SP2NL + +# turn newlines into spaces. +NL2SP=$lt_lt_NL2SP + +# convert \$build file names to \$host format. +to_host_file_cmd=$lt_cv_to_host_file_cmd + +# convert \$build files to toolchain format. +to_tool_file_cmd=$lt_cv_to_tool_file_cmd + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method = "file_magic". +file_magic_cmd=$lt_file_magic_cmd + +# How to find potential files when deplibs_check_method = "file_magic". +file_magic_glob=$lt_file_magic_glob + +# Find potential files using nocaseglob when deplibs_check_method = "file_magic". +want_nocaseglob=$lt_want_nocaseglob + +# Command to associate shared and link libraries. +sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd + +# The archiver. +AR=$lt_AR + +# Flags to create an archive. +AR_FLAGS=$lt_AR_FLAGS + +# How to feed a file listing to the archiver. +archiver_list_spec=$lt_archiver_list_spec + +# A symbol stripping program. +STRIP=$lt_STRIP + +# Commands used to install an old-style archive. +RANLIB=$lt_RANLIB +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Whether to use a lock for old archive extraction. +lock_old_archive_extraction=$lock_old_archive_extraction + +# A C compiler. +LTCC=$lt_CC + +# LTCC compiler flags. +LTCFLAGS=$lt_CFLAGS + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration. +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm into a list of symbols to manually relocate. +global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import + +# Transform the output of nm in a C name address pair. +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# Transform the output of nm in a C name address pair when lib prefix is needed. +global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix + +# The name lister interface. +nm_interface=$lt_lt_cv_nm_interface + +# Specify filename containing input files for \$NM. +nm_file_list_spec=$lt_nm_file_list_spec + +# The root where to search for dependent libraries,and where our libraries should be installed. +lt_sysroot=$lt_sysroot + +# Command to truncate a binary pipe. +lt_truncate_bin=$lt_lt_cv_truncate_bin + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# Used to examine libraries when file_magic_cmd begins with "file". +MAGIC_CMD=$MAGIC_CMD + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Manifest tool. +MANIFEST_TOOL=$lt_MANIFEST_TOOL + +# Tool to manipulate archived DWARF debug symbol files on Mac OS X. +DSYMUTIL=$lt_DSYMUTIL + +# Tool to change global to local symbols on Mac OS X. +NMEDIT=$lt_NMEDIT + +# Tool to manipulate fat objects and archives on Mac OS X. +LIPO=$lt_LIPO + +# ldd/readelf like tool for Mach-O binaries on Mac OS X. +OTOOL=$lt_OTOOL + +# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. +OTOOL64=$lt_OTOOL64 + +# Old archive suffix (normally "a"). +libext=$libext + +# Shared library suffix (normally ".so"). +shrext_cmds=$lt_shrext_cmds + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at link time. +variables_saved_for_relink=$lt_variables_saved_for_relink + +# Do we need the "lib" prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Library versioning type. +version_type=$version_type + +# Shared library runtime path variable. +runpath_var=$runpath_var + +# Shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# Format of library name prefix. +libname_spec=$lt_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=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Permission mode override for installation of shared libraries. +install_override_mode=$lt_install_override_mode + +# Command to use after installation of a shared archive. +postinstall_cmds=$lt_postinstall_cmds + +# Command to use after uninstallation of a shared archive. +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# As "finish_cmds", except a single script fragment to be evaled but +# not shown. +finish_eval=$lt_finish_eval + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Compile-time system search path for libraries. +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Detected run-time system search path for libraries. +sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path + +# Explicit LT_SYS_LIBRARY_PATH set during ./configure time. +configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + + +# The linker used to build libraries. +LD=$lt_LD + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# Commands used to build an old-style archive. +old_archive_cmds=$lt_old_archive_cmds + +# A language specific compiler. +CC=$lt_compiler + +# Is the compiler the GNU compiler? +with_gcc=$GCC + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag + +# Additional compiler flags for building library objects. +pic_flag=$lt_lt_prog_compiler_pic + +# How to pass a linker flag through the compiler. +wl=$lt_lt_prog_compiler_wl + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_lt_prog_compiler_static + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_lt_cv_prog_compiler_c_o + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$archive_cmds_need_lc + +# Whether or not to disallow shared libs when runtime libs are static. +allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_whole_archive_flag_spec + +# Whether the compiler copes with passing no objects directly. +compiler_needs_object=$lt_compiler_needs_object + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_old_archive_from_new_cmds + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds + +# Commands used to build a shared archive. +archive_cmds=$lt_archive_cmds +archive_expsym_cmds=$lt_archive_expsym_cmds + +# Commands used to build a loadable module if different from building +# a shared archive. +module_cmds=$lt_module_cmds +module_expsym_cmds=$lt_module_expsym_cmds + +# Whether we are building with GNU ld or not. +with_gnu_ld=$lt_with_gnu_ld + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_allow_undefined_flag + +# Flag that enforces no undefined symbols. +no_undefined_flag=$lt_no_undefined_flag + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist +hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec + +# Whether we need a single "-rpath" flag with a separated argument. +hardcode_libdir_separator=$lt_hardcode_libdir_separator + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary. +hardcode_direct=$hardcode_direct + +# Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes +# DIR into the resulting binary and the resulting library dependency is +# "absolute",i.e impossible to change by setting \$shlibpath_var if the +# library is relocated. +hardcode_direct_absolute=$hardcode_direct_absolute + +# 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 + +# Set to "yes" if building a shared library automatically hardcodes DIR +# into the library and all subsequent libraries and executables linked +# against it. +hardcode_automatic=$hardcode_automatic + +# Set to yes if linker adds runtime paths of dependent libraries +# to runtime path list. +inherit_rpath=$inherit_rpath + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$link_all_deplibs + +# Set to "yes" if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$lt_export_symbols_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$lt_include_expsyms + +# Commands necessary for linking programs (against libraries) with templates. +prelink_cmds=$lt_prelink_cmds + +# Commands necessary for finishing linking programs. +postlink_cmds=$lt_postlink_cmds + +# Specify filename containing input files. +file_list_spec=$lt_file_list_spec + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# ### END LIBTOOL CONFIG + +_LT_EOF + + cat <<'_LT_EOF' >> "$cfgfile" + +# ### BEGIN FUNCTIONS SHARED WITH CONFIGURE + +# func_munge_path_list VARIABLE PATH +# ----------------------------------- +# VARIABLE is name of variable containing _space_ separated list of +# directories to be munged by the contents of PATH, which is string +# having a format: +# "DIR[:DIR]:" +# string "DIR[ DIR]" will be prepended to VARIABLE +# ":DIR[:DIR]" +# string "DIR[ DIR]" will be appended to VARIABLE +# "DIRP[:DIRP]::[DIRA:]DIRA" +# string "DIRP[ DIRP]" will be prepended to VARIABLE and string +# "DIRA[ DIRA]" will be appended to VARIABLE +# "DIR[:DIR]" +# VARIABLE will be replaced by "DIR[ DIR]" +func_munge_path_list () +{ + case x$2 in + x) + ;; + *:) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" + ;; + x:*) + eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" + ;; + *::*) + eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" + eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" + ;; + *) + eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" + ;; + esac +} + + +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +func_cc_basename () +{ + for cc_temp in $*""; do + case $cc_temp in + compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; + distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; + \-*) ;; + *) break;; + esac + done + func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` +} + + +# ### END FUNCTIONS SHARED WITH CONFIGURE + +_LT_EOF + + case $host_os in + aix3*) + cat <<\_LT_EOF >> "$cfgfile" +# 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 set != "${COLLECT_NAMES+set}"; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +_LT_EOF + ;; + esac + + +ltmain=$ac_aux_dir/ltmain.sh + + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" \ + || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" + + ;; + "autoopts/mk-autoopts-pc":F) chmod +x autoopts/mk-autoopts-pc ;; + "autoopts/autoopts-config":F) chmod +x autoopts/autoopts-config ;; + "stamp-h":C) test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h ;; + + esac +done # for ac_tag + + +as_fn_exit 0 +_ACEOF +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || as_fn_exit 1 +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + + +echo \ +"------------------------------------------------------------------------ +Configuration: + + Source code location: ${srcdir} + Compiler: ${CC} + Compiler flags: ${CFLAGS} + Host System Type: ${host} + Install path: ${prefix} + + See config.h for further configuration information. +------------------------------------------------------------------------" diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..bea0892 --- /dev/null +++ b/configure.ac @@ -0,0 +1,247 @@ +dnl -*- Mode: autoconf -*- +dnl configure.ac --- GNU autoconf source for toplevel directory. +dnl +dnl Author: Bruce Korb <bkorb@gnu.org> +dnl +dnl This file is part of AutoGen. +dnl AutoGen Copyright (C) 1992-2017 by Bruce Korb - all rights reserved +dnl +dnl AutoGen is free software: you can redistribute it and/or modify it +dnl under the terms of the GNU General Public License as published by the +dnl Free Software Foundation, either version 3 of the License, or +dnl (at your option) any later version. +dnl +dnl AutoGen is distributed in the hope that it will be useful, but +dnl WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +dnl See the GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License along +dnl with this program. If not, see <http://www.gnu.org/licenses/>. +dnl +AC_INIT([GNU AutoGen],[5.18.16],[autogen-users@lists.sourceforge.net]) +AC_CONFIG_SRCDIR([agen5/autogen.c]) +AC_CONFIG_AUX_DIR([config]) +AC_CANONICAL_TARGET +[. $srcdir/VERSION +d=`dirname $0` +ag_top_srcdir=`cd $d && pwd` +ag_top_builddir=`pwd`] +AM_INIT_AUTOMAKE([gnu check-news 1.5 dist-xz]) +AC_USE_SYSTEM_EXTENSIONS +AC_CONFIG_MACRO_DIR([config]) +AC_LIBTOOL_WIN32_DLL +m4_define(AC_PROVIDE_AC_LIBTOOL_WIN32_DLL) +AC_PROG_LIBTOOL +ifdef([AC_REVISION],AC_REVISION($Revision: 4.34 $),)dnl +[config_start_time=`date +%s 2>/dev/null`] +# ---------------------------------------------------------------------- +# Substitute VERSION vars here, so that they can be used by the Makefile +# ---------------------------------------------------------------------- +AC_SUBST(AG_VERSION) +AC_SUBST(AG_MAJOR_VERSION) +AC_SUBST(AG_MINOR_VERSION) +AC_SUBST(AO_CURRENT) +AC_SUBST(AO_REVISION) +AC_SUBST(AO_AGE) +[AO_TEMPLATE_VERSION=`expr '(' $AO_CURRENT '*' 4096 ')' + $AO_REVISION` +]dnl +AC_SUBST(AO_TEMPLATE_VERSION) +AC_SUBST(GO_CURRENT) +AC_SUBST(GO_REVISION) +AC_SUBST(GO_AGE) +AC_DEFINE_UNQUOTED(AO_CURRENT,$AO_CURRENT, + [Define this to the autoopts current interface number]) +AC_DEFINE_UNQUOTED(AO_REVISION,$AO_REVISION, + [Define this to the autoopts interface revision number]) +AC_DEFINE_UNQUOTED(AO_AGE,$AO_AGE, + [Define this to the autoopts interface age number]) +# ---------------------------------------------------------------------- +# Set up the environment to configure the snprintv subpackage using +# this version of AutoGen (as opposed to any installed version). +# ---------------------------------------------------------------------- +[ag_srcdir=`\cd $srcdir && pwd` +if test x$ag_srcdir != x && test -d $ag_srcdir; then + : +else + ag_srcdir=.. +fi + +# ---------------------------------------------------------------------- +# If `configure' is invoked (in)directly via `make', ensure that it +# encounters no `make' conflicts. Ignore error if shell does not have +# unset, but at least set these to empty values. +# ---------------------------------------------------------------------- +MFLAGS= +MAKEFLAGS= +MAKELEVEL= +unset MFLAGS MAKEFLAGS MAKELEVEL 2>/dev/null] + +AM_WITH_DMALLOC + +# ---------------------------------------------------------------------- +# check for various programs used during the build. +# ---------------------------------------------------------------------- +AC_PROG_CC_STDC +AM_PROG_CC_C_O +gl_FUNC_GLIBC_UNLOCKED_IO +AC_EXEEXT +AC_PROG_INSTALL +AC_PROG_LIBTOOL +AC_CHECK_PROG(TEXI2HTML, texi2html, texi2html, :) +AC_C_CONST +AC_C_INLINE +# ---------------------------------------------------------------------- +AC_CHECK_LIB(dl, dlopen) +# ---------------------------------------------------------------------- +AC_TYPE_MODE_T +AC_TYPE_PID_T +AC_TYPE_SIZE_T +AC_TYPE_UID_T +AC_C_LONG_DOUBLE +[if test x$ac_cv_type_long_double = xno; then + snv_long_double=double +else + snv_long_double='long double' +fi] +AC_DEFINE_UNQUOTED([SNV_LONG_DOUBLE],$snv_long_double, + [Define this to the long+double type]) +AC_CHECK_TYPES([long long, uintmax_t, size_t, wchar_t]) +AC_CHECK_SIZEOF(char*) +AC_CHECK_SIZEOF(int) +AC_CHECK_SIZEOF(long) +AC_CHECK_SIZEOF(short) +# ---------------------------------------------------------------------- + +# ---------------------------------------------------------------------- +# Do all our own macros +# ---------------------------------------------------------------------- +INVOKE_AG_MACROS +[ +if ! test x$ag_cv_sys_siglist = xyes +then + if ! test x$ac_cv_func_strsignal = xyes + then + echo "WARNING: strsignal will use POSIX names and Linux signal numbers" + fi +fi >&2 +if test "X${ag_cv_link_sigsetjmp}" = Xno +then] + AC_MSG_ERROR([AutoGen requires sigsetjmp(3)])[ +fi +] +gl_STDNORETURN_H +# ---------------------------------------------------------------------- +# Do SNPRINTFV macros +# ---------------------------------------------------------------------- +INVOKE_SNPRINTFV_MACROS +# ---------------------------------------------------------------------- +# Generate the make files. +# ---------------------------------------------------------------------- +AC_PROG_LN_S +[ +test -f ./snprintfv/snprintfv/snprintfv.h \ + && rm -f ./snprintfv/snprintfv.h \ + && ${LN_S} `pwd`/snprintfv/snprintfv/snprintfv.h ./snprintfv/ + +AGnam=autogen${ac_exeext} +GDnam=getdefs${ac_exeext} +CLnam=columns${ac_exeext} +if test "X$cross_compiling" = Xyes +then + AGexe=`which ${AGnam}` + GDexe=`which ${GDnam}` + CLexe=`which ${CLnam}` +else + AGexe=${ag_top_builddir}/agen5/${AGnam} + GDexe=${ag_top_builddir}/getdefs/${GDnam} + CLexe=${ag_top_builddir}/columns/${CLnam} +fi +M4_SRC=`cd $srcdir/config ; echo [a-z]*.m4` +ENABLE_STATIC=${enable_static} +config_end_time=`date +%s 2>/dev/null` +time_delta=`expr ${config_end_time} - ${config_start_time} 2>/dev/null` + +if test -z "${AG_TIMEOUT}" +then + if test -z "${time_delta}" + then time_delta=10 + elif test ${time_delta} -lt 5 + then time_delta=5 ; fi + + AG_TIMEOUT=${time_delta} +fi +] +AC_DEFINE_UNQUOTED(AG_DEFAULT_TIMEOUT, ${AG_TIMEOUT}, + [define to suitable timeout limit for shell command]) +AC_SUBST(M4_SRC) +AC_SUBST(AGnam) +AC_SUBST(GDnam) +AC_SUBST(CLnam) +AC_SUBST(AGexe) +AC_SUBST(GDexe) +AC_SUBST(CLexe) +AC_SUBST(AG_TIMEOUT) +AC_SUBST(ac_aux_dir) +AC_SUBST(LIBS) +AC_SUBST(DEBUG_ENABLED) +AC_SUBST(ENABLE_STATIC) +[ +if test "$ag_top_srcdir" = "$ag_top_builddir" +then + INCLIST='-I${top_builddir} -I${top_srcdir}/autoopts' +else + INCLIST='-I${top_builddir} -I${top_srcdir}' + INCLIST="${INCLIST} -I\${top_builddir}/autoopts -I\${top_srcdir}/autoopts" +fi +]AC_SUBST(INCLIST)[ +WARN_CFLAGS= +test "X${GCC}" = Xyes && { + CFLAGS="$CFLAGS -Wno-format-contains-nul -fno-strict-aliasing" + WARN_CFLAGS="$CFLAGS "`echo -Wall -Werror -Wcast-align -Wmissing-prototypes \ + -Wpointer-arith -Wshadow -Wstrict-prototypes -Wwrite-strings \ + -Wstrict-aliasing=3 -Wextra -Wno-cast-qual` +}]dnl -Wconversion -Wsign-conversion -Wstrict-overflow +AC_SUBST(WARN_CFLAGS) +AC_CONFIG_HEADER(config.h:config-h.in) +AH_TOP([#ifndef AUTOGEN_CONFIG_H]) +AH_TOP([#define AUTOGEN_CONFIG_H 1]) +AH_BOTTOM([#endif /* AUTOGEN_CONFIG_H */]) +AC_CONFIG_FILES([autoopts/mk-autoopts-pc], + [chmod +x autoopts/mk-autoopts-pc]) +AC_CONFIG_FILES([autoopts/autoopts-config], + [chmod +x autoopts/autoopts-config]) + +AC_CONFIG_FILES([autoopts/tpl/tpl-config.tlib:autoopts/tpl/tpl-config-tlib.in]) +AC_CONFIG_FILES([doc/auto_gen.tpl:doc/auto_gen-tpl.in]) +AC_CONFIG_FILES([ + autoopts/test/defs config/mk-shdefs pkg/pkg-env + Makefile agen5/Makefile agen5/test/Makefile + autoopts/Makefile autoopts/test/Makefile columns/Makefile + compat/Makefile doc/Makefile getdefs/Makefile + getdefs/test/Makefile pkg/Makefile snprintfv/Makefile + xml2ag/Makefile xml2ag/test/Makefile]) + +AC_CONFIG_COMMANDS([stamp-h], +[test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h]) +[CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} +f=`${CONFIG_SHELL} -c 'echo true | ( + exec 2>/dev/null ; read -u0 line ; echo $line ; )'` +test X$f = Xtrue || CONFIG_SHELL=`command -v bash`] +AC_SUBST(CONFIG_SHELL) +AC_DEFINE_UNQUOTED(CONFIG_SHELL,$CONFIG_SHELL, + [Define this to a working Bourne shell]) +AC_OUTPUT + +echo \ +"------------------------------------------------------------------------ +Configuration: + + Source code location: ${srcdir} + Compiler: ${CC} + Compiler flags: ${CFLAGS} + Host System Type: ${host} + Install path: ${prefix} + + See config.h for further configuration information. +------------------------------------------------------------------------" diff --git a/doc/Makefile.am b/doc/Makefile.am new file mode 100644 index 0000000..0544729 --- /dev/null +++ b/doc/Makefile.am @@ -0,0 +1,71 @@ +## -*- Mode: Makefile -*- +## +## Makefile.am -- process this file with automake to produce Makefile.in +## +## Author: Bruce Korb <bkorb@gnu.org> +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see <http://www.gnu.org/licenses/>. +## --------------------------------------------------------------------- + +# This variable is needed to subvert automake's info rules. +# They don't work for generated texi files: +# +INFO_DEPS = autogen.info +MIexe = $(MAKEINFO) --no-split +MAKEINFOFLAGS = -I$(top_srcdir)/autoopts -I../autoopts +passenv = MAKE=$(MAKE) srcdir="$(srcdir)" SHELL="$(POSIX_SHELL)" \ + top_builddir="$(top_builddir)" top_srcdir="$(top_srcdir)" + +run_mktexi = $(passenv) $(POSIX_SHELL) $${dashx} \ + $(srcdir)/mk-agen-texi.sh +all : $(INFO_DEPS) + +BUILT_SOURCES = autogen.texi +info_TEXINFOS = $(BUILT_SOURCES) +EXTRA_DIST = \ + agdoc.texi auto-opts.tlib autogen-intro.texi \ + autogen-intro.texi autogen-texi.txt fdl.texi \ + gendocs_template libopts.texi mk-agen-texi.sh \ + invoke-autogen.texi invoke-columns.texi \ + invoke-getdefs.texi invoke-xml2ag.texi \ + invoke-snprintfv.texi snprintfv.texi \ + invoke-bitmaps.texi bitmaps.texi + +# MAINTAINERCLEANFILES = MakeDep.inc +TEXI2DVI_FLAGS = --texinfo='@pagesizes 9.5in,7.0in' + +agdoc.texi : # self-depends upon all executables + $(run_mktexi) $@ + +autogen.dvi : agdoc.texi +autogen.texi : agdoc.texi mk-agen-texi.sh + @test -f $@ || { $(run_mktexi) $@ ; } + +# Special rule for generating all the GNU standard formats. +# +autogen.txt : autogen.texi + $(MIexe) --fill-column=70 --paragraph-indent=0 --no-headers \ + --output=$@ autogen.texi + +clobber : maintainer-clean + +.NOTPARALLEL: + +gnudocs : $(srcdir)/gendocs_template agdoc.texi + $(run_mktexi) $@ + +# doc/Makefile.am ends here diff --git a/doc/Makefile.in b/doc/Makefile.in new file mode 100644 index 0000000..7e9a866 --- /dev/null +++ b/doc/Makefile.in @@ -0,0 +1,873 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 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. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = doc +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/ag_macros.m4 \ + $(top_srcdir)/config/asm-underscore.m4 \ + $(top_srcdir)/config/extensions.m4 \ + $(top_srcdir)/config/guile.m4 \ + $(top_srcdir)/config/host-cpu-c-abi.m4 \ + $(top_srcdir)/config/lib-ld.m4 \ + $(top_srcdir)/config/lib-link.m4 \ + $(top_srcdir)/config/lib-prefix.m4 \ + $(top_srcdir)/config/libopts.m4 \ + $(top_srcdir)/config/libtool.m4 \ + $(top_srcdir)/config/ltoptions.m4 \ + $(top_srcdir)/config/ltsugar.m4 \ + $(top_srcdir)/config/ltversion.m4 \ + $(top_srcdir)/config/lt~obsolete.m4 \ + $(top_srcdir)/config/onceonly.m4 $(top_srcdir)/config/pkg.m4 \ + $(top_srcdir)/config/snprintfv.m4 \ + $(top_srcdir)/config/stdnoreturn.m4 \ + $(top_srcdir)/config/unlocked-io.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = auto_gen.tpl +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +AM_V_DVIPS = $(am__v_DVIPS_@AM_V@) +am__v_DVIPS_ = $(am__v_DVIPS_@AM_DEFAULT_V@) +am__v_DVIPS_0 = @echo " DVIPS " $@; +am__v_DVIPS_1 = +AM_V_MAKEINFO = $(am__v_MAKEINFO_@AM_V@) +am__v_MAKEINFO_ = $(am__v_MAKEINFO_@AM_DEFAULT_V@) +am__v_MAKEINFO_0 = @echo " MAKEINFO" $@; +am__v_MAKEINFO_1 = +AM_V_INFOHTML = $(am__v_INFOHTML_@AM_V@) +am__v_INFOHTML_ = $(am__v_INFOHTML_@AM_DEFAULT_V@) +am__v_INFOHTML_0 = @echo " INFOHTML" $@; +am__v_INFOHTML_1 = +AM_V_TEXI2DVI = $(am__v_TEXI2DVI_@AM_V@) +am__v_TEXI2DVI_ = $(am__v_TEXI2DVI_@AM_DEFAULT_V@) +am__v_TEXI2DVI_0 = @echo " TEXI2DVI" $@; +am__v_TEXI2DVI_1 = +AM_V_TEXI2PDF = $(am__v_TEXI2PDF_@AM_V@) +am__v_TEXI2PDF_ = $(am__v_TEXI2PDF_@AM_DEFAULT_V@) +am__v_TEXI2PDF_0 = @echo " TEXI2PDF" $@; +am__v_TEXI2PDF_1 = +AM_V_texinfo = $(am__v_texinfo_@AM_V@) +am__v_texinfo_ = $(am__v_texinfo_@AM_DEFAULT_V@) +am__v_texinfo_0 = -q +am__v_texinfo_1 = +AM_V_texidevnull = $(am__v_texidevnull_@AM_V@) +am__v_texidevnull_ = $(am__v_texidevnull_@AM_DEFAULT_V@) +am__v_texidevnull_0 = > /dev/null +am__v_texidevnull_1 = +TEXINFO_TEX = $(top_srcdir)/config/texinfo.tex +am__TEXINFO_TEX_DIR = $(top_srcdir)/config +DVIS = autogen.dvi +PDFS = autogen.pdf +PSS = autogen.ps +HTMLS = autogen.html +TEXINFOS = $(BUILT_SOURCES) +TEXI2DVI = texi2dvi +TEXI2PDF = $(TEXI2DVI) --pdf --batch +MAKEINFOHTML = $(MAKEINFO) --html +AM_MAKEINFOHTMLFLAGS = $(AM_MAKEINFOFLAGS) +DVIPS = dvips +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__installdirs = "$(DESTDIR)$(infodir)" +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/auto_gen-tpl.in \ + $(top_srcdir)/config/texinfo.tex +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AGEN5_TESTS = @AGEN5_TESTS@ +AG_LDFLAGS = @AG_LDFLAGS@ +AG_MAJOR_VERSION = @AG_MAJOR_VERSION@ +AG_MINOR_VERSION = @AG_MINOR_VERSION@ +AG_STATIC_AUTOGEN = @AG_STATIC_AUTOGEN@ +AG_TIMEOUT = @AG_TIMEOUT@ +AG_VERSION = @AG_VERSION@ +AG_XML2 = @AG_XML2@ +AGexe = @AGexe@ +AGnam = @AGnam@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AO_AGE = @AO_AGE@ +AO_CURRENT = @AO_CURRENT@ +AO_REVISION = @AO_REVISION@ +AO_TEMPLATE_VERSION = @AO_TEMPLATE_VERSION@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLexe = @CLexe@ +CLnam = @CLnam@ +CONFIG_SHELL = @CONFIG_SHELL@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBUG_ENABLED = @DEBUG_ENABLED@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +DYNAMIC_AG = @DYNAMIC_AG@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_STATIC = @ENABLE_STATIC@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GDexe = @GDexe@ +GDnam = @GDnam@ +GO_AGE = @GO_AGE@ +GO_CURRENT = @GO_CURRENT@ +GO_REVISION = @GO_REVISION@ +GREP = @GREP@ +GUILE_CFLAGS = @GUILE_CFLAGS@ +GUILE_EFFECTIVE_VERSION = @GUILE_EFFECTIVE_VERSION@ +GUILE_LDFLAGS = @GUILE_LDFLAGS@ +GUILE_LIBS = @GUILE_LIBS@ +GUILE_LTLIBS = @GUILE_LTLIBS@ +HOST_CPU = @HOST_CPU@ +HOST_CPU_C_ABI = @HOST_CPU_C_ABI@ +INCLIST = @INCLIST@ +INCSNPRINTFV = @INCSNPRINTFV@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSNPRINTFV = @LIBSNPRINTFV@ +LIBTOOL = @LIBTOOL@ +LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ +LIBXML2_LIBS = @LIBXML2_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +M4_SRC = @M4_SRC@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPTS_TESTDIR = @OPTS_TESTDIR@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSIX_SHELL = @POSIX_SHELL@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STDNORETURN_H = @STDNORETURN_H@ +STRIP = @STRIP@ +TEXI2HTML = @TEXI2HTML@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_aux_dir = @ac_aux_dir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ + +# This variable is needed to subvert automake's info rules. +# They don't work for generated texi files: +# +INFO_DEPS = autogen.info +MIexe = $(MAKEINFO) --no-split +MAKEINFOFLAGS = -I$(top_srcdir)/autoopts -I../autoopts +passenv = MAKE=$(MAKE) srcdir="$(srcdir)" SHELL="$(POSIX_SHELL)" \ + top_builddir="$(top_builddir)" top_srcdir="$(top_srcdir)" + +run_mktexi = $(passenv) $(POSIX_SHELL) $${dashx} \ + $(srcdir)/mk-agen-texi.sh + +BUILT_SOURCES = autogen.texi +info_TEXINFOS = $(BUILT_SOURCES) +EXTRA_DIST = \ + agdoc.texi auto-opts.tlib autogen-intro.texi \ + autogen-intro.texi autogen-texi.txt fdl.texi \ + gendocs_template libopts.texi mk-agen-texi.sh \ + invoke-autogen.texi invoke-columns.texi \ + invoke-getdefs.texi invoke-xml2ag.texi \ + invoke-snprintfv.texi snprintfv.texi \ + invoke-bitmaps.texi bitmaps.texi + + +# MAINTAINERCLEANFILES = MakeDep.inc +TEXI2DVI_FLAGS = --texinfo='@pagesizes 9.5in,7.0in' +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .dvi .html .info .pdf .ps .texi +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu doc/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu doc/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +auto_gen.tpl: $(top_builddir)/config.status $(srcdir)/auto_gen-tpl.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +.texi.info: + $(AM_V_MAKEINFO)restore=: && backupdir="$(am__leading_dot)am$$$$" && \ + am__cwd=`pwd` && $(am__cd) $(srcdir) && \ + rm -rf $$backupdir && mkdir $$backupdir && \ + if ($(MAKEINFO) --version) >/dev/null 2>&1; then \ + for f in $@ $@-[0-9] $@-[0-9][0-9] $(@:.info=).i[0-9] $(@:.info=).i[0-9][0-9]; do \ + if test -f $$f; then mv $$f $$backupdir; restore=mv; else :; fi; \ + done; \ + else :; fi && \ + cd "$$am__cwd"; \ + if $(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \ + -o $@ $<; \ + then \ + rc=0; \ + $(am__cd) $(srcdir); \ + else \ + rc=$$?; \ + $(am__cd) $(srcdir) && \ + $$restore $$backupdir/* `echo "./$@" | sed 's|[^/]*$$||'`; \ + fi; \ + rm -rf $$backupdir; exit $$rc + +.texi.dvi: + $(AM_V_TEXI2DVI)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ + MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \ + $(TEXI2DVI) $(AM_V_texinfo) --build-dir=$(@:.dvi=.t2d) -o $@ $(AM_V_texidevnull) \ + $< + +.texi.pdf: + $(AM_V_TEXI2PDF)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ + MAKEINFO='$(MAKEINFO) $(AM_MAKEINFOFLAGS) $(MAKEINFOFLAGS) -I $(srcdir)' \ + $(TEXI2PDF) $(AM_V_texinfo) --build-dir=$(@:.pdf=.t2p) -o $@ $(AM_V_texidevnull) \ + $< + +.texi.html: + $(AM_V_MAKEINFO)rm -rf $(@:.html=.htp) + $(AM_V_at)if $(MAKEINFOHTML) $(AM_MAKEINFOHTMLFLAGS) $(MAKEINFOFLAGS) -I $(srcdir) \ + -o $(@:.html=.htp) $<; \ + then \ + rm -rf $@ && mv $(@:.html=.htp) $@; \ + else \ + rm -rf $(@:.html=.htp); exit 1; \ + fi +$(srcdir)/autogen.info: autogen.texi +autogen.pdf: autogen.texi +autogen.html: autogen.texi +.dvi.ps: + $(AM_V_DVIPS)TEXINPUTS="$(am__TEXINFO_TEX_DIR)$(PATH_SEPARATOR)$$TEXINPUTS" \ + $(DVIPS) $(AM_V_texinfo) -o $@ $< + +uninstall-dvi-am: + @$(NORMAL_UNINSTALL) + @list='$(DVIS)'; test -n "$(dvidir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(dvidir)/$$f'"; \ + rm -f "$(DESTDIR)$(dvidir)/$$f"; \ + done + +uninstall-html-am: + @$(NORMAL_UNINSTALL) + @list='$(HTMLS)'; test -n "$(htmldir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " rm -rf '$(DESTDIR)$(htmldir)/$$f'"; \ + rm -rf "$(DESTDIR)$(htmldir)/$$f"; \ + done + +uninstall-info-am: + @$(PRE_UNINSTALL) + @if test -d '$(DESTDIR)$(infodir)' && $(am__can_run_installinfo); then \ + list='$(INFO_DEPS)'; \ + for file in $$list; do \ + relfile=`echo "$$file" | sed 's|^.*/||'`; \ + echo " install-info --info-dir='$(DESTDIR)$(infodir)' --remove '$(DESTDIR)$(infodir)/$$relfile'"; \ + if install-info --info-dir="$(DESTDIR)$(infodir)" --remove "$(DESTDIR)$(infodir)/$$relfile"; \ + then :; else test ! -f "$(DESTDIR)$(infodir)/$$relfile" || exit 1; fi; \ + done; \ + else :; fi + @$(NORMAL_UNINSTALL) + @list='$(INFO_DEPS)'; \ + for file in $$list; do \ + relfile=`echo "$$file" | sed 's|^.*/||'`; \ + relfile_i=`echo "$$relfile" | sed 's|\.info$$||;s|$$|.i|'`; \ + (if test -d "$(DESTDIR)$(infodir)" && cd "$(DESTDIR)$(infodir)"; then \ + echo " cd '$(DESTDIR)$(infodir)' && rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]"; \ + rm -f $$relfile $$relfile-[0-9] $$relfile-[0-9][0-9] $$relfile_i[0-9] $$relfile_i[0-9][0-9]; \ + else :; fi); \ + done + +uninstall-pdf-am: + @$(NORMAL_UNINSTALL) + @list='$(PDFS)'; test -n "$(pdfdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(pdfdir)/$$f'"; \ + rm -f "$(DESTDIR)$(pdfdir)/$$f"; \ + done + +uninstall-ps-am: + @$(NORMAL_UNINSTALL) + @list='$(PSS)'; test -n "$(psdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(psdir)/$$f'"; \ + rm -f "$(DESTDIR)$(psdir)/$$f"; \ + done + +dist-info: $(INFO_DEPS) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + list='$(INFO_DEPS)'; \ + for base in $$list; do \ + case $$base in \ + $(srcdir)/*) base=`echo "$$base" | sed "s|^$$srcdirstrip/||"`;; \ + esac; \ + if test -f $$base; then d=.; else d=$(srcdir); fi; \ + base_i=`echo "$$base" | sed 's|\.info$$||;s|$$|.i|'`; \ + for file in $$d/$$base $$d/$$base-[0-9] $$d/$$base-[0-9][0-9] $$d/$$base_i[0-9] $$d/$$base_i[0-9][0-9]; do \ + if test -f $$file; then \ + relfile=`expr "$$file" : "$$d/\(.*\)"`; \ + test -f "$(distdir)/$$relfile" || \ + cp -p $$file "$(distdir)/$$relfile"; \ + else :; fi; \ + done; \ + done + +mostlyclean-aminfo: + -rm -rf autogen.t2d autogen.t2p + +clean-aminfo: + -test -z "autogen.dvi autogen.pdf autogen.ps autogen.html" \ + || rm -rf autogen.dvi autogen.pdf autogen.ps autogen.html + +maintainer-clean-aminfo: + @list='$(INFO_DEPS)'; for i in $$list; do \ + i_i=`echo "$$i" | sed 's|\.info$$||;s|$$|.i|'`; \ + echo " rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]"; \ + rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]; \ + done +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: + + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$(top_distdir)" distdir="$(distdir)" \ + dist-info +check-am: all-am +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-am +all-am: Makefile $(INFO_DEPS) +installdirs: + for dir in "$(DESTDIR)$(infodir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +clean: clean-am + +clean-am: clean-aminfo clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: $(DVIS) + +html: html-am + +html-am: $(HTMLS) + +info: info-am + +info-am: $(INFO_DEPS) + +install-data-am: install-info-am + +install-dvi: install-dvi-am + +install-dvi-am: $(DVIS) + @$(NORMAL_INSTALL) + @list='$(DVIS)'; test -n "$(dvidir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(dvidir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(dvidir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(dvidir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(dvidir)" || exit $$?; \ + done +install-exec-am: + +install-html: install-html-am + +install-html-am: $(HTMLS) + @$(NORMAL_INSTALL) + @list='$(HTMLS)'; list2=; test -n "$(htmldir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(htmldir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p" || test -d "$$p"; then d=; else d="$(srcdir)/"; fi; \ + $(am__strip_dir) \ + d2=$$d$$p; \ + if test -d "$$d2"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)/$$f'"; \ + $(MKDIR_P) "$(DESTDIR)$(htmldir)/$$f" || exit 1; \ + echo " $(INSTALL_DATA) '$$d2'/* '$(DESTDIR)$(htmldir)/$$f'"; \ + $(INSTALL_DATA) "$$d2"/* "$(DESTDIR)$(htmldir)/$$f" || exit $$?; \ + else \ + list2="$$list2 $$d2"; \ + fi; \ + done; \ + test -z "$$list2" || { echo "$$list2" | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(htmldir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(htmldir)" || exit $$?; \ + done; } +install-info: install-info-am + +install-info-am: $(INFO_DEPS) + @$(NORMAL_INSTALL) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + list='$(INFO_DEPS)'; test -n "$(infodir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(infodir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(infodir)" || exit 1; \ + fi; \ + for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + esac; \ + if test -f $$file; then d=.; else d=$(srcdir); fi; \ + file_i=`echo "$$file" | sed 's|\.info$$||;s|$$|.i|'`; \ + for ifile in $$d/$$file $$d/$$file-[0-9] $$d/$$file-[0-9][0-9] \ + $$d/$$file_i[0-9] $$d/$$file_i[0-9][0-9] ; do \ + if test -f $$ifile; then \ + echo "$$ifile"; \ + else : ; fi; \ + done; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(infodir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(infodir)" || exit $$?; done + @$(POST_INSTALL) + @if $(am__can_run_installinfo); then \ + list='$(INFO_DEPS)'; test -n "$(infodir)" || list=; \ + for file in $$list; do \ + relfile=`echo "$$file" | sed 's|^.*/||'`; \ + echo " install-info --info-dir='$(DESTDIR)$(infodir)' '$(DESTDIR)$(infodir)/$$relfile'";\ + install-info --info-dir="$(DESTDIR)$(infodir)" "$(DESTDIR)$(infodir)/$$relfile" || :;\ + done; \ + else : ; fi +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: $(PDFS) + @$(NORMAL_INSTALL) + @list='$(PDFS)'; test -n "$(pdfdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(pdfdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(pdfdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pdfdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(pdfdir)" || exit $$?; done +install-ps: install-ps-am + +install-ps-am: $(PSS) + @$(NORMAL_INSTALL) + @list='$(PSS)'; test -n "$(psdir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(psdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(psdir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(psdir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(psdir)" || exit $$?; done +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-aminfo \ + maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-aminfo mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: $(PDFS) + +ps: ps-am + +ps-am: $(PSS) + +uninstall-am: uninstall-dvi-am uninstall-html-am uninstall-info-am \ + uninstall-pdf-am uninstall-ps-am + +.MAKE: all check install install-am install-strip + +.PHONY: all all-am check check-am clean clean-aminfo clean-generic \ + clean-libtool cscopelist-am ctags-am dist-info distclean \ + distclean-generic distclean-libtool distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-aminfo maintainer-clean-generic mostlyclean \ + mostlyclean-aminfo mostlyclean-generic mostlyclean-libtool pdf \ + pdf-am ps ps-am tags-am uninstall uninstall-am \ + uninstall-dvi-am uninstall-html-am uninstall-info-am \ + uninstall-pdf-am uninstall-ps-am + +.PRECIOUS: Makefile + +all : $(INFO_DEPS) + +agdoc.texi : # self-depends upon all executables + $(run_mktexi) $@ + +autogen.dvi : agdoc.texi +autogen.texi : agdoc.texi mk-agen-texi.sh + @test -f $@ || { $(run_mktexi) $@ ; } + +# Special rule for generating all the GNU standard formats. +# +autogen.txt : autogen.texi + $(MIexe) --fill-column=70 --paragraph-indent=0 --no-headers \ + --output=$@ autogen.texi + +clobber : maintainer-clean + +.NOTPARALLEL: + +gnudocs : $(srcdir)/gendocs_template agdoc.texi + $(run_mktexi) $@ + +# doc/Makefile.am ends here + +# 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/doc/agdoc.texi b/doc/agdoc.texi new file mode 100644 index 0000000..9982e56 --- /dev/null +++ b/doc/agdoc.texi @@ -0,0 +1,13580 @@ +@settitle GNU AutoGen - The Automated Program Generator +@setchapternewpage off +@syncodeindex pg cp +@c %**end of header +@copying +This manual is for GNU AutoGen version 5.18, updated August 2018. + +Copyright @copyright{} 1992-2018 by Bruce Korb. + +@quotation +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.2 or +any later version published by the Free Software Foundation; with no +Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. +@end quotation +@end copying + +@ignore +EDIT THIS FILE WITH CAUTION (agdoc.texi) + +It has been AutoGen-ed +From the definitions /u/bkorb/tools/ag/autogen-bld/doc/ag-texi-32340.d/agdoc.def +and the template file auto_gen.tpl + +Plus bits and pieces gathered from all over the source/build +directories: + /u/bkorb/tools/ag/autogen-bld/doc/auto_gen.tpl + /u/bkorb/tools/ag/autogen-bld/agen5/opts.def + /u/bkorb/tools/ag/autogen-bld/doc/bitmaps.texi + /u/bkorb/tools/ag/autogen-bld/columns/invoke-columns.texi + /u/bkorb/tools/ag/autogen-bld/getdefs/invoke-getdefs.texi + /u/bkorb/tools/ag/autogen-bld/xml2ag/invoke-xml2ag.texi + /u/bkorb/tools/ag/autogen-bld/doc/snprintfv.texi + /u/bkorb/tools/ag/autogen-bld/agen5/defParse-fsm.c + /u/bkorb/tools/ag/autogen-bld/agen5/opts.h + /u/bkorb/tools/ag/autogen-bld/autoopts/libopts.texi + /u/bkorb/tools/ag/autogen-bld/doc/autogen-intro.texi + /u/bkorb/tools/ag/autogen-bld/agen5/invoke-autogen.texi + /u/bkorb/tools/ag/autogen-bld/agen5/agShell.c + /u/bkorb/tools/ag/autogen-bld/agen5/expExtract.c + /u/bkorb/tools/ag/autogen-bld/agen5/expFormat.c + /u/bkorb/tools/ag/autogen-bld/agen5/expGperf.c + /u/bkorb/tools/ag/autogen-bld/agen5/expGuile.c + /u/bkorb/tools/ag/autogen-bld/agen5/expMake.c + /u/bkorb/tools/ag/autogen-bld/agen5/expOutput.c + /u/bkorb/tools/ag/autogen-bld/agen5/expPrint.c + /u/bkorb/tools/ag/autogen-bld/agen5/expState.c + /u/bkorb/tools/ag/autogen-bld/agen5/expString.c + /u/bkorb/tools/ag/autogen-bld/agen5/fmemopen.c + /u/bkorb/tools/ag/autogen-bld/agen5/funcCase.c + /u/bkorb/tools/ag/autogen-bld/agen5/funcDef.c + /u/bkorb/tools/ag/autogen-bld/agen5/funcEval.c + /u/bkorb/tools/ag/autogen-bld/agen5/funcFor.c + /u/bkorb/tools/ag/autogen-bld/agen5/funcIf.c + /u/bkorb/tools/ag/autogen-bld/agen5/functions.c + /u/bkorb/tools/ag/autogen-bld/agen5/schemedef.scm + /u/bkorb/tools/ag/autogen-bld/doc/autogen-texi.txt + +@end ignore + +@dircategory GNU programming tools +@direntry +* AutoGen: (autogen). The Automated Program Generator +@end direntry + +@ifinfo +@ifnothtml +This file documents GNU AutoGen Version 5.18. + +AutoGen copyright @copyright{} 1992-2018 Bruce Korb +AutoOpts copyright @copyright{} 1992-2018 Bruce Korb +snprintfv copyright @copyright{} 1999-2000 Gary V. Vaughan + +AutoGen is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +AutoGen is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program. If not, see <http://www.gnu.org/licenses/>. + +@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. +@end ignore +@end ifnothtml +@end ifinfo + +@finalout +@titlepage +@title AutoGen - The Automated Program Generator +@subtitle For version 5.18, August 2018 +@author Bruce Korb +@author @email{bkorb@@gnu.org} + +@page +@vskip 0pt plus 1filll +AutoGen copyright @copyright{} 1992-2018 Bruce Korb +@sp 2 +This is the second edition of the GNU AutoGen documentation, +@sp 2 +Published by Bruce Korb, 910 Redwood Dr., Santa Cruz, CA 95060 + +AutoGen is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +AutoGen is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program. If not, see <http://www.gnu.org/licenses/>. + +@insertcopying +@end titlepage + +@node Top, Introduction, , (dir) +@top The Automated Program Generator +@comment node-name, next, previous, up + +This file documents AutoGen version 5.18. It is a tool designed +for generating program files that contain repetitive text with varied +substitutions. This document is very long because it is intended as a +reference document. For a quick start example, @xref{Example Usage}. + +The AutoGen distribution includes the basic generator engine and +several add-on libraries and programs. Of the most general interest +would be Automated Option processing, @xref{AutoOpts}, which also +includes stand-alone support for configuration file parsing, @xref{Features}. +@xref{Add-Ons, Add-on packages for AutoGen}, section for additional +programs and libraries associated with AutoGen. + +This edition documents version 5.18, August 2018. + +@ignore + +This file is part of AutoGen. +AutoGen is free software. +AutoGen is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + +AutoGen is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +AutoGen is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program. If not, see <http://www.gnu.org/licenses/>. + +This file has the following md5sum: + +43b91e8ca915626ed3818ffb1b71248b COPYING.gplv3 + +@end ignore +@menu +* Introduction:: AutoGen's Purpose +* Definitions File:: AutoGen Definitions File +* Template File:: AutoGen Template +* Augmenting AutoGen:: Augmenting AutoGen Features +* autogen Invocation:: Invoking AutoGen +* Installation:: Configuring and Installing +* AutoOpts:: Automated Option Processing +* Add-Ons:: Add-on packages for AutoGen +* Future:: Some ideas for the future. +* Copying This Manual:: Copying This Manual +* Concept Index:: General index +* Function Index:: Function index +@end menu + +@ignore +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +@end ignore +@page +@node Introduction +@chapter Introduction +@cindex Introduction + +AutoGen is a tool designed for generating program files that contain +repetitive text with varied substitutions. Its goal is to simplify the +maintenance of programs that contain large amounts of repetitious text. +This is especially valuable if there are several blocks of such text +that must be kept synchronized in parallel tables. + +An obvious example is the problem of maintaining the code required for +processing program options and configuration settings. Processing options +requires a minimum of four different constructs be kept in proper order in +different places in your program. You need at least: + +@enumerate +@item +The flag character in the flag string, +@item +code to process the flag when it is encountered, +@item +a global state variable or two, and +@item +a line in the usage text. +@end enumerate + +@noindent +You will need more things besides this if you choose to implement long option +names, configuration (rc/ini) file processing, environment variable settings +and keep all the documentation for these up to date. This can be done +mechanically; with the proper templates and this program. In fact, it has +already been done and AutoGen itself uses it@: @xref{AutoOpts}. For a simple +example of Automated Option processing, @xref{Quick Start}. For a full list +of the Automated Option features, @xref{Features}. Be forewarned, though, the +feature list is ridiculously extensive. + +@menu +* Generalities:: The Purpose of AutoGen +* Example Usage:: A Simple Example +* csh/zsh caveat:: csh/zsh caveat +* Testimonial:: A User's Perspective +@end menu + +@c === SECTION MARKER + +@node Generalities +@section The Purpose of AutoGen + +The idea of this program is to have a text file, a template if +you will, that contains the general text of the desired output file. +That file includes substitution expressions and sections of text that are +replicated under the control of separate definition files. + +@cindex design goals + +AutoGen was designed with the following features: + +@enumerate +@item +The definitions are completely separate from the template. By completely +isolating the definitions from the template it greatly increases the +flexibility of the template implementation. A secondary goal is that a +template user only needs to specify those data that are necessary to describe +his application of a template. + +@item +Each datum in the definitions is named. Thus, the definitions can be +rearranged, augmented and become obsolete without it being necessary to +go back and clean up older definition files. Reduce incompatibilities! + +@item +Every definition name defines an array of values, even when there is +only one entry. These arrays of values are used to control the +replication of sections of the template. + +@item +There are named collections of definitions. They form a nested hierarchy. +Associated values are collected and associated with a group name. +These associated data are used collectively in sets of substitutions. + +@item +The template has special markers to indicate where substitutions are +required, much like the @code{$@{VAR@}} construct in a shell @code{here doc}. +These markers are not fixed strings. They are specified at the start of +each template. Template designers know best what fits into their +syntax and can avoid marker conflicts. + +We did this because it is burdensome and difficult to avoid conflicts +using either M4 tokenization or C preprocessor substitution rules. It +also makes it easier to specify expressions that transform the value. +Of course, our expressions are less cryptic than the shell methods. + +@item +These same markers are used, in conjunction with enclosed keywords, to +indicate sections of text that are to be skipped and for sections of +text that are to be repeated. This is a major improvement over using C +preprocessing macros. With the C preprocessor, you have no way of +selecting output text because it is an @i{un}varying, mechanical +substitution process. + +@item +Finally, we supply methods for carefully controlling the output. +Sometimes, it is just simply easier and clearer to compute some text or +a value in one context when its application needs to be later. So, +functions are available for saving text or values for later use. +@end enumerate + +@c === SECTION MARKER + +@node Example Usage +@section A Simple Example +@cindex example, simple AutoGen + +This is just one simple example that shows a few basic features. +If you are interested, you also may run "make check" with the +@code{VERBOSE} environment variable set and see a number of other +examples in the @file{agen5/test} directory. + +Assume you have an enumeration of names and you wish to associate some +string with each name. Assume also, for the sake of this example, +that it is either too complex or too large to maintain easily by hand. +We will start by writing an abbreviated version of what the result +is supposed to be. We will use that to construct our output templates. + +@noindent +In a header file, @file{list.h}, you define the enumeration +and the global array containing the associated strings: + +@example +typedef enum @{ + IDX_ALPHA, + IDX_BETA, + IDX_OMEGA @} list_enum; + +extern char const* az_name_list[ 3 ]; +@end example + +@noindent +Then you also have @file{list.c} that defines the actual strings: + +@example +#include "list.h" +char const* az_name_list[] = @{ + "some alpha stuff", + "more beta stuff", + "final omega stuff" @}; +@end example + +@noindent +First, we will define the information that is unique for each enumeration +name/string pair. This would be placed in a file named, @file{list.def}, +for example. + +@example +autogen definitions list; +list = @{ list_element = alpha; + list_info = "some alpha stuff"; @}; +list = @{ list_info = "more beta stuff"; + list_element = beta; @}; +list = @{ list_element = omega; + list_info = "final omega stuff"; @}; +@end example + +The @code{autogen definitions list;} entry defines the file as an AutoGen +definition file that uses a template named @code{list}. That is followed by +three @code{list} entries that define the associations between the +enumeration names and the strings. The order of the differently named +elements inside of list is unimportant. They are reversed inside of the +@code{beta} entry and the output is unaffected. + +Now, to actually create the output, we need a template or two that can be +expanded into the files you want. In this program, we use a single template +that is capable of multiple output files. The definitions above refer to a +@file{list} template, so it would normally be named, @file{list.tpl}. + +It looks something like this. +(For a full description, @xref{Template File}.) + +@example +[+ AutoGen5 template h c +] +[+ CASE (suffix) +][+ + == h +] +typedef enum @{[+ + FOR list "," +] + IDX_[+ (string-upcase! (get "list_element")) +][+ + ENDFOR list +] @} list_enum; + +extern char const* az_name_list[ [+ (count "list") +] ]; +[+ + + == c +] +#include "list.h" +char const* az_name_list[] = @{[+ + FOR list "," +] + "[+list_info+]"[+ + ENDFOR list +] @};[+ + +ESAC +] +@end example + +The @code{[+ AutoGen5 template h c +]} text tells AutoGen that this is +an AutoGen version 5 template file; that it is to be processed twice; +that the start macro marker is @code{[+}; and the end marker is +@code{+]}. The template will be processed first with a suffix value of +@code{h} and then with @code{c}. Normally, the suffix values are +appended to the @file{base-name} to create the output file name. + +The @code{[+ == h +]} and @code{[+ == c +]} @code{CASE} selection clauses +select different text for the two different passes. In this example, +the output is nearly disjoint and could have been put in two separate +templates. However, sometimes there are common sections and this is +just an example. + +The @code{[+FOR list "," +]} and @code{[+ ENDFOR list +]} clauses delimit +a block of text that will be repeated for every definition of @code{list}. +Inside of that block, the definition name-value pairs that +are members of each @code{list} are available for substitutions. + +The remainder of the macros are expressions. Some of these contain +special expression functions that are dependent on AutoGen named values; +others are simply Scheme expressions, the result of which will be +inserted into the output text. Other expressions are names of AutoGen +values. These values will be inserted into the output text. For example, +@code{[+list_info+]} will result in the value associated with +the name @code{list_info} being inserted between the double quotes and +@code{(string-upcase! (get "list_element"))} will first "get" the value +associated with the name @code{list_element}, then change the case of +all the letters to upper case. The result will be inserted into the +output document. + +If you have compiled AutoGen, you can copy out the template and definitions +as described above and run @code{autogen list.def}. This will produce +exactly the hypothesized desired output. + +One more point, too. Lets say you decided it was too much trouble to figure +out how to use AutoGen, so you created this enumeration and string list with +thousands of entries. Now, requirements have changed and it has become +necessary to map a string containing the enumeration name into the enumeration +number. With AutoGen, you just alter the template to emit the table of names. +It will be guaranteed to be in the correct order, missing none of the entries. +If you want to do that by hand, well, good luck. + +@c === SECTION MARKER + +@node csh/zsh caveat +@section csh/zsh caveat + +AutoGen tries to use your normal shell so that you can supply shell code +in a manner you are accustomed to using. If, however, you use csh or +zsh, you cannot do this. Csh is sufficiently difficult to program that +it is unsupported. Zsh, though largely programmable, also has some +anomalies that make it incompatible with AutoGen usage. Therefore, when +invoking AutoGen from these environments, you must be certain to set the +SHELL environment variable to a Bourne-derived shell, e.g., sh, ksh or +bash. + +Any shell you choose for your own scripts need to follow these basic +requirements: + +@enumerate +@item +It handles @code{trap ":" $sig} without output to standard out. This is done +when the server shell is first started. If your shell does not handle this, +then it may be able to by loading functions from its start up files. +@item +At the beginning of each scriptlet, the command @code{\\cd $PWD} +is inserted. This ensures that @code{cd} is not aliased to something +peculiar and each scriptlet starts life in the execution directory. +@item +At the end of each scriptlet, the command @code{echo mumble} is +appended. The program you use as a shell must emit the single +argument @code{mumble} on a line by itself. +@end enumerate + +@c === SECTION MARKER + +@node Testimonial +@section A User's Perspective + +@format +Alexandre wrote: +> +> I'd appreciate opinions from others about advantages/disadvantages of +> each of these macro packages. +@end format + +I am using AutoGen in my pet project, and find one of its best points to +be that it separates the operational data from the implementation. + +Indulge me for a few paragraphs, and all will be revealed: +In the manual, Bruce cites the example of maintaining command line flags +inside the source code; traditionally spreading usage information, flag +names, letters and processing across several functions (if not files). +Investing the time in writing a sort of boiler plate (a template in +AutoGen terminology) pays by moving all of the option details (usage, +flags names etc.) into a well structured table (a definition file if you +will), so that adding a new command line option becomes a simple matter +of adding a set of details to the table. + +So far so good! Of course, now that there is a template, writing all of +that tedious optargs processing and usage functions is no longer an +issue. Creating a table of the options needed for the new project and +running AutoGen generates all of the option processing code in C +automatically from just the tabular data. AutoGen in fact already ships +with such a template... AutoOpts. + +One final consequence of the good separation in the design of AutoGen is +that it is retargetable to a greater extent. The +egcs/gcc/fixinc/inclhack.def can equally be used (with different +templates) to create a shell script (inclhack.sh) or a c program +(fixincl.c). + +This is just the tip of the iceberg. AutoGen is far more powerful than +these examples might indicate, and has many other varied uses. I am +certain Bruce or I could supply you with many and varied examples, and I +would heartily recommend that you try it for your project and see for +yourself how it compares to m4. +@cindex m4 + +As an aside, I would be interested to see whether someone might be +persuaded to rationalise autoconf with AutoGen in place of m4... Ben, +are you listening? autoconf-3.0! `kay? =)O| + +@format +Sincerely, + Gary V. Vaughan +@end format + +@ignore +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +@end ignore +@page +@node Definitions File +@chapter Definitions File +@cindex definitions file +@cindex .def file + +This chapter describes the syntax and semantics of the AutoGen +definition file. In order to instantiate a template, you normally must +provide a definitions file that identifies itself and contains some +value definitions. Consequently, we keep it very simple. For +"advanced" users, there are preprocessing directives, sparse +arrays, named indexes and comments that may be used as well. + +The definitions file is used to associate values with names. Every +value is implicitly an array of values, even if there is only one value. +Values may be either simple strings or compound collections of +name-value pairs. An array may not contain both simple and compound +members. Fundamentally, it is as simple as: + +@example +prog-name = "autogen"; +flag = @{ + name = templ_dirs; + value = L; + descrip = "Template search directory list"; +@}; +@end example + +For purposes of commenting and controlling the processing of the +definitions, C-style comments and most C preprocessing directives are +honored. The major exception is that the @code{#if} directive is +ignored, along with all following text through the matching +@code{#endif} directive. The C preprocessor is not actually invoked, so +C macro substitution is @strong{not} performed. + +@menu +* Identification:: The Identification Definition +* Definitions:: Named Definitions +* Index Assignments:: Assigning an Index to a Definition +* Dynamic Text:: Dynamic Text +* Directives:: Controlling What Gets Processed +* Predefines:: Pre-defined Names +* Comments:: Commenting Your Definitions +* Example:: What it all looks like. +* Full Syntax:: Finite State Machine Grammar +* Alternate Definition:: Alternate Definition Forms +@end menu + +@c === SECTION MARKER + +@node Identification +@section The Identification Definition +@cindex identification + +The first definition in this file is used to identify it as a +AutoGen file. It consists of the two keywords, +@samp{autogen} and @samp{definitions} followed by the default +template name and a terminating semi-colon (@code{;}). That is: + +@example + AutoGen Definitions @var{template-name}; +@end example + +@noindent +Note that, other than the name @var{template-name}, the words +@samp{AutoGen} and @samp{Definitions} are searched for without case +sensitivity. Most lookups in this program are case insensitive. + +@noindent +Also, if the input contains more identification definitions, +they will be ignored. This is done so that you may include +(@pxref{Directives}) other definition files without an identification +conflict. + +@cindex template file + +@noindent +AutoGen uses the name of the template to find the corresponding template +file. It searches for the file in the following way, stopping when +it finds the file: + +@enumerate +@item +It tries to open @file{./@var{template-name}}. If it fails, +@item +it tries @file{./@var{template-name}.tpl}. +@item +It searches for either of these files in the directories listed in the +templ-dirs command line option. +@end enumerate + +If AutoGen fails to find the template file in one of these places, +it prints an error message and exits. + +@c === SECTION MARKER + +@node Definitions +@section Named Definitions +@cindex definitions + +A name is a sequence of characters beginning with an alphabetic character +(@code{a} through @code{z}) followed by zero or more alpha-numeric +characters and/or separator characters: hyphen (@code{-}), underscore +(@code{_}) or carat (@code{^}). Names are case insensitive. + +Any name may have multiple values associated with it. Every name may be +considered a sparse array of one or more elements. If there is more than +one value, the values my be accessed by indexing the value with +@code{[index]} or by iterating over them using the FOR (@pxref{FOR}) AutoGen +macro on it, as described in the next chapter. Sparse arrays are specified +by specifying an index when defining an entry +(@pxref{Index Assignments,, Assigning an Index to a Definition}). + +There are two kinds of definitions, @samp{simple} and @samp{compound}. +They are defined thus (@pxref{Full Syntax}): + +@example +compound_name '=' '@{' definition-list '@}' ';' + +simple-name[2] '=' string ';' + +no^text^name ';' +@end example + +@noindent +@code{simple-name} has the third index (index number 2) defined here. +@code{No^text^name} is a simple definition with a shorthand empty string +value. The string values for definitions may be specified in any of +several formation rules. + +@menu +* def-list:: Definition List +* double-quote-string:: Double Quote String +* single-quote-string:: Single Quote String +* simple-string:: An Unquoted String +* shell-generated:: Shell Output String +* scheme-generated:: Scheme Result String +* here-string:: A Here String +* concat-string:: Concatenated Strings +@end menu + +@cindex simple definitions +@cindex compound definitions + +@node def-list +@subsection Definition List + +@code{definition-list} is a list of definitions that may or may not +contain nested compound definitions. Any such definitions may +@strong{only} be expanded within a @code{FOR} block iterating over the +containing compound definition. @xref{FOR}. + +Here is, again, the example definitions from the previous chapter, +with three additional name value pairs. Two with an empty value +assigned (@var{first} and @var{last}), and a "global" @var{group_name}. + +@example +autogen definitions list; +group_name = example; +list = @{ list_element = alpha; first; + list_info = "some alpha stuff"; @}; +list = @{ list_info = "more beta stuff"; + list_element = beta; @}; +list = @{ list_element = omega; last; + list_info = "final omega stuff"; @}; +@end example + +@node double-quote-string +@subsection Double Quote String + +@cindex string, double quote +The string follows the C-style escaping, using the backslash to quote +(escape) the following character(s). Certain letters are translated to +various control codes (e.g. @code{\n}, @code{\f}, @code{\t}, etc.). +@code{x} introduces a two character hex code. @code{0} (the digit zero) +introduces a one to three character octal code (note: an octal byte followed +by a digit must be represented with three octal digits, thus: @code{"\0001"} +yielding a NUL byte followed by the ASCII digit 1). Any other character +following the backslash escape is simply inserted, without error, into the +string being formed. + +Like ANSI "C", a series of these strings, possibly intermixed with +single quote strings, will be concatenated together. + +@node single-quote-string +@subsection Single Quote String + +@cindex string, single quote +This is similar to the shell single-quote string. However, escapes +@code{\} are honored before another escape, single quotes @code{'} +and hash characters @code{#}. This latter is done specifically +to disambiguate lines starting with a hash character inside +of a quoted string. In other words, + +@example +fumble = ' +#endif +'; +@end example + +could be misinterpreted by the definitions scanner, whereas +this would not: + +@example +fumble = ' +\#endif +'; +@end example + +@* +As with the double quote string, a series of these, even intermixed +with double quote strings, will be concatenated together. + +@node simple-string +@subsection An Unquoted String + +A simple string that does not contain white space @i{may} be left +unquoted. The string must not contain any of the characters special to +the definition text (i.e., @code{"}, @code{#}, @code{'}, @code{(}, +@code{)}, @code{,}, @code{;}, @code{<}, @code{=}, @code{>}, @code{[}, +@code{]}, @code{`}, @code{@{}, or @code{@}}). This list is subject to +change, but it will never contain underscore (@code{_}), period +(@code{.}), slash (@code{/}), colon (@code{:}), hyphen (@code{-}) or +backslash (@code{\\}). Basically, if the string looks like it is a +normal DOS or UNIX file or variable name, and it is not one of two +keywords (@samp{autogen} or @samp{definitions}) then it is OK to not +quote it, otherwise you should. + +@node shell-generated +@subsection Shell Output String +@cindex shell-generated string + +@cindex string, shell output +This is assembled according to the same rules as the double quote string, +except that there is no concatenation of strings and the resulting string is +written to a shell server process. The definition takes on the value of +the output string. + +NB@: The text is interpreted by a server shell. There may be left over +state from previous server shell processing. This scriptlet may also leave +state for subsequent processing. However, a @code{cd} to the original +directory is always issued before the new command is issued. + +@node scheme-generated +@subsection Scheme Result String + +A scheme result string must begin with an open parenthesis @code{(}. +The scheme expression will be evaluated by Guile and the +value will be the result. The AutoGen expression functions +are @strong{dis}abled at this stage, so do not use them. + +@node here-string +@subsection A Here String +@cindex here-string + +A @samp{here string} is formed in much the same way as a shell here doc. It +is denoted with two less than characters(@code{<<}) and, optionally, a hyphen. +This is followed by optional horizontal white space and an ending +marker-identifier. This marker must follow the syntax rules for identifiers. +Unlike the shell version, however, you must not quote this marker. + +The resulting string will start with the first character on the next line and +continue up to but not including the newline that precedes the line that +begins with the marker token. The characters are copied directly into the +result string. Mostly. + +If a hyphen follows the less than characters, then leading tabs will be +stripped and the terminating marker will be recognized even if preceded by +tabs. Also, if the first character on the line (after removing tabs) is a +backslash and the next character is a tab or space, then the backslash will +be removed as well. No other kind of processing is done on this string. + +Here are three examples: +@example +str1 = <<- STR_END + $quotes = " ' ` + STR_END; + +str2 = << STR_END + $quotes = " ' ` + STR_END; +STR_END; + +str3 = <<- STR_END + \ $quotes = " ' ` + STR_END; +@end example +The first string contains no new line characters. +The first character is the dollar sign, the last the back quote. + +The second string contains one new line character. The first character +is the tab character preceding the dollar sign. The last character is +the semicolon after the @code{STR_END}. That @code{STR_END} does not +end the string because it is not at the beginning of the line. In the +preceding case, the leading tab was stripped. + +The third string is almost identical to the first, except that the +first character is a tab. That is, it exactly matches the first line +of the second string. + +@node concat-string +@subsection Concatenated Strings +@cindex concat-string + +If single or double quote characters are used, +then you also have the option, a la ANSI-C syntax, +of implicitly concatenating a series of them together, +with intervening white space ignored. + +NB@: You @strong{cannot} use directives to alter the string +content. That is, + +@example +str = "fumble" +#ifdef LATER + "stumble" +#endif + ; +@end example + +@noindent +will result in a syntax error. The preprocessing directives are not +carried out by the C preprocessor. However, + +@example +str = '"fumble\n" +#ifdef LATER +" stumble\n" +#endif +'; +@end example + +@noindent +@strong{Will} work. It will enclose the @samp{#ifdef LATER} +and @samp{#endif} in the string. But it may also wreak +havoc with the definition processing directives. The hash +characters in the first column should be disambiguated with +an escape @code{\} or join them with previous lines: +@code{"fumble\n#ifdef LATER...}. + +@c === SECTION MARKER + +@node Index Assignments +@section Assigning an Index to a Definition +@cindex Definition Index + +In AutoGen, every name is implicitly an array of values. +When assigning values, they are usually implicitly +assigned to the next highest slot. They can also be +specified explicitly: + +@example +mumble[9] = stumble; +mumble[0] = grumble; +@end example + +@noindent +If, subsequently, you assign a value to @code{mumble} without an +index, its index will be @code{10}, not @code{1}. +If indexes are specified, they must not cause conflicts. + +@code{#define}-d names may also be used for index values. +This is equivalent to the above: + +@example +#define FIRST 0 +#define LAST 9 +mumble[LAST] = stumble; +mumble[FIRST] = grumble; +@end example + +All values in a range do @strong{not} have to be filled in. +If you leave gaps, then you will have a sparse array. This +is fine (@pxref{FOR}). You have your choice of iterating +over all the defined values, or iterating over a range +of slots. This: + +@example +[+ FOR mumble +][+ ENDFOR +] +@end example + +@noindent +iterates over all and only the defined entries, whereas this: + +@example +[+ FOR mumble (for-by 1) +][+ ENDFOR +] +@end example + +@noindent +will iterate over all 10 "slots". Your template will +likely have to contain something like this: + +@example +[+ IF (exist? (sprintf "mumble[%d]" (for-index))) +] +@end example + +@noindent +or else "mumble" will have to be a compound value that, +say, always contains a "grumble" value: + +@example +[+ IF (exist? "grumble") +] +@end example + +@c === SECTION MARKER + +@node Dynamic Text +@section Dynamic Text +@cindex Dynamic Definition Text + +There are several methods for including dynamic content inside a definitions +file. Three of them are mentioned above (@ref{shell-generated} and +@pxref{scheme-generated}) in the discussion of string formation rules. +Another method uses the @code{#shell} processing directive. +It will be discussed in the next section (@pxref{Directives}). +Guile/Scheme may also be used to yield to create definitions. + +When the Scheme expression is preceded by a backslash and single +quote, then the expression is expected to be an alist of +names and values that will be used to create AutoGen definitions. + +@noindent +This method can be be used as follows: + +@example +\'( (name (value-expression)) + (name2 (another-expr)) ) +@end example + +@noindent +This is entirely equivalent to: + +@example +name = (value-expression); +name2 = (another-expr); +@end example + +@noindent +Under the covers, the expression gets handed off to a Guile function +named @code{alist->autogen-def} in an expression that looks like this: + +@example +(alist->autogen-def + ( (name (value-expression)) (name2 (another-expr)) ) ) +@end example + +@node Directives +@section Controlling What Gets Processed +@cindex directives + +Definition processing directives can @strong{only} be processed +if the '#' character is the first character on a line. Also, if you +want a '#' as the first character of a line in one of your string +assignments, you should either escape it by preceding it with a +backslash @samp{\}, or by embedding it in the string as in @code{"\n#"}. + +All of the normal C preprocessing directives are recognized, though +several are ignored. There is also an additional @code{#shell} - +@code{#endshell} pair. Another minor difference is that AutoGen +directives must have the hash character (@code{#}) in column 1. +Unrecognized directives produce an error. + +The final tweak is that @code{#!} is treated as a comment line. +Using this feature, you can use: @samp{#! /usr/local/bin/autogen} +as the first line of a definitions file, set the mode to executable +and "run" the definitions file as if it were a direct invocation of +AutoGen. This was done for its hack value. + +The AutoGen recognized directives are: +@table @code +@item #assert +@cindex assert +@cindex assert directive +This directive @i{is} processed, but only if the expression begins with +either a back quote (@code{`}) or an open parenthesis (@code{(}). +Text within the back quotes are handed off to the shell for processing +and parenthesized text is handed off to Guile. Multiple line expressions +must be joined with backslashes. + +If the @code{shell-script} or @code{scheme-expr} do not yield @code{true} +valued results, autogen will be aborted. If @code{<anything else>} or +nothing at all is provided, then this directive is ignored. + +The result is @code{false} (and fails) if the result is empty, the +number zero, or a string that starts with the letters 'n' or 'f' ("no" +or "false"). + +@item #define +@cindex define +@cindex define directive +Will add the name to the define list as if it were a DEFINE program +argument. Its value will be the first non-whitespace token following +the name. Quotes are @strong{not} processed. + +After the definitions file has been processed, any remaining entries +in the define list will be added to the environment. + +@item #elif +@cindex elif +@cindex elif directive +Marks a transition in the #if directive. Error when out of context. +#if blocks are always ignored. + +@item #else +@cindex else +@cindex else directive +This must follow an @code{#if}, @code{#ifdef} or @code{#ifndef}. +If it follows the @code{#if}, then it will be ignored. Otherwise, +it will change the processing state to the reverse of what it was. + +@item #endif +@cindex endif +@cindex endif directive +This must follow an @code{#if}, @code{#ifdef} or @code{#ifndef}. +In all cases, this will resume normal processing of text. + +@item #endmac +@cindex endmac +@cindex endmac directive +Marks the end of the #macdef directive. Error when out of context. + +@item #endshell +@cindex endshell +@cindex endshell directive +Marks the end of the #shell directive. Error when out of context. + +@item #error +@cindex error +@cindex error directive +This directive will cause AutoGen to stop processing +and exit with a status of EXIT_FAILURE. + +@item #ident +@cindex ident +@cindex ident directive +Ignored directive. + +@item #if +@cindex if +@cindex if directive +@code{#if} expressions are not analyzed. @strong{Everything} from here +to the matching @code{#endif} is skipped. + +@item #ifdef +@cindex ifdef +@cindex ifdef directive +The definitions that follow, up to the matching @code{#endif} will be +processed only if there is a corresponding @code{-Dname} command line +option or if a @code{#define} of that name has been previously encountered. + +@item #ifndef +@cindex ifndef +@cindex ifndef directive +The definitions that follow, up to the matching @code{#endif} will be +processed only if the named value has @strong{not} been defined. + +@item #include +@cindex include +@cindex include directive +This directive will insert definitions from another file into +the current collection. If the file name is adorned with +double quotes or angle brackets (as in a C program), then the +include is ignored. + +@item #let +@cindex let +@cindex let directive +Ignored directive. + +@item #line +@cindex line +@cindex line directive +Alters the current line number and/or file name. You may wish to +use this directive if you extract definition source from other files. +@command{getdefs} uses this mechanism so AutoGen will report the correct +file and approximate line number of any errors found in extracted +definitions. + +@item #macdef +@cindex macdef +@cindex macdef directive +This is a new AT&T research preprocessing directive. Basically, it is +a multi-line #define that may include other preprocessing directives. +Text between this line and a #endmac directive are ignored. + +@item #option +@cindex option +@cindex option directive +This directive will pass the option name and associated text to the +AutoOpts optionLoadLine routine (@pxref{libopts-optionLoadLine}). The +option text may span multiple lines by continuing them with a backslash. +The backslash/newline pair will be replaced with two space characters. +This directive may be used to set a search path for locating template files +For example, this: + +@example +#option templ-dirs $ENVVAR/dirname +@end example +@noindent +will direct autogen to use the @code{ENVVAR} environment variable to find +a directory named @code{dirname} that (may) contain templates. Since these +directories are searched in most recently supplied first order, search +directories supplied in this way will be searched before any supplied on +the command line. + +@item #pragma +@cindex pragma +@cindex pragma directive +Ignored directive. + +@item #shell +@cindex shell +@cindex shell directive +Invokes @code{$SHELL} or @file{/bin/sh} on a script that should +generate AutoGen definitions. It does this using the same server +process that handles the back-quoted @code{`} text. +The block of text handed to the shell is terminated with +the #endshell directive. + +@strong{CAUTION}@: let not your @code{$SHELL} be @code{csh}. + +@item #undef +@cindex undef +@cindex undef directive +Will remove any entries from the define list +that match the undef name pattern. +@end table +@ignore +START == COMMENTS == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@ignore +Resume input from autogen.texi +@end ignore + +@c === SECTION MARKER + +@node Predefines +@section Pre-defined Names +@cindex predefines + +When AutoGen starts, it tries to determine several names from the +operating environment and put them into environment variables for use in +both @code{#ifdef} tests in the definitions files and in shell scripts +with environment variable tests. @env{__autogen__} is always defined. +For other names, AutoGen will first try to use the POSIX version of the +@code{sysinfo(2)} system call. Failing that, it will try for the POSIX +@code{uname(2)} call. If neither is available, then only +"@env{__autogen__}" will be inserted into the environment. +In all cases, the associated names are converted to lower case, surrounded +by doubled underscores and non-symbol characters are replaced with +underscores. + +With Solaris on a sparc platform, @code{sysinfo(2)} is available. +The following strings are used: + +@itemize @bullet +@item +@code{SI_SYSNAME} (e.g., "__sunos__") +@item +@code{SI_HOSTNAME} (e.g., "__ellen__") +@item +@code{SI_ARCHITECTURE} (e.g., "__sparc__") +@item +@code{SI_HW_PROVIDER} (e.g., "__sun_microsystems__") +@item +@code{SI_PLATFORM} (e.g., "__sun_ultra_5_10__") +@item +@code{SI_MACHINE} (e.g., "__sun4u__") +@end itemize + +For Linux and other operating systems that only support the +@code{uname(2)} call, AutoGen will use these values: + +@itemize @bullet +@item +@code{sysname} (e.g., "__linux__") +@item +@code{machine} (e.g., "__i586__") +@item +@code{nodename} (e.g., "__bach__") +@end itemize + +By testing these pre-defines in my definitions, you can select +pieces of the definitions without resorting to writing shell +scripts that parse the output of @code{uname(1)}. You can also +segregate real C code from autogen definitions by testing for +"@code{__autogen__}". + +@example +#ifdef __bach__ + location = home; +#else + location = work; +#endif +@end example + +@c === SECTION MARKER + +@node Comments +@section Commenting Your Definitions +@cindex comments + +The definitions file may contain C and C++ style comments. + +@example +/* + * This is a comment. It continues for several lines and closes + * when the characters '*' and '/' appear together. + */ +// this comment is a single line comment +@end example + +@c === SECTION MARKER + +@node Example +@section What it all looks like. + +@noindent +This is an extended example: + +@example +autogen definitions @samp{template-name}; +/* + * This is a comment that describes what these + * definitions are all about. + */ +global = "value for a global text definition."; + +/* + * Include a standard set of definitions + */ +#include standards.def + +a_block = @{ + a_field; + a_subblock = @{ + sub_name = first; + sub_field = "sub value."; + @}; + +#ifdef FEATURE + a_subblock = @{ + sub_name = second; + @}; +#endif + +@}; +@end example + +@ignore +END == COMMENTS == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore +@node Full Syntax +@section Finite State Machine Grammar + +The preprocessing directives and comments are not part of the grammar. They +are handled by the scanner/lexer. The following was extracted directly from +the generated defParse-fsm.c source file. The "EVT:" is the token seen, +the "STATE:" is the current state and the entries in this table describe +the next state and the action to take. Invalid transitions were removed +from the table. + +@ignore +Extracted from $top_srcdir/agen5/defParse.y +@end ignore +@example +dp_trans_table[ DP_STATE_CT ][ DP_EVENT_CT ] = @{ + + /* STATE 0: DP_ST_INIT */ + @{ @{ DP_ST_NEED_DEF, NULL @}, /* EVT: AUTOGEN */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: DEFINITIONS */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: End-Of-File */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: VAR_NAME */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: OTHER_NAME */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: STRING */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: HERE_STRING */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: DELETE_ENT */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: NUMBER */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: ; */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: = */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: , */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: @{ */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: @} */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: [ */ + @{ DP_ST_INVALID, dp_do_invalid @} /* EVT: ] */ + + /* STATE 1: DP_ST_NEED_DEF */ + @{ @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: AUTOGEN */ + @{ DP_ST_NEED_TPL, NULL @}, /* EVT: DEFINITIONS */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: End-Of-File */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: VAR_NAME */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: OTHER_NAME */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: STRING */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: HERE_STRING */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: DELETE_ENT */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: NUMBER */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: ; */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: = */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: , */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: @{ */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: @} */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: [ */ + @{ DP_ST_INVALID, dp_do_invalid @} /* EVT: ] */ + + /* STATE 2: DP_ST_NEED_TPL */ + @{ @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: AUTOGEN */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: DEFINITIONS */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: End-Of-File */ + @{ DP_ST_NEED_SEMI, dp_do_tpl_name @}, /* EVT: VAR_NAME */ + @{ DP_ST_NEED_SEMI, dp_do_tpl_name @}, /* EVT: OTHER_NAME */ + @{ DP_ST_NEED_SEMI, dp_do_tpl_name @}, /* EVT: STRING */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: HERE_STRING */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: DELETE_ENT */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: NUMBER */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: ; */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: = */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: , */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: @{ */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: @} */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: [ */ + @{ DP_ST_INVALID, dp_do_invalid @} /* EVT: ] */ + + /* STATE 3: DP_ST_NEED_SEMI */ + @{ @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: AUTOGEN */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: DEFINITIONS */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: End-Of-File */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: VAR_NAME */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: OTHER_NAME */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: STRING */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: HERE_STRING */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: DELETE_ENT */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: NUMBER */ + @{ DP_ST_NEED_NAME, NULL @}, /* EVT: ; */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: = */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: , */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: @{ */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: @} */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: [ */ + @{ DP_ST_INVALID, dp_do_invalid @} /* EVT: ] */ + + /* STATE 4: DP_ST_NEED_NAME */ + @{ @{ DP_ST_NEED_DEF, NULL @}, /* EVT: AUTOGEN */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: DEFINITIONS */ + @{ DP_ST_DONE, dp_do_need_name_end @}, /* EVT: End-Of-File */ + @{ DP_ST_HAVE_NAME, dp_do_need_name_var_name @}, /* EVT: VAR_NAME */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: OTHER_NAME */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: STRING */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: HERE_STRING */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: DELETE_ENT */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: NUMBER */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: ; */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: = */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: , */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: @{ */ + @{ DP_ST_HAVE_VALUE, dp_do_end_block @}, /* EVT: @} */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: [ */ + @{ DP_ST_INVALID, dp_do_invalid @} /* EVT: ] */ + + /* STATE 5: DP_ST_HAVE_NAME */ + @{ @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: AUTOGEN */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: DEFINITIONS */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: End-Of-File */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: VAR_NAME */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: OTHER_NAME */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: STRING */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: HERE_STRING */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: DELETE_ENT */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: NUMBER */ + @{ DP_ST_NEED_NAME, dp_do_empty_val @}, /* EVT: ; */ + @{ DP_ST_NEED_VALUE, dp_do_have_name_lit_eq @}, /* EVT: = */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: , */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: @{ */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: @} */ + @{ DP_ST_NEED_IDX, NULL @}, /* EVT: [ */ + @{ DP_ST_INVALID, dp_do_invalid @} /* EVT: ] */ + + /* STATE 6: DP_ST_NEED_VALUE */ + @{ @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: AUTOGEN */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: DEFINITIONS */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: End-Of-File */ + @{ DP_ST_HAVE_VALUE, dp_do_str_value @}, /* EVT: VAR_NAME */ + @{ DP_ST_HAVE_VALUE, dp_do_str_value @}, /* EVT: OTHER_NAME */ + @{ DP_ST_HAVE_VALUE, dp_do_str_value @}, /* EVT: STRING */ + @{ DP_ST_HAVE_VALUE, dp_do_str_value @}, /* EVT: HERE_STRING */ + @{ DP_ST_NEED_NAME, dp_do_need_value_delete_ent @}, /* EVT: DELETE_ENT */ + @{ DP_ST_HAVE_VALUE, dp_do_str_value @}, /* EVT: NUMBER */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: ; */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: = */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: , */ + @{ DP_ST_NEED_NAME, dp_do_start_block @}, /* EVT: @{ */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: @} */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: [ */ + @{ DP_ST_INVALID, dp_do_invalid @} /* EVT: ] */ + + /* STATE 7: DP_ST_NEED_IDX */ + @{ @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: AUTOGEN */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: DEFINITIONS */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: End-Of-File */ + @{ DP_ST_NEED_CBKT, dp_do_indexed_name @}, /* EVT: VAR_NAME */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: OTHER_NAME */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: STRING */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: HERE_STRING */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: DELETE_ENT */ + @{ DP_ST_NEED_CBKT, dp_do_indexed_name @}, /* EVT: NUMBER */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: ; */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: = */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: , */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: @{ */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: @} */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: [ */ + @{ DP_ST_INVALID, dp_do_invalid @} /* EVT: ] */ + + /* STATE 8: DP_ST_NEED_CBKT */ + @{ @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: AUTOGEN */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: DEFINITIONS */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: End-Of-File */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: VAR_NAME */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: OTHER_NAME */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: STRING */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: HERE_STRING */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: DELETE_ENT */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: NUMBER */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: ; */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: = */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: , */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: @{ */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: @} */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: [ */ + @{ DP_ST_INDX_NAME, NULL @} /* EVT: ] */ + + /* STATE 9: DP_ST_INDX_NAME */ + @{ @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: AUTOGEN */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: DEFINITIONS */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: End-Of-File */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: VAR_NAME */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: OTHER_NAME */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: STRING */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: HERE_STRING */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: DELETE_ENT */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: NUMBER */ + @{ DP_ST_NEED_NAME, dp_do_empty_val @}, /* EVT: ; */ + @{ DP_ST_NEED_VALUE, NULL @}, /* EVT: = */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: , */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: @{ */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: @} */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: [ */ + @{ DP_ST_INVALID, dp_do_invalid @} /* EVT: ] */ + + /* STATE 10: DP_ST_HAVE_VALUE */ + @{ @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: AUTOGEN */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: DEFINITIONS */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: End-Of-File */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: VAR_NAME */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: OTHER_NAME */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: STRING */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: HERE_STRING */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: DELETE_ENT */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: NUMBER */ + @{ DP_ST_NEED_NAME, NULL @}, /* EVT: ; */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: = */ + @{ DP_ST_NEED_VALUE, dp_do_next_val @}, /* EVT: , */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: @{ */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: @} */ + @{ DP_ST_INVALID, dp_do_invalid @}, /* EVT: [ */ + @{ DP_ST_INVALID, dp_do_invalid @} /* EVT: ] */ +@end example +@ignore +START == TEMPLATE == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@c === SECTION MARKER + +@node Alternate Definition +@section Alternate Definition Forms +@cindex Alternate Definition + +There are several methods for supplying data values for templates. + +@table @samp +@item no definitions +It is entirely possible to write a template that does not depend upon +external definitions. Such a template would likely have an unvarying +output, but be convenient nonetheless because of an external library +of either AutoGen or Scheme functions, or both. This can be accommodated +by providing the @option{--override-tpl} and @option{--no-definitions} +options on the command line. @xref{autogen Invocation}. + +@item CGI +AutoGen behaves as a CGI server if the definitions input is from stdin +and the environment variable @env{REQUEST_METHOD} is defined +and set to either "GET" or "POST", @xref{AutoGen CGI}. Obviously, +all the values are constrained to strings because there is no way +to represent nested values. + +@item XML +AutoGen comes with a program named, @command{xml2ag}. Its output can +either be redirected to a file for later use, or the program can +be used as an AutoGen wrapper. @xref{xml2ag Invocation}. + +The introductory template example (@pxref{Example Usage}) can be rewritten +in XML as follows: + +@example +<EXAMPLE template="list.tpl"> +<LIST list_element="alpha" + list_info="some alpha stuff"/> +<LIST list_info="more beta stuff" + list_element="beta"/> +<LIST list_element="omega" + list_info="final omega stuff"/> +</EXAMPLE> +@end example + +A more XML-normal form might look like this: +@example +<EXAMPLE template="list.tpl"> +<LIST list_element="alpha">some alpha stuff</LIST> +<LIST list_element="beta" >more beta stuff</LIST> +<LIST list_element="omega">final omega stuff</LIST> +</EXAMPLE> +@end example +@noindent +but you would have to change the template @code{list-info} references +into @code{text} references. + +@item standard AutoGen definitions +Of course. :-) + +@end table + +@ignore +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +@end ignore +@page +@node Template File +@chapter Template File +@cindex template file +@cindex .tpl file + +The AutoGen template file defines the content of the output text. +It is composed of two parts. The first part consists of a pseudo +macro invocation and commentary. It is followed by the template proper. + +@cindex pseudo macro +@cindex macro, pseudo +This pseudo macro is special. It is used to identify the file as a +AutoGen template file, fixing the starting and ending marks for +the macro invocations in the rest of the file, specifying the list +of suffixes to be generated by the template and, optionally, the +shell to use for processing shell commands embedded in the template. + +AutoGen-ing a file consists of copying text from the template to the +output file until a start macro marker is found. The text from the +start marker to the end marker constitutes the macro text. AutoGen +macros may cause sections of the template to be skipped or processed +several times. The process continues until the end of the template is +reached. The process is repeated once for each suffix specified in the +pseudo macro. + +This chapter describes the format of the AutoGen template macros +and the usage of the AutoGen native macros. Users may augment +these by defining their own macros, @xref{DEFINE}. + +@menu +* pseudo macro:: Format of the Pseudo Macro +* naming values:: Naming a value +* expression syntax:: Macro Expression Syntax +* AutoGen Functions:: AutoGen Scheme Functions +* Common Functions:: Common Scheme Functions +* native macros:: AutoGen Native Macros +* output controls:: Redirecting Output +@end menu + +@c === SECTION MARKER + +@node pseudo macro +@section Format of the Pseudo Macro +@cindex pseudo macro + +The pseudo macro is used to tell AutoGen how to process a template. +It tells autogen: + +@enumerate +@item +The start macro marker. It consists of punctuation characters used to +demarcate the start of a macro. It may be up to seven characters long and +must be the first non-whitespace characters in the file. + +@noindent +It is generally a good idea to use some sort of opening +bracket in the starting macro and closing bracket in the ending +macro (e.g. @code{@{}, @code{(}, @code{[}, or even @code{<} +in the starting macro). It helps both visually and with editors +capable of finding a balancing parenthesis. + +@item +That start marker must be immediately followed by the identifier strings +"AutoGen5" and then "template", though capitalization is not important. +@end enumerate + +@noindent +The next several components may be intermingled: + +@enumerate 3 +@item +Zero, one or more suffix specifications tell AutoGen how many times to +process the template file. No suffix specifications mean that it is to +be processed once and that the generated text is to be written to +@file{stdout}. The current suffix for each pass can be determined with the +@code{(suffix)} scheme function (@pxref{SCM suffix}). + +The suffix specification consists of a sequence of POSIX compliant file name +characters and, optionally, an equal sign and a file name formatting +specification. That specification may be either an ordinary sequence of +file name characters with zero, one or two "%s" formatting sequences in it, +or else it may be a Scheme expression that, when evaluated, produces such a +string. The Scheme result may not be empty. The two string arguments +allowed for that string are the base name of the definition file, and the +current suffix (that being the text to the left of the equal sign). (Note: +"POSIX compliant file name characters" consist of alphanumerics plus the +period (@code{.}), hyphen (@code{-}) and underscore (@code{_}) characters.) + +If the suffix begins with one of these three latter characters and +a formatting string is not specified, then that character is presumed to +be the suffix separator. Otherwise, without a specified format string, +a single period will separate the suffix from the base name in constructing +the output file name. + +@item +Shell specification: to specify that the template was written expecting a +particular shell to run the shell commands. By default, the shell used is the +autoconf-ed @env{CONFIG_SHELL}. This will usually be @file{/bin/sh}. The +shell is specified by a hash mark (@code{#}) followed by an exclamation mark +(@code{!}) followed by a full-path file name (e.g. @file{/usr/xpg4/bin/sh} on +Solaris): +@example +[= Autogen5 Template c +#!/usr/xpg4/bin/sh +=] +@end example + +@item +Comments: blank lines, lines starting with a hash mark (@code{#}) and not +specifying a shell, and edit mode markers (text between pairs of @code{-*-} +strings) are all treated as comments. + +@item +Some scheme expressions may be inserted in order to make configuration +changes before template processing begins. +@i{before template processing begins} means that there is no current +output file, no current suffix and, basically, none of the AutoGen +specific functions +(@pxref{AutoGen Functions}) may be invoked. + +The scheme expression can also be used, for example, to save a pre-existing +output file for later text extraction (@pxref{SCM extract}). + +@example +(shellf "mv -f %1$s.c %1$s.sav" (base-name)) +@end example +@end enumerate + +@noindent +After these must come the end macro marker: + +@enumerate 6 +@item +The punctuation characters used to demarcate the end of a macro. +Like the start marker, it must consist of seven or fewer punctuation +characters. +@end enumerate + +The ending macro marker has a few constraints on its content. Some of +them are just advisory, though. There is no special check for advisory +restrictions. + +@itemize @bullet +@item +It must not begin with a POSIX file name character (hyphen @code{-}, +underscore @code{_} or period @code{.}), the backslash (@code{\}) or +open parenthesis (@code{(}). These are used to identify a suffix +specification, indicate Scheme code and trim white space. + +@item +If it begins with an equal sign, then it +must be separated from any suffix specification by white space. + +@item +The closing marker may not begin with an open parenthesis, as that is used +to enclose a scheme expression. + +@item +It cannot begin with a backslash, as that is used to indicate white +space trimming after the end macro mark. If, in the body of the template, +you put the backslash character (@code{\}) before the end macro mark, then +any white space characters after the mark and through the newline character +are trimmed. + +@item +It is also helpful to avoid using the comment marker (@code{#}). +It might be seen as a comment within the pseudo macro. + +@item +You should avoid using any of the quote characters@: double, +single or back-quote. It won't confuse AutoGen, but it might well +confuse you and/or your editor. +@end itemize + +As an example, assume we want to use @code{[+} and @code{+]} as the start +and end macro markers, and we wish to produce a @file{.c} and a @file{.h} +file, then the pseudo macro might look something like this: + +@example +[+ AutoGen5 template -*- Mode: emacs-mode-of-choice -*- +h=chk-%s.h +c +# make sure we don't use csh: +(setenv "SHELL" "/bin/sh") +] +@end example + +The template proper starts after the pseudo-macro. The starting +character is either the first non-whitespace character or the first +character after the newline that follows the end macro marker. + +@c === SECTION MARKER + +@node naming values +@section Naming a value +@cindex naming values + +When an AutoGen value is specified in a template, it is specified by name. +The name may be a simple name, or a compound name of several components. +Since each named value in AutoGen is implicitly an array of one or more +values, each component may have an index associated with it. + +@noindent +It looks like this: + +@example +comp-name-1 . comp-name-2 [ 2 ] +@end example + +Note that if there are multiple components to a name, each component +name is separated by a dot (@code{.}). Indexes follow a component name, +enclosed in square brackets (@code{[} and @code{]}). The index may be +either an integer or an integer-valued define name. The first component +of the name is searched for in the current definition level. If not +found, higher levels will be searched until either a value is found, +or there are no more definition levels. Subsequent components of the +name must be found within the context of the newly-current definition +level. Also, if the named value is prefixed by a dot (@code{.}), +@cindex . +then the value search is started in the current context only. +Backtracking +@cindex backtrack +into other definition levels is prevented. + +If someone rewrites this, I'll incorporate it. :-) + +@c === SECTION MARKER + +@node expression syntax +@section Macro Expression Syntax +@cindex expression syntax + +AutoGen has two types of expressions: full expressions and basic ones. +A full AutoGen expression can appear by itself, or as the argument +to certain AutoGen built-in macros: CASE, IF, ELIF, INCLUDE, +INVOKE (explicit invocation, @pxref{INVOKE}), and WHILE. +If it appears by itself, the result is inserted into the output. +If it is an argument to one of these macros, the macro code +will act on it sensibly. + +You are constrained to basic expressions only when passing +arguments to user defined macros, @xref{DEFINE}. + +The syntax of a full AutoGen expression is: + +@example +[[ <apply-code> ] <value-name> ] [ <basic-expr-1> [ <basic-expr-2> ]] +@end example + +How the expression is evaluated depends upon the presence or absence +of the apply code and value name. The "value name" is the name of +an AutoGen defined value, or not. If it does not name such a value, +the expression result is generally the empty string. All expressions +must contain either a @var{value-name} or a @var{basic-expr}. + +@menu +* apply code:: Apply Code +* basic expression:: Basic Expression +@end menu + +@node apply code +@subsection Apply Code + +The "apply code" selected determines the method of evaluating the +expression. There are five apply codes, including the non-use +of an apply code. + +@table @samp +@item no apply code +This is the most common expression type. +Expressions of this sort come in three flavors: + +@table @samp +@item <value-name> +The result is the value of @var{value-name}, if defined. +Otherwise it is the empty string. + +@item <basic-expr> +The result of the basic expression is the result of the full expression, +@xref{basic expression}. + +@item <value-name> <basic-expr> +If there is a defined value for @var{value-name}, then the @var{basic-expr} +is evaluated. Otherwise, the result is the empty string. +@end table + +@item % <value-name> <basic-expr> +If @var{value-name} is defined, use @var{basic-expr} as a format +string for sprintf. Then, if the @var{basic-expr} is either a back-quoted +string or a parenthesized expression, then hand the result to the +appropriate interpreter for further evaluation. Otherwise, for single +and double quote strings, the result is the result of the sprintf operation. +Naturally, if @var{value-name} is not defined, the result is the empty +string. + +For example, assume that @samp{fumble} had the string value, @samp{stumble}: +@example +[+ % fumble `printf '%%x\\n' $%s` +] +@end example +This would cause the shell to evaluate "@samp{printf '%x\n' $stumble}". +Assuming that the shell variable @samp{stumble} had a numeric value, +the expression result would be that number, in hex. Note the need +for doubled percent characters and backslashes. + +@item ? <value-name> <basic-expr-1> <basic-expr-2> +Two @var{basic-expr}-s are required. If the @var{value-name} is +defined, then the first @var{basic-expr-1} is evaluated, otherwise +@var{basic-expr-2} is. + +@item - <value-name> <basic-expr> +Evaluate @var{basic-expr} only if @var{value-name} is @i{not} defined. + +@item ?% <value-name> <basic-expr-1> <basic-expr-2> +This combines the functions of @samp{?} and @samp{%}. If @var{value-name} is +defined, it behaves exactly like @samp{%}, above, using @var{basic-expr-1}. +If not defined, then @var{basic-expr-2} is evaluated. + +For example, assume again that @samp{fumble} had the string value, +@samp{stumble}: +@example +[+ ?% fumble `cat $%s` `pwd` +] +@end example +This would cause the shell to evaluate "@samp{cat $stumble}". +If @samp{fumble} were not defined, then the result would be the name +of our current directory. +@end table + +@node basic expression +@subsection Basic Expression + +A basic expression can have one of the following forms: + +@table @samp +@item 'STRING' +A single quoted string. Backslashes can be used to protect single +quotes (@code{'}), hash characters (@code{#}), or backslashes (@code{\}) +in the string. All other characters of STRING are output as-is when the +single quoted string is evaluated. Backslashes are processed before the hash +character for consistency with the definition syntax. It is needed there +to avoid preprocessing conflicts. + +@item "STRING" +A double quoted string. This is a cooked text string as in C, +except that they are not concatenated with adjacent strings. +Evaluating "@samp{STRING}" will output STRING with all +backslash sequences interpreted. + +@item `STRING` +A back quoted string. When this expression is evaluated, STRING +is first interpreted as a cooked string (as in `"STRING"') and +evaluated as a shell expression by the AutoGen server shell. This +expression is replaced by the @file{stdout} output of +the shell. + +@item (STRING) +A parenthesized expression. It will be passed to the Guile +interpreter for evaluation and replaced by the resulting value. +If there is a Scheme error in this expression, Guile 1.4 and Guile 1.6 +will report the template line number where the error occurs. Guile 1.7 +has lost this capability. + +Guile has the capability of creating and manipulating variables that +can be referenced later on in the template processing. If you define +such a variable, it is invisible to AutoGen. To reference its value, +you must use a Guile expression. For example, +@example +[+ (define my-var "some-string-value") +] +@end example +can have that string inserted later, but only as in: +@example +[+ (. my-var) +] +@end example + +Additionally, other than in the @code{%} and @code{?%} expressions, the +Guile expressions may be introduced with the Guile comment character +(@code{;}) and you may put a series of Guile expressions within a single +macro. They will be implicitly evaluated as if they were arguments +to the @code{(begin ...)} expression. The result will be the +result of the last Guile expression evaluated. +@end table + +@ignore +END == TEMPLATE == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore +@ignore + +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +@end ignore +@page +@node AutoGen Functions +@section AutoGen Scheme Functions + +AutoGen uses Guile to interpret Scheme expressions within AutoGen +macros. All of the normal Guile functions are available, plus several +extensions (@pxref{Common Functions}) have been added to +augment the repertoire of string manipulation functions and +manage the state of AutoGen processing. + +This section describes those functions that are specific to AutoGen. +Please take note that these AutoGen specific functions are not loaded +and thus not made available until after the command line options have +been processed and the AutoGen definitions have been loaded. They may, +of course, be used in Scheme functions that get defined at those times, +but they cannot be invoked. + +@menu +* SCM ag-fprintf:: @file{ag-fprintf} - format to autogen stream +* SCM ag-function?:: @file{ag-function?} - test for function +* SCM base-name:: @file{base-name} - base output name +* SCM chdir:: @file{chdir} - Change current directory +* SCM count:: @file{count} - definition count +* SCM def-file:: @file{def-file} - definitions file name +* SCM def-file-line:: @file{def-file-line} - get a definition file+line number +* SCM dne:: @file{dne} - "Do Not Edit" warning +* SCM emit:: @file{emit} - emit the text for each argument +* SCM emit-string-table:: @file{emit-string-table} - output a string table +* SCM error:: @file{error} - display message and exit +* SCM exist?:: @file{exist?} - test for value name +* SCM find-file:: @file{find-file} - locate a file in the search path +* SCM first-for?:: @file{first-for?} - detect first iteration +* SCM for-by:: @file{for-by} - set iteration step +* SCM for-from:: @file{for-from} - set initial index +* SCM for-index:: @file{for-index} - get current loop index +* SCM for-sep:: @file{for-sep} - set loop separation string +* SCM for-to:: @file{for-to} - set ending index +* SCM found-for?:: @file{found-for?} - is current index in list? +* SCM get:: @file{get} - get named value +* SCM get-c-name:: @file{get-c-name} - get named value, mapped to C name syntax +* SCM get-down-name:: @file{get-down-name} - get lower cased named value, mapped to C name syntax +* SCM get-up-name:: @file{get-up-name} - get upper cased named value, mapped to C name syntax +* SCM high-lim:: @file{high-lim} - get highest value index +* SCM insert-file:: @file{insert-file} - insert the contents of a (list of) files. +* SCM insert-suspended:: @file{insert-suspended} - insert a named suspension in current output +* SCM last-for?:: @file{last-for?} - detect last iteration +* SCM len:: @file{len} - get count of values +* SCM low-lim:: @file{low-lim} - get lowest value index +* SCM make-header-guard:: @file{make-header-guard} - make self-inclusion guard +* SCM make-tmp-dir:: @file{make-tmp-dir} - create a temporary directory +* SCM match-value?:: @file{match-value?} - test for matching value +* SCM max-file-time:: @file{max-file-time} - get the maximum input file modification time +* SCM mk-gettextable:: @file{mk-gettextable} - print a string in a gettext-able format +* SCM out-delete:: @file{out-delete} - delete current output file +* SCM out-depth:: @file{out-depth} - output file stack depth +* SCM out-emit-suspended:: @file{out-emit-suspended} - emit the text of suspended output +* SCM out-line:: @file{out-line} - output file line number +* SCM out-move:: @file{out-move} - change name of output file +* SCM out-name:: @file{out-name} - current output file name +* SCM out-pop:: @file{out-pop} - close current output file +* SCM out-push-add:: @file{out-push-add} - append output to file +* SCM out-push-new:: @file{out-push-new} - purge and create output file +* SCM out-resume:: @file{out-resume} - resume suspended output file +* SCM out-suspend:: @file{out-suspend} - suspend current output file +* SCM out-switch:: @file{out-switch} - close and create new output +* SCM output-file-next-line:: @file{output-file-next-line} - print the file name and next line number +* SCM set-option:: @file{set-option} - Set a command line option +* SCM set-writable:: @file{set-writable} - Make the output file be writable +* SCM stack:: @file{stack} - make list of AutoGen values +* SCM stack-join:: @file{stack-join} - stack values then join them +* SCM suffix:: @file{suffix} - get the current suffix +* SCM tpl-file:: @file{tpl-file} - get the template file name +* SCM tpl-file-line:: @file{tpl-file-line} - get the template file+line number +* SCM tpl-file-next-line:: @file{tpl-file-next-line} - get the template file plus next line number +* SCM warn:: @file{warn} - display warning message and continue +* SCM autogen-version:: @file{autogen-version} - ``5.18.16'' +* SCM c-file-line-fmt:: format file info as, ``@code{#line nn "file"}'' +@end menu + + +@node SCM ag-fprintf +@subsection @file{ag-fprintf} - format to autogen stream +@findex ag-fprintf + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expOutput.c line 454. +@end ignore + +Usage: (ag-fprintf ag-diversion format [ format-arg ... ]) +@* +Format a string using arguments from the alist. +Write to a specified AutoGen diversion. +That may be either a specified suspended output stream +(@pxref{SCM out-suspend}) or an index into the output stack +(@pxref{SCM out-push-new}). @code{(ag-fprintf 0 ...)} is +equivalent to @code{(emit (sprintf ...))}, and +@code{(ag-fprintf 1 ...)} sends output to the most recently +suspended output stream. + +Arguments: +@* +ag-diversion - AutoGen diversion name or number +@* +format - formatting string +@* +format-arg - Optional - list of arguments to formatting string + +@node SCM ag-function? +@subsection @file{ag-function?} - test for function +@findex ag-function? + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expState.c line 360. +@end ignore + +Usage: (ag-function? ag-name) +@* +return SCM_BOOL_T if a specified name is a user-defined AutoGen +macro, otherwise return SCM_BOOL_F. + +Arguments: +@* +ag-name - name of AutoGen macro + +@node SCM base-name +@subsection @file{base-name} - base output name +@findex base-name + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expState.c line 197. +@end ignore + +Usage: (base-name) +@* +Returns a string containing the base name of the output file(s). +Generally, this is also the base name of the definitions file. + +This Scheme function takes no arguments. + +@node SCM chdir +@subsection @file{chdir} - Change current directory +@findex chdir + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/agShell.c line 29. +@end ignore + +Usage: (chdir dir) +@* +Sets the current directory for AutoGen. Shell commands will run +from this directory as well. This is a wrapper around the Guile +native function. It returns its directory name argument and +fails the program on failure. + +Arguments: +@* +dir - new directory name + +@node SCM count +@subsection @file{count} - definition count +@findex count + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expState.c line 292. +@end ignore + +Usage: (count ag-name) +@* +Count the number of entries for a definition. +The input argument must be a string containing the name +of the AutoGen values to be counted. If there is no +value associated with the name, the result is an SCM +immediate integer value of zero. + +Arguments: +@* +ag-name - name of AutoGen value + +@node SCM def-file +@subsection @file{def-file} - definitions file name +@findex def-file + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expState.c line 312. +@end ignore + +Usage: (def-file) +@* +Get the name of the definitions file. +Returns the name of the source file containing the AutoGen +definitions. + +This Scheme function takes no arguments. + +@node SCM def-file-line +@subsection @file{def-file-line} - get a definition file+line number +@findex def-file-line + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expState.c line 749. +@end ignore + +Usage: (def-file-line ag-name [ msg-fmt ]) +@* +Returns the file and line number of a AutoGen defined value, using +either the default format, "from %s line %d", or else the format you +supply. For example, if you want to insert a "C" language file-line +directive, you would supply the format "# %2$d \"%1$s\"", but that +is also already supplied with the scheme variable +@xref{SCM c-file-line-fmt}. You may use it thus: + +@example +(def-file-line "ag-def-name" c-file-line-fmt) +@end example + +It is also safe to use the formatting string, "%2$d". AutoGen uses +an argument vector version of printf: @xref{snprintfv}. + +Arguments: +@* +ag-name - name of AutoGen value +@* +msg-fmt - Optional - formatting for line message + +@node SCM dne +@subsection @file{dne} - "Do Not Edit" warning +@findex dne + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expFormat.c line 86. +@end ignore + +Usage: (dne prefix [ first_prefix ] [ optpfx ]) +@* +Generate a "DO NOT EDIT" or "EDIT WITH CARE" warning string. +Which depends on whether or not the @code{--writable} command line +option was set. + +The first argument may be an option: @samp{-D} or @samp{-d}, causing the +second and (potentially) third arguments to be interpreted as the first +and second arguments. The only useful option is @samp{-D}: + +@table @samp +@item -D +will add date, timestamp and version information. +@item -d +is ignored, but still accepted for compatibility with older versions +of the "dne" function where emitting the date was the default. +@end table + +If one of these options is specified, then the "prefix" and "first" +arguments are obtained from the following arguments. The presence (or +absence) of this option can be overridden with the environment variable, +@samp{AUTOGEN_DNE_DATE}. The date is disabled if the value is empty or +starts with one of the characters, @samp{0nNfF} -- zero or the first +letter of "no" or "false". + +The @code{prefix} argument is a per-line string prefix. The optional +second argument is a prefix for the first line only and, in read-only +mode, activates editor hints. + +@example +-*- buffer-read-only: t -*- vi: set ro: +@end example + +@noindent +The warning string also includes information about the template used +to construct the file and the definitions used in its instantiation. + +Arguments: +@* +prefix - string for starting each output line +@* +first_prefix - Optional - for the first output line +@* +optpfx - Optional - shifted prefix + +@node SCM emit +@subsection @file{emit} - emit the text for each argument +@findex emit + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcEval.c line 337. +@end ignore + +Usage: (emit alist ...) +@* +Walk the tree of arguments, displaying the values of displayable +SCM types. EXCEPTION: if the first argument is a number, then +that number is used to index the output stack. "0" is the default, +the current output. + +Arguments: +@* +alist - list of arguments to stringify and emit + +@node SCM emit-string-table +@subsection @file{emit-string-table} - output a string table +@findex emit-string-table + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/schemedef.scm line 294. +@end ignore + +Usage: (emit-string-table st-name) +@* +Emit into the current output stream a +@code{static char const} array named @code{st-name} +that will have @code{NUL} bytes between each inserted string. + +Arguments: +@* +st-name - the name of the array of characters + +@node SCM error +@subsection @file{error} - display message and exit +@findex error + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expFormat.c line 279. +@end ignore + +Usage: (error message) +@* +The argument is a string that printed out as part of an error +message. The message is formed from the formatting string: + +@example +DEFINITIONS ERROR in %s line %d for %s: %s\n +@end example + +The first three arguments to this format are provided by the +routine and are: The name of the template file, the line within +the template where the error was found, and the current output +file name. + +After displaying the message, the current output file is removed +and autogen exits with the EXIT_FAILURE error code. IF, however, +the argument begins with the number 0 (zero), or the string is the +empty string, then processing continues with the next suffix. + +Arguments: +@* +message - message to display before exiting + +@node SCM exist? +@subsection @file{exist?} - test for value name +@findex exist? + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expState.c line 326. +@end ignore + +Usage: (exist? ag-name) +@* +return SCM_BOOL_T iff a specified name has an AutoGen value. +The name may include indexes and/or member names. +All but the last member name must be an aggregate definition. +For example: +@example +(exist? "foo[3].bar.baz") +@end example +will yield true if all of the following is true: +@* +There is a member value of either group or string type +named @code{baz} for some group value @code{bar} that +is a member of the @code{foo} group with index @code{3}. +There may be multiple entries of @code{bar} within +@code{foo}, only one needs to contain a value for @code{baz}. + +Arguments: +@* +ag-name - name of AutoGen value + +@node SCM find-file +@subsection @file{find-file} - locate a file in the search path +@findex find-file + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expExtract.c line 318. +@end ignore + +Usage: (find-file file-name [ suffix ]) +@* +AutoGen has a search path that it uses to locate template and definition +files. This function will search the same list for @file{file-name}, both +with and without the @file{.suffix}, if provided. + +Arguments: +@* +file-name - name of file with text +@* +suffix - Optional - file suffix to try, too + +@node SCM first-for? +@subsection @file{first-for?} - detect first iteration +@findex first-for? + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcFor.c line 64. +@end ignore + +Usage: (first-for? [ for_var ]) +@* +Returns @code{SCM_BOOL_T} if the named FOR loop (or, if not named, the +current innermost loop) is on the first pass through the data. Outside +of any @code{FOR} loop, it returns @code{SCM_UNDEFINED}, @pxref{FOR}. + +Arguments: +@* +for_var - Optional - which for loop + +@node SCM for-by +@subsection @file{for-by} - set iteration step +@findex for-by + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcFor.c line 191. +@end ignore + +Usage: (for-by by) +@* +This function records the "step by" information +for an AutoGen FOR function. +Outside of the FOR macro itself, this function will emit an error. +@xref{FOR}. + +Arguments: +@* +by - the iteration increment for the AutoGen FOR macro + +@node SCM for-from +@subsection @file{for-from} - set initial index +@findex for-from + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcFor.c line 149. +@end ignore + +Usage: (for-from from) +@* +This function records the initial index information +for an AutoGen FOR function. +Outside of the FOR macro itself, this function will emit an error. +@xref{FOR}. + +Arguments: +@* +from - the initial index for the AutoGen FOR macro + +@node SCM for-index +@subsection @file{for-index} - get current loop index +@findex for-index + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcFor.c line 128. +@end ignore + +Usage: (for-index [ for_var ]) +@* +Returns the current index for the named @code{FOR} loop. +If not named, then the index for the innermost loop. +Outside of any FOR loop, it returns @code{SCM_UNDEFINED}, @xref{FOR}. + +Arguments: +@* +for_var - Optional - which for loop + +@node SCM for-sep +@subsection @file{for-sep} - set loop separation string +@findex for-sep + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcFor.c line 211. +@end ignore + +Usage: (for-sep separator) +@* +This function records the separation string that is to be inserted +between each iteration of an AutoGen FOR function. This is often +nothing more than a comma. +Outside of the FOR macro itself, this function will emit an error. + +Arguments: +@* +separator - the text to insert between the output of +each FOR iteration + +@node SCM for-to +@subsection @file{for-to} - set ending index +@findex for-to + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcFor.c line 170. +@end ignore + +Usage: (for-to to) +@* +This function records the terminating value information +for an AutoGen FOR function. +Outside of the FOR macro itself, this function will emit an error. +@xref{FOR}. + +Arguments: +@* +to - the final index for the AutoGen FOR macro + +@node SCM found-for? +@subsection @file{found-for?} - is current index in list? +@findex found-for? + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcFor.c line 108. +@end ignore + +Usage: (found-for? [ for_var ]) +@* +Returns SCM_BOOL_T if the currently indexed value is present, +otherwise SCM_BOOL_F. Outside of any FOR loop, it returns +SCM_UNDEFINED. @xref{FOR}. + +Arguments: +@* +for_var - Optional - which for loop + +@node SCM get +@subsection @file{get} - get named value +@findex get + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expState.c line 413. +@end ignore + +Usage: (get ag-name [ alt-val ]) +@* +Get the first string value associated with the name. +It will either return the associated string value (if +the name resolves), the alternate value (if one is provided), +or else the empty string. + +Arguments: +@* +ag-name - name of AutoGen value +@* +alt-val - Optional - value if not present + +@node SCM get-c-name +@subsection @file{get-c-name} - get named value, mapped to C name syntax +@findex get-c-name + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expState.c line 450. +@end ignore + +Usage: (get-c-name ag-name) +@* +Get the first string value associated with the name. It will either +return the associated string value (if the name resolves), the alternate +value (if one is provided), or else the empty string. The result is +passed through "string->c-name!". + +Arguments: +@* +ag-name - name of AutoGen value + +@node SCM get-down-name +@subsection @file{get-down-name} - get lower cased named value, mapped to C name syntax +@findex get-down-name + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expState.c line 488. +@end ignore + +Usage: (get-down-name ag-name) +@* +Get the first string value associated with the name. It will either +return the associated string value (if the name resolves), the alternate +value (if one is provided), or else the empty string. The result is +passed through "string->c-name!" and "string->down-case!". + +Arguments: +@* +ag-name - name of AutoGen value + +@node SCM get-up-name +@subsection @file{get-up-name} - get upper cased named value, mapped to C name syntax +@findex get-up-name + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expState.c line 469. +@end ignore + +Usage: (get-up-name ag-name) +@* +Get the first string value associated with the name. It will either +return the associated string value (if the name resolves), the alternate +value (if one is provided), or else the empty string. The result is +passed through "string->c-name!" and "string->up-case!". + +Arguments: +@* +ag-name - name of AutoGen value + +@node SCM high-lim +@subsection @file{high-lim} - get highest value index +@findex high-lim + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expState.c line 507. +@end ignore + +Usage: (high-lim ag-name) +@* +Returns the highest index associated with an array of definitions. +This is generally, but not necessarily, one less than the +@code{count} value. (The indexes may be specified, rendering a +non-zero based or sparse array of values.) + +This is very useful for specifying the size of a zero-based array +of values where not all values are present. For example: + +@example +tMyStruct myVals[ [+ (+ 1 (high-lim "my-val-list")) +] ]; +@end example + +Arguments: +@* +ag-name - name of AutoGen value + +@node SCM insert-file +@subsection @file{insert-file} - insert the contents of a (list of) files. +@findex insert-file + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcEval.c line 439. +@end ignore + +Usage: (insert-file alist ...) +@* +Insert the contents of one or more files. + +Arguments: +@* +alist - list of files to emit + +@node SCM insert-suspended +@subsection @file{insert-suspended} - insert a named suspension in current output +@findex insert-suspended + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/schemedef.scm line 133. +@end ignore + +Usage: (insert-suspended susp-name) +@* +Emit into the current output the output suspended under a +given diversion name. + +Arguments: +@* +susp-name - the name of the suspended output + +@node SCM last-for? +@subsection @file{last-for?} - detect last iteration +@findex last-for? + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcFor.c line 88. +@end ignore + +Usage: (last-for? [ for_var ]) +@* +Returns SCM_BOOL_T if the named FOR loop (or, if not named, the +current innermost loop) is on the last pass through the data. +Outside of any FOR loop, it returns SCM_UNDEFINED. +@xref{FOR}. + +Arguments: +@* +for_var - Optional - which for loop + +@node SCM len +@subsection @file{len} - get count of values +@findex len + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expState.c line 552. +@end ignore + +Usage: (len ag-name) +@* +If the named object is a group definition, then "len" is +the same as "count". Otherwise, if it is one or more text +definitions, then it is the sum of their string lengths. +If it is a single text definition, then it is equivalent to +@code{(string-length (get "ag-name"))}. + +Arguments: +@* +ag-name - name of AutoGen value + +@node SCM low-lim +@subsection @file{low-lim} - get lowest value index +@findex low-lim + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expState.c line 572. +@end ignore + +Usage: (low-lim ag-name) +@* +Returns the lowest index associated with an array of definitions. + +Arguments: +@* +ag-name - name of AutoGen value + +@node SCM make-header-guard +@subsection @file{make-header-guard} - make self-inclusion guard +@findex make-header-guard + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expOutput.c line 801. +@end ignore + +Usage: (make-header-guard name) +@* +This function will create a @code{#ifndef}/@code{#define} +sequence for protecting a header from multiple evaluation. +It will also set the Scheme variable @code{header-file} +to the name of the file being protected and it will set +@code{header-guard} to the name of the @code{#define} being +used to protect it. It is expected that this will be used +as follows: +@example +[+ (make-header-guard "group_name") +] +... +#endif /* [+ (. header-guard) +] */ + +#include "[+ (. header-file) +]" +@end example +@noindent +The @code{#define} name is composed as follows: + +@enumerate +@item +The first element is the string argument and a separating underscore. +@item +That is followed by the name of the header file with illegal +characters mapped to underscores. +@item +The end of the name is always, "@code{_GUARD}". +@item +Finally, the entire string is mapped to upper case. +@end enumerate + +The final @code{#define} name is stored in an SCM symbol named +@code{header-guard}. Consequently, the concluding @code{#endif} for the +file should read something like: + +@example +#endif /* [+ (. header-guard) +] */ +@end example + +The name of the header file (the current output file) is also stored +in an SCM symbol, @code{header-file}. Therefore, if you are also +generating a C file that uses the previously generated header file, +you can put this into that generated file: + +@example +#include "[+ (. header-file) +]" +@end example + +Obviously, if you are going to produce more than one header file from +a particular template, you will need to be careful how these SCM symbols +get handled. + +Arguments: +@* +name - header group name + +@node SCM make-tmp-dir +@subsection @file{make-tmp-dir} - create a temporary directory +@findex make-tmp-dir + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expOutput.c line 561. +@end ignore + +Usage: (make-tmp-dir) +@* +Create a directory that will be cleaned up upon exit. + +This Scheme function takes no arguments. + +@node SCM match-value? +@subsection @file{match-value?} - test for matching value +@findex match-value? + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expState.c line 381. +@end ignore + +Usage: (match-value? op ag-name test-str) +@* +This function answers the question, "Is there an AutoGen value named +@code{ag-name} with a value that matches the pattern @code{test-str} +using the match function @code{op}?" Return SCM_BOOL_T iff at least +one occurrence of the specified name has such a value. The operator +can be any function that takes two string arguments and yields a +boolean. It is expected that you will use one of the string matching +functions provided by AutoGen. +@* +The value name must follow the same rules as the +@code{ag-name} argument for @code{exist?} (@pxref{SCM exist?}). + +Arguments: +@* +op - boolean result operator +@* +ag-name - name of AutoGen value +@* +test-str - string to test against + +@node SCM max-file-time +@subsection @file{max-file-time} - get the maximum input file modification time +@findex max-file-time + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expState.c line 730. +@end ignore + +Usage: (max-file-time) +@* +returns the time stamp of the most recently modified sourc file as the +number of seconds since the epoch. If any input is dynamic +(a shell command), then it will be the current time. + +This Scheme function takes no arguments. + +@node SCM mk-gettextable +@subsection @file{mk-gettextable} - print a string in a gettext-able format +@findex mk-gettextable + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expString.c line 249. +@end ignore + +Usage: (mk-gettextable string) +@* +Returns SCM_UNDEFINED. The input text string is printed +to the current output as one puts() call per paragraph. + +Arguments: +@* +string - a multi-paragraph string + +@node SCM out-delete +@subsection @file{out-delete} - delete current output file +@findex out-delete + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expOutput.c line 201. +@end ignore + +Usage: (out-delete) +@* +Remove the current output file. Cease processing the template for +the current suffix. It is an error if there are @code{push}-ed +output files. Use the @code{(error "0")} scheme function instead. +@xref{output controls}. + +This Scheme function takes no arguments. + +@node SCM out-depth +@subsection @file{out-depth} - output file stack depth +@findex out-depth + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expOutput.c line 736. +@end ignore + +Usage: (out-depth) +@* +Returns the depth of the output file stack. +@xref{output controls}. + +This Scheme function takes no arguments. + +@node SCM out-emit-suspended +@subsection @file{out-emit-suspended} - emit the text of suspended output +@findex out-emit-suspended + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expOutput.c line 438. +@end ignore + +Usage: (out-emit-suspended susp_nm) +@* +This function is equivalent to +@code{(begin (out-resume <name>) (out-pop #t))} + +Arguments: +@* +susp_nm - A name tag of suspended output + +@node SCM out-line +@subsection @file{out-line} - output file line number +@findex out-line + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expOutput.c line 766. +@end ignore + +Usage: (out-line) +@* +Returns the current line number of the output file. +It rewinds and reads the file to count newlines. + +This Scheme function takes no arguments. + +@node SCM out-move +@subsection @file{out-move} - change name of output file +@findex out-move + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expOutput.c line 226. +@end ignore + +Usage: (out-move new-name) +@* +Rename current output file. @xref{output controls}. +Please note: changing the name will not save a temporary file from +being deleted. It @i{may}, however, be used on the root output file. + +Arguments: +@* +new-name - new name for the current output file + +@node SCM out-name +@subsection @file{out-name} - current output file name +@findex out-name + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expOutput.c line 749. +@end ignore + +Usage: (out-name) +@* +Returns the name of the current output file. If the current file +is a temporary, unnamed file, then it will scan up the chain until +a real output file name is found. +@xref{output controls}. + +This Scheme function takes no arguments. + +@node SCM out-pop +@subsection @file{out-pop} - close current output file +@findex out-pop + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expOutput.c line 273. +@end ignore + +Usage: (out-pop [ disp ]) +@* +If there has been a @code{push} on the output, then close that +file and go back to the previously open file. It is an error +if there has not been a @code{push}. @xref{output controls}. + +If there is no argument, no further action is taken. Otherwise, +the argument should be @code{#t} and the contents of the file +are returned by the function. + +Arguments: +@* +disp - Optional - return contents of the file + +@node SCM out-push-add +@subsection @file{out-push-add} - append output to file +@findex out-push-add + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expOutput.c line 537. +@end ignore + +Usage: (out-push-add file-name) +@* +Identical to @code{push-new}, except the contents are @strong{not} +purged, but appended to. @xref{output controls}. + +Arguments: +@* +file-name - name of the file to append text to + +@node SCM out-push-new +@subsection @file{out-push-new} - purge and create output file +@findex out-push-new + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expOutput.c line 592. +@end ignore + +Usage: (out-push-new [ file-name ]) +@* +Leave the current output file open, but purge and create +a new file that will remain open until a @code{pop} @code{delete} +or @code{switch} closes it. The file name is optional and, if omitted, +the output will be sent to a temporary file that will be deleted when +it is closed. +@xref{output controls}. + +Arguments: +@* +file-name - Optional - name of the file to create + +@node SCM out-resume +@subsection @file{out-resume} - resume suspended output file +@findex out-resume + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expOutput.c line 402. +@end ignore + +Usage: (out-resume susp_nm) +@* +If there has been a suspended output, then make that output descriptor +current again. That output must have been suspended with the same tag +name given to this routine as its argument. + +Arguments: +@* +susp_nm - A name tag for reactivating + +@node SCM out-suspend +@subsection @file{out-suspend} - suspend current output file +@findex out-suspend + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expOutput.c line 359. +@end ignore + +Usage: (out-suspend suspName) +@* +If there has been a @code{push} on the output, then set aside the output +descriptor for later reactiviation with @code{(out-resume "xxx")}. The +tag name need not reflect the name of the output file. In fact, the +output file may be an anonymous temporary file. You may also change the +tag every time you suspend output to a file, because the tag names are +forgotten as soon as the file has been "resumed". + +Arguments: +@* +suspName - A name tag for reactivating + +@node SCM out-switch +@subsection @file{out-switch} - close and create new output +@findex out-switch + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expOutput.c line 676. +@end ignore + +Usage: (out-switch file-name) +@* +Switch output files - close current file and make the current +file pointer refer to the new file. This is equivalent to +@code{out-pop} followed by @code{out-push-new}, except that +you may not pop the base level output file, but you may +@code{switch} it. @xref{output controls}. + +Arguments: +@* +file-name - name of the file to create + +@node SCM output-file-next-line +@subsection @file{output-file-next-line} - print the file name and next line number +@findex output-file-next-line + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expOutput.c line 321. +@end ignore + +Usage: (output-file-next-line [ line_off ] [ alt_fmt ]) +@* +Returns a string with the current output file name and line number. +The default format is: # <line+1> "<output-file-name>" The argument may be +either a number indicating an offset from the current output line number +or an alternate formatting string. If both are provided, then the first +must be a numeric offset. + +Be careful that you are directing output to the final output file. +Otherwise, you will get the file name and line number of the temporary +file. That won't be what you want. + +Arguments: +@* +line_off - Optional - offset to line number +@* +alt_fmt - Optional - alternate format string + +@node SCM set-option +@subsection @file{set-option} - Set a command line option +@findex set-option + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expState.c line 599. +@end ignore + +Usage: (set-option opt) +@* +The text argument must be an option name followed by any needed +option argument. Returns SCM_UNDEFINED. + +Arguments: +@* +opt - AutoGen option name + its argument + +@node SCM set-writable +@subsection @file{set-writable} - Make the output file be writable +@findex set-writable + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcIf.c line 469. +@end ignore + +Usage: (set-writable [ set? ]) +@* +This function will set the current output file to be writable +(or not). This is only effective if neither the @code{--writable} +nor @code{--not-writable} have been specified. This state +is reset when the current suffix's output is complete. + +Arguments: +@* +set? - Optional - boolean arg, false to make output non-writable + +@node SCM stack +@subsection @file{stack} - make list of AutoGen values +@findex stack + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expString.c line 707. +@end ignore + +Usage: (stack ag-name) +@* +Create a scheme list of all the strings that are associated +with a name. They must all be text values or we choke. + +Arguments: +@* +ag-name - AutoGen value name + +@node SCM stack-join +@subsection @file{stack-join} - stack values then join them +@findex stack-join + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/schemedef.scm line 387. +@end ignore + +Usage: (stack-join join ag-name) +@* +This function will collect all the values named @code{ag-name} +(see the @pxref{SCM stack, stack function}) and join them +separated by the @code{join} string (see the +@pxref{SCM join, join function}). + +Arguments: +@* +join - string between each element +@* +ag-name - name of autogen values to stack + +@node SCM suffix +@subsection @file{suffix} - get the current suffix +@findex suffix + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expState.c line 615. +@end ignore + +Usage: (suffix) +@* +Returns the current active suffix (@pxref{pseudo macro}). + +This Scheme function takes no arguments. + +@node SCM tpl-file +@subsection @file{tpl-file} - get the template file name +@findex tpl-file + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expState.c line 628. +@end ignore + +Usage: (tpl-file [ full_path ]) +@* +Returns the name of the current template file. +If @code{#t} is passed in as an argument, then the template +file is hunted for in the template search path. Otherwise, +just the unadorned name. + +Arguments: +@* +full_path - Optional - include full path to file + +@node SCM tpl-file-line +@subsection @file{tpl-file-line} - get the template file+line number +@findex tpl-file-line + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expState.c line 677. +@end ignore + +Usage: (tpl-file-line [ msg-fmt ]) +@* +Returns the file and line number of the current template macro using +either the default format, "from %s line %d", or else the format you +supply. For example, if you want to insert a "C" language file-line +directive, you would supply the format "# %2$d \"%1$s\"", but that +is also already supplied with the scheme variable +@xref{SCM c-file-line-fmt}. You may use it thus: +@example +(tpl-file-line c-file-line-fmt) +@end example + +It is also safe to use the formatting string, "%2$d". AutoGen uses +an argument vector version of printf: @xref{snprintfv}, +and it does not need to know the types of each argument in order to +skip forward to the second argument. + +Arguments: +@* +msg-fmt - Optional - formatting for line message + +@node SCM tpl-file-next-line +@subsection @file{tpl-file-next-line} - get the template file plus next line number +@findex tpl-file-next-line + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expState.c line 709. +@end ignore + +Usage: (tpl-file-next-line [ msg-fmt ]) +@* +This is almost the same as @xref{SCM tpl-file-line}, except that +the line referenced is the next line, per C compiler conventions, and +consequently defaults to the format: # <line-no+1> "<file-name>" + +Arguments: +@* +msg-fmt - Optional - formatting for line message + +@node SCM warn +@subsection @file{warn} - display warning message and continue +@findex warn + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expFormat.c line 252. +@end ignore + +Usage: (warn message) +@* +The argument is a string that printed out to stderr. +The message is formed from the formatting string: + +@example +@code{WARNING:} %s\n +@end example + +The template processing resumes after printing the message. + +Arguments: +@* +message - message to display + +@ignore +Generated from auto_gen.tpl line 291. +@end ignore + +@node SCM autogen-version +@subsection @file{autogen-version} - autogen version number +@findex autogen-version + +This is a symbol defining the current AutoGen version number string. +It was first defined in AutoGen-5.2.14. +It is currently ``5.18.16''. + +@node SCM c-file-line-fmt +@subsection format file info as, ``@code{#line nn "file"}'' +@findex c-file-line-fmt + +This is a symbol that can easily be used with the functions +@xref{SCM tpl-file-line}, and @xref{SCM def-file-line}. +These will emit C program @code{#line} directives pointing to template +and definitions text, respectively. +@ignore + +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +@end ignore +@page +@node Common Functions +@section Common Scheme Functions + +This section describes a number of general purpose functions that make +the kind of string processing that AutoGen does a little easier. +Unlike the AutoGen specific functions (@pxref{AutoGen Functions}), +these functions are available for direct use during definition load time. +The equality test (@pxref{SCM =}) is ``overloaded'' to do string equivalence +comparisons. If you are looking for inequality, the Scheme/Lisp way +of spelling that is, ``(not (= ...))''. + +@menu +* SCM agpl:: @file{agpl} - GNU Affero General Public License +* SCM bsd:: @file{bsd} - BSD Public License +* SCM c-string:: @file{c-string} - emit string for ANSI C +* SCM error-source-line:: @file{error-source-line} - display of file & line +* SCM extract:: @file{extract} - extract text from another file +* SCM format-arg-count:: @file{format-arg-count} - count the args to a format +* SCM fprintf:: @file{fprintf} - format to a file +* SCM gperf:: @file{gperf} - perform a perfect hash function +* SCM gperf-code:: @file{gperf-code} - emit the source of the generated gperf program +* SCM gpl:: @file{gpl} - GNU General Public License +* SCM hide-email:: @file{hide-email} - convert eaddr to javascript +* SCM html-escape-encode:: @file{html-escape-encode} - encode html special characters +* SCM in?:: @file{in?} - test for string in list +* SCM join:: @file{join} - join string list with separator +* SCM kr-string:: @file{kr-string} - emit string for K&R C +* SCM lgpl:: @file{lgpl} - GNU Library General Public License +* SCM license:: @file{license} - an arbitrary license +* SCM license-description:: @file{license-description} - Emit a license description +* SCM license-full:: @file{license-full} - Emit the licensing information and description +* SCM license-info:: @file{license-info} - Emit the licensing information and copyright years +* SCM license-name:: @file{license-name} - Emit the name of the license +* SCM make-gperf:: @file{make-gperf} - build a perfect hash function program +* SCM makefile-script:: @file{makefile-script} - create makefile script +* SCM max:: @file{max} - maximum value in list +* SCM min:: @file{min} - minimum value in list +* SCM prefix:: @file{prefix} - prefix lines with a string +* SCM printf:: @file{printf} - format to stdout +* SCM raw-shell-str:: @file{raw-shell-str} - single quote shell string +* SCM shell:: @file{shell} - invoke a shell script +* SCM shell-str:: @file{shell-str} - double quote shell string +* SCM shellf:: @file{shellf} - format a string, run shell +* SCM sprintf:: @file{sprintf} - format a string +* SCM string-capitalize:: @file{string-capitalize} - capitalize a new string +* SCM string-capitalize!:: @file{string-capitalize!} - capitalize a string +* SCM *=*:: @file{string-contains-eqv?} - caseless substring +* SCM *==*:: @file{string-contains?} - substring match +* SCM string-downcase:: @file{string-downcase} - lower case a new string +* SCM string-downcase!:: @file{string-downcase!} - make a string be lower case +* SCM *~:: @file{string-end-eqv-match?} - caseless regex ending +* SCM *~~:: @file{string-end-match?} - regex match end +* SCM *=:: @file{string-ends-eqv?} - caseless string ending +* SCM *==:: @file{string-ends-with?} - string ending +* SCM ==:: @file{string-equals?} - string matching +* SCM ~:: @file{string-eqv-match?} - caseless regex match +* SCM =:: @file{string-eqv?} - caseless match +* SCM *~*:: @file{string-has-eqv-match?} - caseless regex contains +* SCM *~~*:: @file{string-has-match?} - contained regex match +* SCM ~~:: @file{string-match?} - regex match +* SCM ~*:: @file{string-start-eqv-match?} - caseless regex start +* SCM ~~*:: @file{string-start-match?} - regex match start +* SCM =*:: @file{string-starts-eqv?} - caseless string start +* SCM ==*:: @file{string-starts-with?} - string starting +* SCM string-substitute:: @file{string-substitute} - multiple global replacements +* SCM string-table-add:: @file{string-table-add} - Add an entry to a string table +* SCM string-table-add-ref:: @file{string-table-add-ref} - Add an entry to a string table, get reference +* SCM string-table-new:: @file{string-table-new} - create a string table +* SCM string-table-size:: @file{string-table-size} - print the current size of a string table +* SCM string->c-name!:: @file{string->c-name!} - map non-name chars to underscore +* SCM string->camelcase:: @file{string->camelcase} - make a string be CamelCase +* SCM string-tr:: @file{string-tr} - convert characters with new result +* SCM string-tr!:: @file{string-tr!} - convert characters +* SCM string-upcase:: @file{string-upcase} - upper case a new string +* SCM string-upcase!:: @file{string-upcase!} - make a string be upper case +* SCM sub-shell-str:: @file{sub-shell-str} - back quoted (sub-)shell string +* SCM sum:: @file{sum} - sum of values in list +* SCM time-string->number:: @file{time-string->number} - duration string to seconds +* SCM version-compare:: @file{version-compare} - compare two version numbers +@end menu + + +@node SCM agpl +@subsection @file{agpl} - GNU Affero General Public License +@findex agpl + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expFormat.c line 775. +@end ignore + +Usage: (agpl prog-name prefix) +@* +Emit a string that contains the GNU Affero General Public License. +This function is now deprecated. Please @xref{SCM license-description}. + +Arguments: +@* +prog-name - name of the program under the GPL +@* +prefix - String for starting each output line + +@node SCM bsd +@subsection @file{bsd} - BSD Public License +@findex bsd + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expFormat.c line 824. +@end ignore + +Usage: (bsd prog_name owner prefix) +@* +Emit a string that contains the Free BSD Public License. +This function is now deprecated. Please @xref{SCM license-description}. + +Arguments: +@* +prog_name - name of the program under the BSD +@* +owner - Grantor of the BSD License +@* +prefix - String for starting each output line + +@node SCM c-string +@subsection @file{c-string} - emit string for ANSI C +@findex c-string + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expString.c line 775. +@end ignore + +Usage: (c-string string) +@* +Reform a string so that, when printed, the C compiler will be able to +compile the data and construct a string that contains exactly what the +current string contains. Many non-printing characters are replaced with +escape sequences. Newlines are replaced with a backslash, an @code{n}, a +closing quote, a newline, seven spaces and another re-opening quote. The +compiler will implicitly concatenate them. The reader will see line +breaks. + +A K&R compiler will choke. Use @code{kr-string} for that compiler. + +Arguments: +@* +string - string to reformat + +@node SCM error-source-line +@subsection @file{error-source-line} - display of file & line +@findex error-source-line + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcEval.c line 318. +@end ignore + +Usage: (error-source-line) +@* +This function is only invoked just before Guile displays +an error message. It displays the file name and line number +that triggered the evaluation error. You should not need to +invoke this routine directly. Guile will do it automatically. + +This Scheme function takes no arguments. + +@node SCM extract +@subsection @file{extract} - extract text from another file +@findex extract + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expExtract.c line 191. +@end ignore + +Usage: (extract file-name marker-fmt [ caveat ] [ default ]) +@* +This function is used to help construct output files that may contain +text that is carried from one version of the output to the next. + +The first two arguments are required, the second are optional: + +@itemize @bullet +@item +The @code{file-name} argument is used to name the file that +contains the demarcated text. +@item +The @code{marker-fmt} is a formatting string that is used to construct +the starting and ending demarcation strings. The sprintf function is +given the @code{marker-fmt} with two arguments. The first is either +"START" or "END". The second is either "DO NOT CHANGE THIS COMMENT" +or the optional @code{caveat} argument. +@item +@code{caveat} is presumed to be absent if it is the empty string +(@code{""}). If absent, ``DO NOT CHANGE THIS COMMENT'' is used +as the second string argument to the @code{marker-fmt}. +@item +When a @code{default} argument is supplied and no pre-existing text +is found, then this text will be inserted between the START and END +markers. +@end itemize + +@noindent +The resulting strings are presumed to be unique within +the subject file. As a simplified example: + +@example +[+ (extract "fname" "// %s - SOMETHING - %s" "" +"example default") +] +@end example +@noindent +will result in the following text being inserted into the output: + +@example +// START - SOMETHING - DO NOT CHANGE THIS COMMENT +example default +// END - SOMETHING - DO NOT CHANGE THIS COMMENT +@end example + +@noindent +The ``@code{example default}'' string can then be carried forward to +the next generation of the output, @strong{@i{provided}} the output +is not named "@code{fname}" @i{and} the old output is renamed to +"@code{fname}" before AutoGen-eration begins. + +@table @strong +@item NB: +You can set aside previously generated source files inside the pseudo +macro with a Guile/scheme function, extract the text you want to keep +with this extract function. Just remember you should delete it at the +end, too. Here is an example from my Finite State Machine generator: + +@example +[+ AutoGen5 Template -*- Mode: text -*- +h=%s-fsm.h c=%s-fsm.c +(shellf +"test -f %1$s-fsm.h && mv -f %1$s-fsm.h .fsm.head +test -f %1$s-fsm.c && mv -f %1$s-fsm.c .fsm.code" (base-name)) ++] +@end example + +This code will move the two previously produced output files to files +named ".fsm.head" and ".fsm.code". At the end of the 'c' output +processing, I delete them. + +@item also NB: +This function presumes that the output file ought to be editable so +that the code between the @code{START} and @code{END} marks can be edited +by the template user. Consequently, when the @code{(extract ...)} function +is invoked, if the @code{writable} option has not been specified, then +it will be set at that point. If this is not the desired behavior, the +@code{--not-writable} command line option will override this. +Also, you may use the guile function @code{(chmod "file" mode-value)} +to override whatever AutoGen is using for the result mode. +@end table + +Arguments: +@* +file-name - name of file with text +@* +marker-fmt - format for marker text +@* +caveat - Optional - warn about changing marker +@* +default - Optional - default initial text + +@node SCM format-arg-count +@subsection @file{format-arg-count} - count the args to a format +@findex format-arg-count + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expPrint.c line 290. +@end ignore + +Usage: (format-arg-count format) +@* +Sometimes, it is useful to simply be able to figure out how many +arguments are required by a format string. For example, if you +are extracting a format string for the purpose of generating a +macro to invoke a printf-like function, you can run the +formatting string through this function to determine how many +arguments to provide for in the macro. e.g. for this extraction +text: +@example + + /*=fumble bumble + * fmt: 'stumble %s: %d\n' + =*/ +@end example + +@noindent +You may wish to generate a macro: +@example + + #define BUMBLE(a1,a2) printf_like(something,(a1),(a2)) +@end example + +@noindent +You can do this by knowing that the format needs two arguments. + +Arguments: +@* +format - formatting string + +@node SCM fprintf +@subsection @file{fprintf} - format to a file +@findex fprintf + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expPrint.c line 223. +@end ignore + +Usage: (fprintf port format [ format-arg ... ]) +@* +Format a string using arguments from the alist. +Write to a specified port. The result will NOT appear in your +output. Use this to print information messages to a template user. + +Arguments: +@* +port - Guile-scheme output port +@* +format - formatting string +@* +format-arg - Optional - list of arguments to formatting string + +@node SCM gperf +@subsection @file{gperf} - perform a perfect hash function +@findex gperf + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expGperf.c line 111. +@end ignore + +Usage: (gperf name str) +@* +Perform the perfect hash on the input string. This is only useful if +you have previously created a gperf program with the @code{make-gperf} +function @xref{SCM make-gperf}. The @code{name} you supply here must +match the name used to create the program and the string to hash must +be one of the strings supplied in the @code{make-gperf} string list. +The result will be a perfect hash index. + +See the documentation for @command{gperf(1GNU)} for more details. + +Arguments: +@* +name - name of hash list +@* +str - string to hash + +@node SCM gperf-code +@subsection @file{gperf-code} - emit the source of the generated gperf program +@findex gperf-code + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/schemedef.scm line 339. +@end ignore + +Usage: (gperf-code st-name) +@* +Returns the contents of the emitted code, suitable +for inclusion in another program. The interface contains +the following elements: + +@table @samp +@item struct @i{<st-name>}_index +containg the fields: @code{@{char const * name, int const id; @};} + +@item @i{<st-name>}_hash() +This is the hashing function with local only scope (static). + +@item @i{<st-name>}_find() +This is the searching and validation function. The first argument +is the string to look up, the second is its length. +It returns a pointer to the corresponding @code{@i{<st-name>}_index} +entry. +@end table + +Use this in your template as follows where "@i{<st-name>}" was +set to be "@code{lookup}": + +@example +[+ (make-gperf "lookup" (join "\n" (stack "name_list"))) +(gperf-code "lookup") +] +void my_fun(char * str) @{ +struct lookup_index * li = lookup_find(str, strlen(str)); +if (li != NULL) printf("%s yields %d\n", str, li->idx); +@end example + +Arguments: +@* +st-name - the name of the gperf hash list + +@node SCM gpl +@subsection @file{gpl} - GNU General Public License +@findex gpl + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expFormat.c line 751. +@end ignore + +Usage: (gpl prog-name prefix) +@* +Emit a string that contains the GNU General Public License. +This function is now deprecated. Please @xref{SCM license-description}. + +Arguments: +@* +prog-name - name of the program under the GPL +@* +prefix - String for starting each output line + +@node SCM hide-email +@subsection @file{hide-email} - convert eaddr to javascript +@findex hide-email + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expPrint.c line 246. +@end ignore + +Usage: (hide-email display eaddr) +@* +Hides an email address as a java scriptlett. +The 'mailto:' tag and the email address are coded bytes +rather than plain text. They are also broken up. + +Arguments: +@* +display - display text +@* +eaddr - email address + +@node SCM html-escape-encode +@subsection @file{html-escape-encode} - encode html special characters +@findex html-escape-encode + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/schemedef.scm line 110. +@end ignore + +Usage: (html-escape-encode str) +@* +This function will replace replace the characters @code{'&'}, +@code{'<'} and @code{'>'} characters with the HTML/XML +escape-encoded strings (@code{"&"}, @code{"<"}, and +@code{">"}, respectively). + +Arguments: +@* +str - string to make substitutions in + +@node SCM in? +@subsection @file{in?} - test for string in list +@findex in? + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expString.c line 267. +@end ignore + +Usage: (in? test-string string-list ...) +@* +Return SCM_BOOL_T if the first argument string is found +in one of the entries in the second (list-of-strings) argument. + +Arguments: +@* +test-string - string to look for +@* +string-list - list of strings to check + +@node SCM join +@subsection @file{join} - join string list with separator +@findex join + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expString.c line 334. +@end ignore + +Usage: (join separator list ...) +@* +With the first argument as the separator string, +joins together an a-list of strings into one long string. +The list may contain nested lists, partly because you +cannot always control that. + +Arguments: +@* +separator - string to insert between entries +@* +list - list of strings to join + +@node SCM kr-string +@subsection @file{kr-string} - emit string for K&R C +@findex kr-string + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expString.c line 749. +@end ignore + +Usage: (kr-string string) +@* +Reform a string so that, when printed, a K&R C compiler will be able +to compile the data and construct a string that contains exactly +what the current string contains. Many non-printing characters are +replaced with escape sequences. New-lines are replaced with a +backslash-n-backslash and newline sequence, + +Arguments: +@* +string - string to reformat + +@node SCM lgpl +@subsection @file{lgpl} - GNU Library General Public License +@findex lgpl + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expFormat.c line 799. +@end ignore + +Usage: (lgpl prog_name owner prefix) +@* +Emit a string that contains the GNU Library General Public License. +This function is now deprecated. Please @xref{SCM license-description}. + +Arguments: +@* +prog_name - name of the program under the LGPL +@* +owner - Grantor of the LGPL +@* +prefix - String for starting each output line + +@node SCM license +@subsection @file{license} - an arbitrary license +@findex license + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expFormat.c line 850. +@end ignore + +Usage: (license lic_name prog_name owner prefix) +@* +Emit a string that contains the named license. +This function is now deprecated. Please @xref{SCM license-description}. + +Arguments: +@* +lic_name - file name of the license +@* +prog_name - name of the licensed program or library +@* +owner - Grantor of the License +@* +prefix - String for starting each output line + +@node SCM license-description +@subsection @file{license-description} - Emit a license description +@findex license-description + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expFormat.c line 673. +@end ignore + +Usage: (license-description license prog-name prefix [ owner ]) +@* +Emit a string that contains a detailed license description, with +substitutions for program name, copyright holder and a per-line prefix. +This is the text typically used as part of a source file header. +For more details, @xref{SCM license-full, the license-full command}. + +Arguments: +@* +license - name of license type +@* +prog-name - name of the program under the GPL +@* +prefix - String for starting each output line +@* +owner - Optional - owner of the program + +@node SCM license-full +@subsection @file{license-full} - Emit the licensing information and description +@findex license-full + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expFormat.c line 616. +@end ignore + +Usage: (license-full license prog-name prefix [ owner ] [ years ]) +@* +Emit all the text that @code{license-info} and @code{license-description} +would emit (@pxref{SCM license-info, @code{license-info}}, +and @pxref{SCM license-description, @code{license-description}}), +with all the same substitutions. + +All of these depend upon the existence of a license file named after the +@code{license} argument with a @code{.lic} suffix. That file should +contain three blocks of text, each separated by two or more consecutive +newline characters (at least one completely blank line). + +The first section describes copyright attribution and the name of the usage +licence. For GNU software, this should be the text that is to be displayed +with the program version. Four text markers can be replaced: <PFX>, +<program>, <years> and <owner>. + +The second section is a short description of the terms of the license. +This is typically the kind of text that gets displayed in the header of +source files. Only the <PFX>, <owner> and <program> markers are +substituted. + +The third section is strictly the name of the license. +No marker substitutions are performed. + +@example +<PFX>Copyright (C) <years> <owner>, all rights reserved. +<PFX> +<PFX>This is free software. It is licensed for use, +<PFX>modification and redistribution under the terms +<PFX>of the GNU General Public License, version 3 or later +<PFX> <http://gnu.org/licenses/gpl.html> + +<PFX><program> is free software: you can redistribute it +<PFX>and/or modify it under the terms of the GNU General +<PFX>Public License as published by the Free Software ... + +the GNU General Public License, version 3 or later +@end example + +Arguments: +@* +license - name of license type +@* +prog-name - name of the program under the GPL +@* +prefix - String for starting each output line +@* +owner - Optional - owner of the program +@* +years - Optional - copyright years + +@node SCM license-info +@subsection @file{license-info} - Emit the licensing information and copyright years +@findex license-info + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expFormat.c line 697. +@end ignore + +Usage: (license-info license prog-name prefix [ owner ] [ years ]) +@* +Emit a string that contains the licensing description, with some +substitutions for program name, copyright holder, a list of years when the +source was modified, and a per-line prefix. This text typically includes a +brief license description and is often printed out when a program starts +running or as part of the @code{--version} output. +For more details, @xref{SCM license-full, the license-full command}. + +Arguments: +@* +license - name of license type +@* +prog-name - name of the program under the GPL +@* +prefix - String for starting each output line +@* +owner - Optional - owner of the program +@* +years - Optional - copyright years + +@node SCM license-name +@subsection @file{license-name} - Emit the name of the license +@findex license-name + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expFormat.c line 724. +@end ignore + +Usage: (license-name license) +@* +Emit a string that contains the full name of the license. + +Arguments: +@* +license - name of license type + +@node SCM make-gperf +@subsection @file{make-gperf} - build a perfect hash function program +@findex make-gperf + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expGperf.c line 41. +@end ignore + +Usage: (make-gperf name strings ...) +@* +Build a program to perform perfect hashes of a known list of input +strings. This function produces no output, but prepares a program +named, @file{gperf_<name>} for use by the gperf function +@xref{SCM gperf}. + +This program will be obliterated as AutoGen exits. +However, you may incorporate the generated hashing function +into your C program with commands something like the following: + +@example +[+ (shellf "sed '/^int main(/,$d;/^#line/d' $@{gpdir@}/%s.c" +name ) +] +@end example + +where @code{name} matches the name provided to this @code{make-perf} +function. @code{gpdir} is the variable used to store the name of the +temporary directory used to stash all the files. + +Arguments: +@* +name - name of hash list +@* +strings - list of strings to hash + +@node SCM makefile-script +@subsection @file{makefile-script} - create makefile script +@findex makefile-script + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expMake.c line 255. +@end ignore + +Usage: (makefile-script text) +@* +This function will take ordinary shell script text and reformat it +so that it will work properly inside of a makefile shell script. +Not every shell construct can be supported; the intent is to have +most ordinary scripts work without much, if any, alteration. + +The following transformations are performed on the source text: + +@enumerate +@item +Trailing whitespace on each line is stripped. + +@item +Except for the last line, the string, " ; \\" is appended to the end of +every line that does not end with certain special characters or keywords. +Note that this will mutilate multi-line quoted strings, but @command{make} +renders it impossible to use multi-line constructs anyway. + +@item +If the line ends with a backslash, it is left alone. + +@item +If the line ends with a semi-colon, conjunction operator, pipe (vertical +bar) or one of the keywords "then", "else" or "in", then a space and a +backslash is added, but no semi-colon. + +@item +The dollar sign character is doubled, unless it immediately precedes an +opening parenthesis or the single character make macros '*', '<', '@@', +'?' or '%'. Other single character make macros that do not have enclosing +parentheses will fail. For shell usage of the "$@@", "$?" and "$*" +macros, you must enclose them with curly braces, e.g., "$@{?@}". +The ksh construct @code{$(<command>)} will not work. Though some +@command{make}s accept @code{$@{var@}} constructs, this function will +assume it is for shell interpretation and double the dollar character. +You must use @code{$(var)} for all @command{make} substitutions. + +@item +Double dollar signs are replaced by four before the next character +is examined. + +@item +Every line is prefixed with a tab, unless the first line +already starts with a tab. + +@item +The newline character on the last line, if present, is suppressed. + +@item +Blank lines are stripped. + +@item +Lines starting with "@@ifdef", "@@ifndef", "@@else" and "@@endif" are +presumed to be autoconf "sed" expression tags. These lines will be +emitted as-is, with no tab prefix and no line splicing backslash. +These lines can then be processed at configure time with +@code{AC_CONFIG_FILES} sed expressions, similar to: + +@example +sed "/^@@ifdef foo/d;/^@@endif foo/d;/^@@ifndef foo/,/^@@endif foo/d" +@end example +@end enumerate + +@noindent +This function is intended to be used approximately as follows: + +@example +$(TARGET) : $(DEPENDENCIES) +<+ (out-push-new) +> +....mostly arbitrary shell script text.... +<+ (makefile-script (out-pop #t)) +> +@end example + +Arguments: +@* +text - the text of the script + +@node SCM max +@subsection @file{max} - maximum value in list +@findex max + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expGuile.c line 126. +@end ignore + +Usage: (max list ...) +@* +Return the maximum value in the list + +Arguments: +@* +list - list of values. Strings are converted to numbers + +@node SCM min +@subsection @file{min} - minimum value in list +@findex min + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expGuile.c line 185. +@end ignore + +Usage: (min list ...) +@* +Return the minimum value in the list + +Arguments: +@* +list - list of values. Strings are converted to numbers + +@node SCM prefix +@subsection @file{prefix} - prefix lines with a string +@findex prefix + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expString.c line 432. +@end ignore + +Usage: (prefix prefix text) +@* +Prefix every line in the second string with the first string. +This includes empty lines. Trailing white space will be removed +so if the prefix is all horizontal white space, then it will be +removed from otherwise blank lines. Also, if the last character +is a newline, then *two* prefixes will be inserted into the result +text. + +For example, if the first string is "# " and the second contains: +@example +"two\nlines\n" +@end example +@noindent +The result string will contain: +@example +# two +# lines +# +@end example + +The last line will be incomplete: no newline and no space after the +hash character, either. + +Arguments: +@* +prefix - string to insert at start of each line +@* +text - multi-line block of text + +@node SCM printf +@subsection @file{printf} - format to stdout +@findex printf + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expPrint.c line 200. +@end ignore + +Usage: (printf format [ format-arg ... ]) +@* +Format a string using arguments from the alist. +Write to the standard out port. The result will NOT appear in your +output. Use this to print information messages to a template user. +Use ``(sprintf ...)'' to add text to your document. + +Arguments: +@* +format - formatting string +@* +format-arg - Optional - list of arguments to formatting string + +@node SCM raw-shell-str +@subsection @file{raw-shell-str} - single quote shell string +@findex raw-shell-str + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expString.c line 521. +@end ignore + +Usage: (raw-shell-str string) +@* +Convert the text of the string into a singly quoted string +that a normal shell will process into the original string. +(It will not do macro expansion later, either.) +Contained single quotes become tripled, with the middle quote +escaped with a backslash. Normal shells will reconstitute the +original string. + +@strong{Notice}: some shells will not correctly handle unusual +non-printing characters. This routine works for most reasonably +conventional ASCII strings. + +Arguments: +@* +string - string to transform + +@node SCM shell +@subsection @file{shell} - invoke a shell script +@findex shell + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/agShell.c line 60. +@end ignore + +Usage: (shell command ...) +@* +Generate a string by writing the value to a server shell and reading the +output back in. The template programmer is responsible for ensuring that +it completes within 10 seconds. If it does not, the server will be +killed, the output tossed and a new server started. + +Please note: This is the same server process used by the '#shell' +definitions directive and backquoted @code{`} definitions. There may be +left over state from previous shell expressions and the @code{`} +processing in the declarations. However, a @code{cd} to the original +directory is always issued before the new command is issued. + +Also note: When initializing, autogen will set the environment +variable "AGexe" to the full path of the autogen executable. + +Arguments: +@* +command - shell command - the result is from stdout + +@node SCM shell-str +@subsection @file{shell-str} - double quote shell string +@findex shell-str + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expString.c line 618. +@end ignore + +Usage: (shell-str string) +@* +Convert the text of the string into a double quoted string that a normal +shell will process into the original string, almost. It will add the +escape character @code{\\} before two special characters to +accomplish this: the backslash @code{\\} and double quote @code{"}. + +@strong{Notice}: some shells will not correctly handle unusual +non-printing characters. This routine works for most reasonably +conventional ASCII strings. + +@strong{WARNING}: +@* +This function omits the extra backslash in front of a backslash, however, +if it is followed by either a backquote or a dollar sign. It must do this +because otherwise it would be impossible to protect the dollar sign or +backquote from shell evaluation. Consequently, it is not possible to +render the strings "\\$" or "\\`". The lesser of two evils. + +All others characters are copied directly into the output. + +The @code{sub-shell-str} variation of this routine behaves identically, +except that the extra backslash is omitted in front of @code{"} instead +of @code{`}. You have to think about it. I'm open to suggestions. + +Meanwhile, the best way to document is with a detailed output example. +If the backslashes make it through the text processing correctly, +below you will see what happens with three example strings. The first +example string contains a list of quoted @code{foo}s, the second is +the same with a single backslash before the quote characters and the +last is with two backslash escapes. Below each is the result of the +@code{raw-shell-str}, @code{shell-str} and @code{sub-shell-str} functions. + +@example +foo[0] ''foo'' 'foo' "foo" `foo` $foo +raw-shell-str -> \'\''foo'\'\'' '\''foo'\'' "foo" `foo` $foo' +shell-str -> "''foo'' 'foo' \"foo\" `foo` $foo" +sub-shell-str -> `''foo'' 'foo' "foo" \`foo\` $foo` + +foo[1] \'bar\' \"bar\" \`bar\` \$bar +raw-shell-str -> '\'\''bar\'\'' \"bar\" \`bar\` \$bar' +shell-str -> "\\'bar\\' \\\"bar\\\" \`bar\` \$bar" +sub-shell-str -> `\\'bar\\' \"bar\" \\\`bar\\\` \$bar` + +foo[2] \\'BAZ\\' \\"BAZ\\" \\`BAZ\\` \\$BAZ +raw-shell-str -> '\\'\''BAZ\\'\'' \\"BAZ\\" \\`BAZ\\` \\$BAZ' +shell-str -> "\\\\'BAZ\\\\' \\\\\"BAZ\\\\\" \\\`BAZ\\\` \\\$BAZ" +sub-shell-str -> `\\\\'BAZ\\\\' \\\"BAZ\\\" \\\\\`BAZ\\\\\` \\\$BAZ` +@end example + +There should be four, three, five and three backslashes for the four +examples on the last line, respectively. The next to last line should +have four, five, three and three backslashes. If this was not accurately +reproduced, take a look at the agen5/test/shell.test test. Notice the +backslashes in front of the dollar signs. It goes from zero to one to +three for the "cooked" string examples. + +Arguments: +@* +string - string to transform + +@node SCM shellf +@subsection @file{shellf} - format a string, run shell +@findex shellf + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/agShell.c line 108. +@end ignore + +Usage: (shellf format [ format-arg ... ]) +@* +Format a string using arguments from the alist, +then send the result to the shell for interpretation. + +Arguments: +@* +format - formatting string +@* +format-arg - Optional - list of arguments to formatting string + +@node SCM sprintf +@subsection @file{sprintf} - format a string +@findex sprintf + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expPrint.c line 178. +@end ignore + +Usage: (sprintf format [ format-arg ... ]) +@* +Format a string using arguments from the alist. + +Arguments: +@* +format - formatting string +@* +format-arg - Optional - list of arguments to formatting string + +@node SCM string-capitalize +@subsection @file{string-capitalize} - capitalize a new string +@findex string-capitalize + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expGuile.c line 425. +@end ignore + +Usage: (string-capitalize str) +@* +Create a new SCM string containing the same text as the original, +only all the first letter of each word is upper cased and all +other letters are made lower case. + +Arguments: +@* +str - input string + +@node SCM string-capitalize! +@subsection @file{string-capitalize!} - capitalize a string +@findex string-capitalize! + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expGuile.c line 382. +@end ignore + +Usage: (string-capitalize! str) +@* +capitalize all the words in an SCM string. + +Arguments: +@* +str - input/output string + +@node SCM *=* +@subsection @file{string-contains-eqv?} - caseless substring +@findex string-contains-eqv? +@findex *=* + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcCase.c line 229. +@end ignore + +Usage: (*=* text match) +@* +string-contains-eqv?: Test to see if a string contains an equivalent string. +`equivalent' means the strings match, but without regard +to character case and certain characters are considered `equivalent'. +Viz., '-', '_' and '^' are equivalent. + +Arguments: +@* +text - text to test for pattern +@* +match - pattern/substring to search for + +@node SCM *==* +@subsection @file{string-contains?} - substring match +@findex string-contains? +@findex *==* + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcCase.c line 96. +@end ignore + +Usage: (*==* text match) +@* +string-contains?: Test to see if a string contains a substring. "strstr(3)" +will find an address. + +Arguments: +@* +text - text to test for pattern +@* +match - pattern/substring to search for + +@node SCM string-downcase +@subsection @file{string-downcase} - lower case a new string +@findex string-downcase + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expGuile.c line 481. +@end ignore + +Usage: (string-downcase str) +@* +Create a new SCM string containing the same text as the original, +only all the upper case letters are changed to lower case. + +Arguments: +@* +str - input string + +@node SCM string-downcase! +@subsection @file{string-downcase!} - make a string be lower case +@findex string-downcase! + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expGuile.c line 450. +@end ignore + +Usage: (string-downcase! str) +@* +Change to lower case all the characters in an SCM string. + +Arguments: +@* +str - input/output string + +@node SCM *~ +@subsection @file{string-end-eqv-match?} - caseless regex ending +@findex string-end-eqv-match? +@findex *~ + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcCase.c line 501. +@end ignore + +Usage: (*~ text match) +@* +string-end-eqv-match?: Test to see if a string ends with a pattern. +Case is not significant. + +Arguments: +@* +text - text to test for pattern +@* +match - pattern/substring to search for + +@node SCM *~~ +@subsection @file{string-end-match?} - regex match end +@findex string-end-match? +@findex *~~ + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcCase.c line 488. +@end ignore + +Usage: (*~~ text match) +@* +string-end-match?: Test to see if a string ends with a pattern. +Case is significant. + +Arguments: +@* +text - text to test for pattern +@* +match - pattern/substring to search for + +@node SCM *= +@subsection @file{string-ends-eqv?} - caseless string ending +@findex string-ends-eqv? +@findex *= + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcCase.c line 277. +@end ignore + +Usage: (*= text match) +@* +string-ends-eqv?: Test to see if a string ends with an equivalent string. + +Arguments: +@* +text - text to test for pattern +@* +match - pattern/substring to search for + +@node SCM *== +@subsection @file{string-ends-with?} - string ending +@findex string-ends-with? +@findex *== + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcCase.c line 125. +@end ignore + +Usage: (*== text match) +@* +string-ends-with?: Test to see if a string ends with a substring. +strcmp(3) returns zero for comparing the string ends. + +Arguments: +@* +text - text to test for pattern +@* +match - pattern/substring to search for + +@node SCM == +@subsection @file{string-equals?} - string matching +@findex string-equals? +@findex == + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcCase.c line 200. +@end ignore + +Usage: (== text match) +@* +string-equals?: Test to see if two strings exactly match. + +Arguments: +@* +text - text to test for pattern +@* +match - pattern/substring to search for + +@node SCM ~ +@subsection @file{string-eqv-match?} - caseless regex match +@findex string-eqv-match? +@findex ~ + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcCase.c line 689. +@end ignore + +Usage: (~ text match) +@* +string-eqv-match?: Test to see if a string fully matches a pattern. +Case is not significant, but any character equivalences +must be expressed in your regular expression. + +Arguments: +@* +text - text to test for pattern +@* +match - pattern/substring to search for + +@node SCM = +@subsection @file{string-eqv?} - caseless match +@findex string-eqv? +@findex = + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcCase.c line 347. +@end ignore + +Usage: (= text match) +@* +string-eqv?: Test to see if two strings are equivalent. `equivalent' means the +strings match, but without regard to character case and certain +characters are considered `equivalent'. Viz., '-', '_' and '^' are +equivalent. If the arguments are not strings, then the result of the +numeric comparison is returned. + +This is an overloaded operation. If the arguments are both +numbers, then the query is passed through to @code{scm_num_eq_p()}, +otherwise the result depends on the SCMs being strictly equal. + +Arguments: +@* +text - text to test for pattern +@* +match - pattern/substring to search for + +@node SCM *~* +@subsection @file{string-has-eqv-match?} - caseless regex contains +@findex string-has-eqv-match? +@findex *~* + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcCase.c line 419. +@end ignore + +Usage: (*~* text match) +@* +string-has-eqv-match?: Test to see if a string contains a pattern. +Case is not significant. + +Arguments: +@* +text - text to test for pattern +@* +match - pattern/substring to search for + +@node SCM *~~* +@subsection @file{string-has-match?} - contained regex match +@findex string-has-match? +@findex *~~* + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcCase.c line 406. +@end ignore + +Usage: (*~~* text match) +@* +string-has-match?: Test to see if a string contains a pattern. +Case is significant. + +Arguments: +@* +text - text to test for pattern +@* +match - pattern/substring to search for + +@node SCM ~~ +@subsection @file{string-match?} - regex match +@findex string-match? +@findex ~~ + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcCase.c line 676. +@end ignore + +Usage: (~~ text match) +@* +string-match?: Test to see if a string fully matches a pattern. +Case is significant. + +Arguments: +@* +text - text to test for pattern +@* +match - pattern/substring to search for + +@node SCM ~* +@subsection @file{string-start-eqv-match?} - caseless regex start +@findex string-start-eqv-match? +@findex ~* + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcCase.c line 595. +@end ignore + +Usage: (~* text match) +@* +string-start-eqv-match?: Test to see if a string starts with a pattern. +Case is not significant. + +Arguments: +@* +text - text to test for pattern +@* +match - pattern/substring to search for + +@node SCM ~~* +@subsection @file{string-start-match?} - regex match start +@findex string-start-match? +@findex ~~* + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcCase.c line 582. +@end ignore + +Usage: (~~* text match) +@* +string-start-match?: Test to see if a string starts with a pattern. +Case is significant. + +Arguments: +@* +text - text to test for pattern +@* +match - pattern/substring to search for + +@node SCM =* +@subsection @file{string-starts-eqv?} - caseless string start +@findex string-starts-eqv? +@findex =* + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcCase.c line 314. +@end ignore + +Usage: (=* text match) +@* +string-starts-eqv?: Test to see if a string starts with an equivalent string. + +Arguments: +@* +text - text to test for pattern +@* +match - pattern/substring to search for + +@node SCM ==* +@subsection @file{string-starts-with?} - string starting +@findex string-starts-with? +@findex ==* + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcCase.c line 164. +@end ignore + +Usage: (==* text match) +@* +string-starts-with?: Test to see if a string starts with a substring. + +Arguments: +@* +text - text to test for pattern +@* +match - pattern/substring to search for + +@node SCM string-substitute +@subsection @file{string-substitute} - multiple global replacements +@findex string-substitute + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expString.c line 917. +@end ignore + +Usage: (string-substitute source match repl) +@* +@code{match} and @code{repl} may be either a single string or +a list of strings. Either way, they must have the same structure +and number of elements. For example, to replace all amphersands, +less than and greater than characters, do something like this: + +@example +(string-substitute source +(list "&" "<" ">") +(list "&" "<" ">")) +@end example + +Arguments: +@* +source - string to transform +@* +match - substring or substring list to be replaced +@* +repl - replacement strings or substrings + +@node SCM string-table-add +@subsection @file{string-table-add} - Add an entry to a string table +@findex string-table-add + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/schemedef.scm line 239. +@end ignore + +Usage: (string-table-add st-name str-val) +@* +Check for a duplicate string and, if none, then insert a new +string into the string table. In all cases, returns the +character index of the beginning of the string in the table. + +The returned index can be used in expressions like: +@example +string_array + <returned-value> +@end example +@noindent +that will yield the address of the first byte of the inserted +string. See the @file{strtable.test} AutoGen test for a usage +example. + +Arguments: +@* +st-name - the name of the array of characters +@* +str-val - the (possibly) new value to add + +@node SCM string-table-add-ref +@subsection @file{string-table-add-ref} - Add an entry to a string table, get reference +@findex string-table-add-ref + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/schemedef.scm line 277. +@end ignore + +Usage: (string-table-add-ref st-name str-val) +@* +Identical to string-table-add, except the value returned +is the string "st-name" '+' and the index returned by +string-table-add. + +Arguments: +@* +st-name - the name of the array of characters +@* +str-val - the (possibly) new value to add + +@node SCM string-table-new +@subsection @file{string-table-new} - create a string table +@findex string-table-new + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/schemedef.scm line 146. +@end ignore + +Usage: (string-table-new st-name) +@* +This function will create an array of characters. The companion +functions, (@xref{SCM string-table-add}, +@xref{SCM string-table-add-ref}, and +@pxref{SCM emit-string-table}) will insert text and emit the +populated table. + +With these functions, it should be much easier to construct +structures containing string offsets instead of string pointers. +That can be very useful when transmitting, storing or sharing data +with different address spaces. + +@noindent +Here is a brief example copied from the strtable.test test: + +@example +[+ (string-table-new "scribble") + (out-push-new) ;; redirect output to temporary + (define ct 1) +][+ + +FOR str IN that was the week that was +][+ + (set! ct (+ ct 1)) ++] + [+ (string-table-add-ref "scribble" (get "str")) +],[+ +ENDFOR +] +[+ (out-suspend "main") + (emit-string-table "scribble") + (ag-fprintf 0 "\nchar const *ap[%d] = @{" ct) + (out-resume "main") + (out-pop #t) ;; now dump out the redirected output +] + NULL @}; +@end example + +@noindent +Some explanation: + +@noindent +I added the @code{(out-push-new)} because the string table text is +diverted into an output stream named, ``scribble'' and I want to +have the string table emitted before the string table references. +The string table references are also emitted inside the @code{FOR} +loop. So, when the loop is done, the current output is suspended +under the name, ``main'' and the ``scribble'' table is then emitted +into the primary output. (@code{emit-string-table} inserts its +output directly into the current output stream. It does not need to +be the last function in an AutoGen macro block.) Next I +@code{ag-fprintf} the array-of-pointer declaration directly into the +current output. Finally I restore the ``main'' output stream and +@code{(out-pop #t)}-it into the main output stream. + +Here is the result. Note that duplicate strings are not repeated +in the string table: + +@example +static char const scribble[18] = + "that\0" "was\0" "the\0" "week\0"; + +char const *ap[7] = @{ + scribble+0, + scribble+5, + scribble+9, + scribble+13, + scribble+0, + scribble+5, + NULL @}; +@end example + +These functions use the global name space @code{stt-*} in addition to +the function names. + +If you utilize this in your programming, it is recommended that you +prevent printf format usage warnings with the GCC option +@code{-Wno-format-contains-nul} + +Arguments: +@* +st-name - the name of the array of characters + +@node SCM string-table-size +@subsection @file{string-table-size} - print the current size of a string table +@findex string-table-size + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/schemedef.scm line 326. +@end ignore + +Usage: (string-table-size st-name) +@* +Returns the current byte count of the string table. + +Arguments: +@* +st-name - the name of the array of characters + +@node SCM string->c-name! +@subsection @file{string->c-name!} - map non-name chars to underscore +@findex string->c-name! + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expGuile.c line 286. +@end ignore + +Usage: (string->c-name! str) +@* +Change all the graphic characters that are invalid in a C name token +into underscores. Whitespace characters are ignored. Any other +character type (i.e. non-graphic and non-white) will cause a failure. + +Arguments: +@* +str - input/output string + +@node SCM string->camelcase +@subsection @file{string->camelcase} - make a string be CamelCase +@findex string->camelcase + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expGuile.c line 505. +@end ignore + +Usage: (string->camelcase str) +@* +Capitalize the first letter of each block of letters and numbers, +and stripping out characters that are not alphanumerics. +For example, "alpha-beta0gamma" becomes "AlphaBeta0gamma". + +Arguments: +@* +str - input/output string + +@node SCM string-tr +@subsection @file{string-tr} - convert characters with new result +@findex string-tr + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expString.c line 897. +@end ignore + +Usage: (string-tr source match translation) +@* +This is identical to @code{string-tr!}, except that it does not +over-write the previous value. + +Arguments: +@* +source - string to transform +@* +match - characters to be converted +@* +translation - conversion list + +@node SCM string-tr! +@subsection @file{string-tr!} - convert characters +@findex string-tr! + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expString.c line 823. +@end ignore + +Usage: (string-tr! source match translation) +@* +This is the same as the @code{tr(1)} program, except the +string to transform is the first argument. The second and +third arguments are used to construct mapping arrays for the +transformation of the first argument. + +It is too bad this little program has so many different +and incompatible implementations! + +Arguments: +@* +source - string to transform +@* +match - characters to be converted +@* +translation - conversion list + +@node SCM string-upcase +@subsection @file{string-upcase} - upper case a new string +@findex string-upcase + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expGuile.c line 358. +@end ignore + +Usage: (string-upcase str) +@* +Create a new SCM string containing the same text as the original, +only all the lower case letters are changed to upper case. + +Arguments: +@* +str - input string + +@node SCM string-upcase! +@subsection @file{string-upcase!} - make a string be upper case +@findex string-upcase! + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expGuile.c line 327. +@end ignore + +Usage: (string-upcase! str) +@* +Change to upper case all the characters in an SCM string. + +Arguments: +@* +str - input/output string + +@node SCM sub-shell-str +@subsection @file{sub-shell-str} - back quoted (sub-)shell string +@findex sub-shell-str + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expString.c line 688. +@end ignore + +Usage: (sub-shell-str string) +@* +This function is substantially identical to @code{shell-str}, except +that the quoting character is @code{`} and the "leave the escape alone" +character is @code{"}. + +Arguments: +@* +string - string to transform + +@node SCM sum +@subsection @file{sum} - sum of values in list +@findex sum + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expGuile.c line 244. +@end ignore + +Usage: (sum list ...) +@* +Compute the sum of the list of expressions. + +Arguments: +@* +list - list of values. Strings are converted to numbers + +@node SCM time-string->number +@subsection @file{time-string->number} - duration string to seconds +@findex time-string->number + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expString.c line 959. +@end ignore + +Usage: (time-string->number time_spec) +@* +Convert the argument string to a time period in seconds. +The string may use multiple parts consisting of days, hours +minutes and seconds. These are indicated with a suffix of +@code{d}, @code{h}, @code{m} and @code{s} respectively. +Hours, minutes and seconds may also be represented with +@code{HH:MM:SS} or, without hours, as @code{MM:SS}. + +Arguments: +@* +time_spec - string to parse + +@node SCM version-compare +@subsection @file{version-compare} - compare two version numbers +@findex version-compare + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/expState.c line 210. +@end ignore + +Usage: (version-compare op v1 v2) +@* +Converts v1 and v2 strings into 64 bit values and returns the +result of running 'op' on those values. It assumes that the version +is a 1 to 4 part dot-separated series of numbers. Suffixes like, +"5pre4" or "5-pre4" will be interpreted as two numbers. The first +number ("5" in this case) will be decremented and the number after +the "pre" will be added to 0xC000. (Unless your platform is unable +to support 64 bit integer arithmetic. Then it will be added to 0xC0.) +Consequently, these yield true: +@example +(version-compare > "5.8.5" "5.8.5-pre4") +(version-compare > "5.8.5-pre10" "5.8.5-pre4") +@end example + +Arguments: +@* +op - comparison operator +@* +v1 - first version +@* +v2 - compared-to version +@ignore +START == MACROS == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@c === SECTION MARKER + +@node native macros +@section AutoGen Native Macros +@cindex native macros + +This section describes the various AutoGen natively defined macros. +Unlike the Scheme functions, some of these macros are "block macros" +with a scope that extends through a terminating macro. Block macros +must not overlap. That is to say, a block macro started within the +scope of an encompassing block macro must have its matching end macro +appear before the encompassing block macro is either ended or subdivided. + +The block macros are these: + +@table @code +@item CASE +This macro has scope through the @code{ESAC} macro. +The scope is subdivided by @code{SELECT} macros. +You must have at least one @code{SELECT} macro. + +@item DEFINE +This macro has scope through the @code{ENDDEF} macro. The defined +user macro can never be a block macro. This macro is extracted from +the template @i{before} the template is processed. Consequently, you +cannot select a definition based on context. You can, however, place +them all at the end of the file. + +@item FOR +This macro has scope through the @code{ENDFOR} macro. + +@item IF +This macro has scope through the @code{ENDIF} macro. +The scope may be subdivided by @code{ELIF} and @code{ELSE} +macros. Obviously, there may be only one @code{ELSE} macro +and it must be the last of these subdivisions. + +@item INCLUDE +This macro has the scope of the included file. +It is a block macro in the sense that the included +file must not contain any incomplete block macros. + +@item WHILE +This macro has scope through the @code{ENDWHILE} macro. +@end table +@ignore +END == MACROS == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore +@menu +* AGMacro syntax:: AutoGen Macro Syntax +* BREAK:: BREAK - Leave a FOR or WHILE macro +* CASE:: CASE - Select one of several template blocks +* COMMENT:: COMMENT - A block of comment to be ignored +* CONTINUE:: CONTINUE - Skip to end of a FOR or WHILE macro. +* DEBUG:: DEBUG - Print debug message to trace output +* DEFINE:: DEFINE - Define a user AutoGen macro +* ELIF:: ELIF - Alternate Conditional Template Block +* ELSE:: ELSE - Alternate Template Block +* ENDDEF:: ENDDEF - Ends a macro definition. +* ENDFOR:: ENDFOR - Terminates the @code{FOR} function template block +* ENDIF:: ENDIF - Terminate the @code{IF} Template Block +* ENDWHILE:: ENDWHILE - Terminate the @code{WHILE} Template Block +* ESAC:: ESAC - Terminate the @code{CASE} Template Block +* EXPR:: EXPR - Evaluate and emit an Expression +* FOR:: FOR - Emit a template block multiple times +* IF:: IF - Conditionally Emit a Template Block +* INCLUDE:: INCLUDE - Read in and emit a template block +* INVOKE:: INVOKE - Invoke a User Defined Macro +* RETURN:: RETURN - Leave an INVOKE-d (DEFINE) macro +* SELECT:: SELECT - Selection block for CASE function +* UNKNOWN:: UNKNOWN - Either a user macro or a value name. +* WHILE:: WHILE - Conditionally loop over a Template Block +* shell command:: Inserting text from a shell script +* guile command:: Inserting text from a scheme script +@end menu +@node AGMacro syntax +@subsection AutoGen Macro Syntax +@cindex macro syntax + +The general syntax is: + +@example +[ @{ <native-macro-name> | <user-defined-name> @} ] [ <arg> ... ] +@end example + +@noindent +The syntax for @code{<arg>} depends on the particular macro, +but is generally a full expression (@pxref{expression syntax}). +Here are the exceptions to that general rule: + +@enumerate +@item +@code{INVOKE} macros, implicit or explicit, must be followed by +a list of name/string value pairs. The string values are +@i{simple expressions}, as described above. + +That is, the @code{INVOKE} syntax is one of these two: +@example +<user-macro-name> [ <name> [ = <expression> ] ... ] + +INVOKE <name-expression> [ <name> [ = <expression> ] ... ] +@end example + +@item +AutoGen FOR macros must be in one of three forms: + +@example +FOR <name> [ <separator-string> ] + +FOR <name> (...Scheme expression list) + +FOR <name> IN <string-entry> [ ... ] +@end example +@noindent +where: +@table @samp +@item <name> +must be a simple name. +@item <separator-string> +is inserted between copies of the enclosed block. Do not try to use ``IN'' +as your separator string. It won't work. +@item <string-entry> +is an entry in a list of strings. ``@code{<name>}'' is assigned +each value from the ``@code{IN}'' list before expanding the @code{FOR} block. +@item (...Scheme expression list) +is expected to contain one or more of the @code{for-from}, +@code{for-to}, @code{for-by}, and @code{for-sep} functions. +(@xref{FOR}, and @ref{AutoGen Functions}) +@end table + +The first two forms iterate over the @code{FOR} block if @code{<name>} +is found in the AutoGen values. The last form will create the AutoGen +value named @code{<name>}. + +@item +AutoGen @code{DEFINE} macros must be followed by a simple name. +Anything after that is ignored. Consequently, that ``comment space'' +may be used to document any named values the macro expects to have +set up as arguments. @xref{DEFINE}. + +@item +The AutoGen @code{COMMENT}, @code{ELSE}, @code{ESAC} and the @code{END*} +macros take no arguments and ignore everything after the macro name +(e.g. see @ref{COMMENT}) +@end enumerate + +@node BREAK +@subsection BREAK - Leave a FOR or WHILE macro + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/functions.c line 38. +@end ignore + +@findex BREAK + +This will unwind the loop context and resume after ENDFOR/ENDWHILE. +Note that unless this happens to be the last iteration anyway, +the (last-for?) function will never yield "#t". + +@node CASE +@subsection CASE - Select one of several template blocks + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcCase.c line 818. +@end ignore + +@findex CASE + +The arguments are evaluated and converted to a string, if necessary. A +simple name will be interpreted as an AutoGen value name and its value will +be used by the @code{SELECT} macros (see the example below and the +expression evaluation function, @pxref{EXPR}). The scope of the macro is +up to the matching @code{ESAC} macro. Within the scope of a @code{CASE}, +this string is matched against case selection macros. There are sixteen +match macros that are derived from four different ways matches may be +performed, plus an "always true", "true if the AutoGen value was found", +and "true if no AutoGen value was found" matches. The codes for the +nineteen match macros are formed as follows: + +@enumerate +@item +Must the match start matching from the beginning of the string? +If not, then the match macro code starts with an asterisk (@code{*}). +@item +Must the match finish matching at the end of the string? +If not, then the match macro code ends with an asterisk (@code{*}). +@item +Is the match a pattern match or a string comparison? +If a comparison, use an equal sign (@code{=}). +If a pattern match, use a tilde (@code{~}). +@item +Is the match case sensitive? +If alphabetic case is important, double the tilde or equal sign. +@item +Do you need a default match when none of the others match? +Use a single asterisk (@code{*}). +@item +Do you need to distinguish between an empty string value and a value +that was not found? Use the non-existence test (@code{!E}) before +testing a full match against an empty string (@code{== ''}). +There is also an existence test (@code{+E}), more for symmetry than +for practical use. +@end enumerate + +@noindent +For example: + +@example +[+ CASE <full-expression> +] +[+ ~~* "[Tt]est" +]reg exp must match at start, not at end +[+ == "TeSt" +]a full-string, case sensitive compare +[+ = "TEST" +]a full-string, case insensitive compare +[+ !E +]not exists - matches if no AutoGen value found +[+ == "" +]expression yielded a zero-length string +[+ +E +]exists - matches if there is any value result +[+ * +]always match - no testing +[+ ESAC +] +@end example + +@code{<full-expression>} (@pxref{expression syntax}) may be any expression, +including the use of apply-codes and value-names. If the expression yields +a number, it is converted to a decimal string. + +These case selection codes have also been implemented as +Scheme expression functions using the same codes. They are documented +in this texi doc as ``string-*?'' predicates (@pxref{Common Functions}). + +@node COMMENT +@subsection COMMENT - A block of comment to be ignored + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/functions.c line 350. +@end ignore + +@findex COMMENT + +This function can be specified by the user, but there will +never be a situation where it will be invoked at emit time. +The macro is actually removed from the internal representation. + +If the native macro name code is @code{#}, then the +entire macro function is treated as a comment and ignored. + +@example +[+ # say what you want, but no '+' before any ']' chars +] +@end example + +@node CONTINUE +@subsection CONTINUE - Skip to end of a FOR or WHILE macro. + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/functions.c line 28. +@end ignore + +@findex CONTINUE + +This will skip the remainder of the loop and start the next. + +@node DEBUG +@subsection DEBUG - Print debug message to trace output + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcDef.c line 379. +@end ignore + +@findex DEBUG + +If the tracing level is at "debug-message" or above +(@pxref{autogen trace}), this macro prints a debug message to trace +output. This message is not evaluated. This macro can also be used to +set useful debugger breakpoints. By inserting [+DEBUG n+] into your +template, you can set a debugger breakpoint on the #n case element +below (in the AutoGen source) and step through the processing of +interesting parts of your template. + +To be useful, you have to have access to the source tree where autogen +was built and the template being processed. The definitions are also +helpful, but not crucial. Please contact the author if you think you +might actually want to use this. + +@node DEFINE +@subsection DEFINE - Define a user AutoGen macro + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcDef.c line 523. +@end ignore + +@findex DEFINE +@cindex define macro + +This function will define a new macro. You must provide a name for the +macro. You do not specify any arguments, though the invocation may +specify a set of name/value pairs that are to be active during the +processing of the macro. + +@example +[+ define foo +] +... macro body with macro functions ... +[+ enddef +] +... [+ foo bar='raw text' baz=<<text expression>> +] +@end example + +Once the macro has been defined, this new macro can be invoked by +specifying the macro name as the first token after the start macro marker. +Alternatively, you may make the invocation explicitly invoke a defined +macro by specifying @code{INVOKE} (@pxref{INVOKE}) in the macro +invocation. If you do that, the macro name can be computed with an +expression that gets evaluated every time the INVOKE macro is encountered. + +Any remaining text in the macro invocation will be used to create new +name/value pairs that only persist for the duration of the processing of +the macro. The expressions are evaluated the same way basic +expressions are evaluated. @xref{expression syntax}. + +The resulting definitions are handled much like regular +definitions, except: + +@enumerate +@item +The values may not be compound. That is, they may not contain +nested name/value pairs. +@item +The bindings go away when the macro is complete. +@item +The name/value pairs are separated by whitespace instead of +semi-colons. +@item +Sequences of strings are not concatenated. +@end enumerate + +@quotation +@strong{NB:} The macro is extracted from the template as the template is +scanned. You cannot conditionally define a macro by enclosing it in an +@code{IF}/@code{ENDIF} (@pxref{IF}) macro pair. If you need to dynamically +select the format of a @code{DEFINE}d macro, then put the flavors into +separate template files that simply define macros. @code{INCLUDE} +(@pxref{INCLUDE}) the appropriate template when you have computed which +you need. +@end quotation + +Due to this, it is acceptable and even a good idea to place all the +@code{DEFINE} macros at the end of the template. That puts the main +body of the template at the beginning of the file. + +@node ELIF +@subsection ELIF - Alternate Conditional Template Block + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcIf.c line 249. +@end ignore + +@findex ELIF + +This macro must only appear after an @code{IF} function, and +before any associated @code{ELSE} or @code{ENDIF} functions. +It denotes the start of an alternate template block for the +@code{IF} function. Its expression argument is evaluated as are +the arguments to @code{IF}. For a complete description @xref{IF}. + +@node ELSE +@subsection ELSE - Alternate Template Block + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcIf.c line 277. +@end ignore + +@findex ELSE + +This macro must only appear after an @code{IF} function, +and before the associated @code{ENDIF} function. +It denotes the start of an alternate template block for +the @code{IF} function. For a complete description @xref{IF}. + +@node ENDDEF +@subsection ENDDEF - Ends a macro definition. + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcDef.c line 587. +@end ignore + +@findex ENDDEF + +This macro ends the @code{DEFINE} function template block. +For a complete description @xref{DEFINE}. + +@node ENDFOR +@subsection ENDFOR - Terminates the @code{FOR} function template block + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcFor.c line 702. +@end ignore + +@findex ENDFOR + +This macro ends the @code{FOR} function template block. +For a complete description @xref{FOR}. + +@node ENDIF +@subsection ENDIF - Terminate the @code{IF} Template Block + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcIf.c line 123. +@end ignore + +@findex ENDIF + +This macro ends the @code{IF} function template block. +For a complete description @xref{IF}. + +@node ENDWHILE +@subsection ENDWHILE - Terminate the @code{WHILE} Template Block + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcIf.c line 206. +@end ignore + +@findex ENDWHILE + +This macro ends the @code{WHILE} function template block. +For a complete description @xref{WHILE}. + +@node ESAC +@subsection ESAC - Terminate the @code{CASE} Template Block + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcCase.c line 885. +@end ignore + +@findex ESAC + +This macro ends the @code{CASE} function template block. +For a complete description, @xref{CASE}. + +@node EXPR +@subsection EXPR - Evaluate and emit an Expression + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcEval.c line 562. +@end ignore + +@findex EXPR + +This macro does not have a name to cause it to be invoked +explicitly, though if a macro starts with one of the apply codes +or one of the simple expression markers, then an expression +macro is inferred. The result of the expression evaluation +(@pxref{expression syntax}) is written to the current output. + +@node FOR +@subsection FOR - Emit a template block multiple times + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcFor.c line 622. +@end ignore + +@findex FOR +@cindex looping, for +@cindex for loop + +This macro has a slight variation on the standard syntax: +@example +FOR <value-name> [ <separator-string> ] + +FOR <value-name> (...Scheme expression list) + +FOR <value-name> IN "string" [ ... ] +@end example + +Other than for the last form, the first macro argument must be the name of +an AutoGen value. If there is no value associated with the name, the +@code{FOR} template block is skipped entirely. The scope of the @code{FOR} +macro extends to the corresponding @code{ENDFOR} macro. The last form will +create an array of string values named @code{<value-name>} that only exists +within the context of this @code{FOR} loop. With this form, in order to +use a @code{separator-string}, you must code it into the end of the +template block using the @code{(last-for?)} predicate function +(@pxref{SCM last-for?}). + +If there are any arguments after the @code{value-name}, the initial +characters are used to determine the form. If the first character is +either a semi-colon (@code{;}) or an opening parenthesis (@code{(}), then +it is presumed to be a Scheme expression containing the FOR macro specific +functions @code{for-from}, @code{for-by}, @code{for-to}, and/or +@code{for-sep}. @xref{AutoGen Functions}. If it consists of an '@code{i}' +an '@code{n}' and separated by white space from more text, then the +@code{FOR x IN} form is processed. Otherwise, the remaining text is +presumed to be a string for inserting between each iteration of the loop. +This string will be emitted one time less than the number of iterations of +the loop. That is, it is emitted after each loop, excepting for the last +iteration. + +If the from/by/to functions are invoked, they will specify which copies of +the named value are to be processed. If there is no copy of the named +value associated with a particular index, the @code{FOR} template block +will be instantiated anyway. The template must use @code{found-for?} +(@pxref{SCM found-for?}) or other methods for detecting missing +definitions and emitting default text. In this fashion, you can insert +entries from a sparse or non-zero based array into a dense, zero based +array. + +@strong{NB:} the @code{for-from}, @code{for-to}, @code{for-by} and +@code{for-sep} functions are disabled outside of the context of the +@code{FOR} macro. Likewise, the @code{first-for?}, @code{last-for?} +@code{for-index}, and @code{found-for?} functions are disabled outside +of the range of a @code{FOR} block. + +@strong{Also:} the @code{<value-name>} must be a single level name, +not a compound name (@pxref{naming values}). + +@example +[+FOR var (for-from 0) (for-to <number>) (for-sep ",") +] +... text with @code{var}ious substitutions ...[+ +ENDFOR var+] +@end example + +@noindent +this will repeat the @code{... text with @code{var}ious +substitutions ...} <number>+1 times. Each repetition, +except for the last, will have a comma @code{,} after it. + +@example +[+FOR var ",\n" +] +... text with @code{var}ious substitutions ...[+ +ENDFOR var +] +@end example + +@noindent +This will do the same thing, but only for the index +values of @code{var} that have actually been defined. + +@node IF +@subsection IF - Conditionally Emit a Template Block + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcIf.c line 87. +@end ignore + +@findex IF +@cindex conditional emit +@cindex if test + +Conditional block. Its arguments are evaluated (@pxref{EXPR}) and +if the result is non-zero or a string with one or more bytes, +then the condition is true and the text from that point +until a matched @code{ELIF}, @code{ELSE} or @code{ENDIF} is emitted. +@code{ELIF} introduces a conditional alternative if the @code{IF} +clause evaluated FALSE and @code{ELSE} introduces an unconditional +alternative. + +@example +[+IF <full-expression> +] +emit things that are for the true condition[+ + +ELIF <full-expression-2> +] +emit things that are true maybe[+ + +ELSE "This may be a comment" +] +emit this if all but else fails[+ + +ENDIF "This may *also* be a comment" +] +@end example + +@noindent +@code{<full-expression>} may be any expression described in the +@code{EXPR} expression function, including the use of apply-codes +and value-names. If the expression yields an empty string, it +is interpreted as @i{false}. + +@node INCLUDE +@subsection INCLUDE - Read in and emit a template block + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/functions.c line 179. +@end ignore + +@findex INCLUDE + +The entire contents of the named file is inserted at this point. +The contents of the file are processed for macro expansion. The +arguments are eval-ed, so you may compute the name of the file to +be included. The included file must not contain any incomplete +function blocks. Function blocks are template text beginning with +any of the macro functions @samp{CASE}, @samp{DEFINE}, @samp{FOR}, +@samp{IF} and @samp{WHILE}; extending through their respective +terminating macro functions. + +@node INVOKE +@subsection INVOKE - Invoke a User Defined Macro + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcDef.c line 659. +@end ignore + +@findex INVOKE + +User defined macros may be invoked explicitly or implicitly. +If you invoke one implicitly, the macro must begin with the +name of the defined macro. Consequently, this may @strong{not} +be a computed value. If you explicitly invoke a user defined macro, +the macro begins with the macro name @code{INVOKE} followed by +a @i{basic expression} that must yield a known user defined macro. +A macro name _must_ be found, or AutoGen will issue a diagnostic +and exit. + +Arguments are passed to the invoked macro by name. +The text following the macro name must consist of a series of +names each of which is followed by an equal sign (@code{=}) and +a @i{basic expression} that yields a string. + +The string values may contain template macros that are parsed +the first time the macro is processed and evaluated again every +time the macro is evaluated. + +@node RETURN +@subsection RETURN - Leave an INVOKE-d (DEFINE) macro + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/functions.c line 95. +@end ignore + +@findex RETURN + +This will unwind looping constructs inside of a DEFINE-d macro and +return to the invocation point. The output files and diversions +@i{are left alone}. This means it is unwise to start diversions +in a DEFINEd macro and RETURN from it before you have handled the +diversion. Unless you are careful. Here is some rope for you. +Please be careful using it. + +@node SELECT +@subsection SELECT - Selection block for CASE function + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcCase.c line 1218. +@end ignore + +@findex SELECT + +This macro selects a block of text by matching an expression +against the sample text expression evaluated in the @code{CASE} +macro. @xref{CASE}. + +You do not specify a @code{SELECT} macro with the word ``select''. +Instead, you must use one of the 19 match operators described in +the @code{CASE} macro description. + +@node UNKNOWN +@subsection UNKNOWN - Either a user macro or a value name. + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/functions.c line 243. +@end ignore + +@findex UNKNOWN + +The macro text has started with a name not known to AutoGen. If, at run +time, it turns out to be the name of a defined macro, then that macro is +invoked. If it is not, then it is a conditional expression that is +evaluated only if the name is defined at the time the macro is invoked. + +You may not specify @code{UNKNOWN} explicitly. + +@node WHILE +@subsection WHILE - Conditionally loop over a Template Block + +@ignore +Generated from auto_gen.tpl line 580. +Extracted from /u/bkorb/tools/ag/autogen-bld/agen5/funcIf.c line 179. +@end ignore + +@findex WHILE +@cindex conditional emit +@cindex while test + +Conditionally repeated block. Its arguments are evaluated (@pxref{EXPR}) +and as long as the result is non-zero or a string with one or more bytes, +then the condition is true and the text from that point +until a matched @code{ENDWHILE} is emitted. + +@example +[+WHILE <full-expression> +] +emit things that are for the true condition[+ + +ENDWHILE +] +@end example + +@noindent +@code{<full-expression>} may be any expression described in the +@code{EXPR} expression function, including the use of apply-codes +and value-names. If the expression yields an empty string, it +is interpreted as @i{false}. +@node shell command +@subsection Inserting text from a shell script + +If the text between the start and end macro markers starts with an opening +curly brace ('@code{@{}') or is surrounded by back quotes ('@code{`}'), then +the text is handed off to the server shell for evaluation. The output to +standard out is inserted into the document. If the text starts with the +curly brace, all the text is passed off as is to the shell. If surrounded by +back quotes, then the string is ``cooked'' before being handed off to the +shell. + +@node guile command +@subsection Inserting text from a scheme script + +If the text between the start and end macro markers starts with a semi-colon +or an opening parenthesis, all the text is handed off to the Guile/scheme +processor. If the last result is text or a number, it is added (as text) +to the output document. + +@ignore +START == AUGMENTING == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@c === SECTION MARKER + +@node output controls +@section Redirecting Output +@cindex Redirecting Output +@cindex diversion + +AutoGen provides a means for redirecting the template output to different +files or, in @file{M4} parlance, to various diversions. It is accomplished +by providing a set of Scheme functions named @code{out-*} +(@pxref{AutoGen Functions}). + +@table @samp +@item out-push-new (@pxref{SCM out-push-new}) +This allows you to logically "push" output files onto a stack. +If you supply a string name, then a file by that name is created +to hold the output. If you do not supply a name, then the text is +written to a scratch pad and retrieved by passing a @code{#t} argument +to the @code{out-pop} (@pxref{SCM out-pop}) function. + +@item out-pop (@pxref{SCM out-pop}) +This function closes the current output file and resumes output to the next +one in the stack. At least one output must have been pushed onto the output +stack with the @code{out-push-new} (@pxref{SCM out-push-new}) function. If +@code{#t} is passed in as an argument, then the entire contents of the +diversion (or file) is returned. + +@item out-suspend (@pxref{SCM out-suspend}) +This function does not close the current output, but instead sets it aside +for resumption by the given name with @code{out-resume}. The current output +must have been pushed on the output queue with @code{out-push-new} +(@pxref{SCM out-push-new}). + +@item out-resume (@pxref{SCM out-resume}) +This will put a named file descriptor back onto the top of +stack so that it becomes the current output again. + +@item out-switch (@pxref{SCM out-switch}) +This closes the current output and creates a new file, +purging any preexisting one. This is a shortcut for "pop" +followed by "push", but this can also be done at the base level. + +@item out-move (@pxref{SCM out-move}) +Renames the current output file without closing it. +@end table + +There are also several functions for determining the output +status. @xref{AutoGen Functions}. + +@ignore + +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +@end ignore + +@page +@node Augmenting AutoGen +@chapter Augmenting AutoGen Features +@cindex Augmenting AutoGen + +AutoGen was designed to be simple to enhance. You can do it by +providing shell commands, Guile/Scheme macros or callout functions +that can be invoked as a Guile macro. Here is how you do these. + +@menu +* shell commands:: Shell Output Commands +* guile macros:: Guile Macros +* guile callouts:: Guile Callout Functions +* AutoGen macros:: AutoGen Macros +@end menu + +@c === SECTION MARKER + +@node shell commands +@section Shell Output Commands + +Shell commands are run inside of a server process. This means that, +unlike @file{make}, context is kept from one command to the next. +Consequently, you can define a shell function in one place inside of +your template and invoke it in another. You may also store values +in shell variables for later reference. If you load functions from +a file containing shell functions, they will remain until AutoGen exits. + +If your shell script should determine that AutoGen should stop +processing, the recommended method for stopping AutoGen is: +@example +die "some error text" +@end example + +@noindent +That is a shell function added by AutoGen. It will send a SIGTERM +to autogen and exit from the "persistent" shell. + +@c === SECTION MARKER + +@node guile macros +@section Guile Macros + +Guile also maintains context from one command to the next. This means you may +define functions and variables in one place and reference them elsewhere. +If your Scheme script should determine that AutoGen should stop +processing, the recommended method for stopping AutoGen is: +@example +(error "some error text") +@end example + +@c === SECTION MARKER + +@node guile callouts +@section Guile Callout Functions + +Callout functions must be registered with Guile to work. This can +be accomplished either by putting your routines into a shared library +that contains a @code{void scm_init(void)} routine that registers +these routines, or by building them into AutoGen. + +To build them into AutoGen, you must place your routines in the source +directory and name the files @file{exp*.c}. You also must have a stylized +comment that @file{getdefs} can find that conforms to the following: + +@example +/*=gfunc <function-name> + * + * what: <short one-liner> + * general_use: + * string: <invocation-name-string> + * exparg: <name>, <description> [, ['optional'] [, 'list']] + * doc: A long description telling people how to use + * this function. +=*/ +SCM +ag_scm_<function-name>( SCM arg_name[, ...] ) +@{ <code> @} +@end example + +@table @samp +@item gfunc +You must have this exactly thus. + +@item <function-name> +This must follow C syntax for variable names + +@item <short one-liner> +This should be about a half a line long. +It is used as a subsection title in this document. + +@item general_use: +You must supply this unless you are an AutoGen maintainer and are writing +a function that queries or modifies the state of AutoGen. + +@item <invocation-name-string> +Normally, the @var{function-name} string will be transformed into +a reasonable invocation name. However, that is not always true. +If the result does not suit your needs, then supply an alternate string. + +@item exparg: +You must supply one for each argument to your function. +All optional arguments must be last. +The last of the optional arguments may be a list, if you choose. + +@item doc: +Please say something meaningful. + +@item [, ...] +Do not actually specify an ANSI ellipsis here. You must provide +for all the arguments you specified with @var{exparg}. +@end table + +See the Guile documentation for more details. +More information is also available in a large comment at the +beginning of the @file{agen5/snarf.tpl} template file. + +@c === SECTION MARKER + +@node AutoGen macros +@section AutoGen Macros + +There are two kinds@: those you define yourself and AutoGen native. +The user-defined macros may be defined in your templates, +@xref{DEFINE}. + +As for AutoGen native macros, do not add any. It is easy to do, but I +won't like it. The basic functions needed to accomplish looping over +and selecting blocks of text have proved to be sufficient over a period +of several years. New text transformations can be easily added via any +of the AutoGen extension methods, as discussed above. + +@ignore +END == AUGMENTING == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore +@ignore + +Invocation section from invoke-autogen.texi + +@end ignore +@page + +@include invoke-autogen.texi + +@ignore +START == INSTALLATION == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@page +@node Installation +@chapter Configuring and Installing + +@menu +* configuring:: Configuring AutoGen +* AutoGen CGI:: AutoGen as a CGI server +* signal names:: Signal Names +* installing:: Installing AutoGen +@end menu + +@c === SECTION MARKER + +@node configuring +@section Configuring AutoGen +@cindex configuring + +AutoGen is configured and built using Libtool, Automake and Autoconf. +Consequently, you can install it wherever you wish using the @samp{--prefix} +and other options. To the various configuration options supplied by these +tools, AutoGen adds a few of its own: + +@table @samp +@item --disable-shell +AutoGen is now capable of acting as a CGI forms server, @xref{AutoGen CGI}. +As such, it will gather its definitions using either @samp{GET} or +@samp{POST} methods. All you need to do is have a template named +@file{cgi.tpl} handy or specify a different one with a command line +option. + +However, doing this without disabling the server shell brings +considerable risk. If you were to pass user input to a script +that contained, say, the classic "@samp{`rm -rf /`}", you might have +a problem. This configuration option will cause shell template +commands to simply return the command string as the result. +No mistakes. Much safer. Strongly recommended. +The default is to have server shell scripting enabled. + +Disabling the shell will have some build side effects, too. + +@itemize @bullet +@item +Many of the make check tests will fail, since they assume +a working server shell. +@item +The getdefs and columns programs are not built. +The options are distributed as definition files and they +cannot be expanded with a shell-disabled AutoGen. +@item +Similarly, the documentation cannot be regenerated because +the documentation templates depend on subshell functionality. +@end itemize + +@item --enable-debug +Turning on AutoGen debugging enables very detailed inspection of +the input definitions and monitoring shell script processing. +These options are not particularly useful to anyone not directly +involved in maintaining AutoGen. If you do choose to enable AutoGen +debugging, be aware that the usage page was generated without these +options, so when the build process reaches the documentation rebuild, +there will be a failure. @samp{cd} into the @file{agen5} build +directory, @samp{make} the @samp{autogen.texi} file and all will +be well thereafter. + +@item --with-regex-header +@itemx --with-header-path +@itemx --with-regex-lib +These three work together to specify how to compile with and link to a +particular POSIX regular expression library. The value for +@file{--with-regex-header=value} must be the name of the relevant header file. +The AutoGen sources will attempt to include that source with a +@code{#include <value>} C preprocessing statement. The @var{path} from the +@option{--with-header-path=path} will be added to @code{CPPFLAGS} as +@option{-Ipath}. The @var{lib-specs} from @option{--with-regex-lib=lib-specs} +will be added to @code{LDFLAGS} without any adornment. +@end table + +@c === SECTION MARKER + +@page +@node AutoGen CGI +@section AutoGen as a CGI server + +AutoGen is now capable of acting as a CGI forms server. +It behaves as a CGI server if the definitions input is from stdin +and the environment variable @env{REQUEST_METHOD} is defined +and set to either "GET" or "POST". If set to anything else, +AutoGen will exit with a failure message. When set to one of those +values, the CGI data will be converted to AutoGen definitions +(@pxref{Definitions File}) and the template named "@file{cgi.tpl}" +will be processed. + +This works by including the name of the real template to process +in the form data and having the "@file{cgi.tpl}" template include +that template for processing. I do this for processing the form +@url{http://autogen.sourceforge.net/conftest.html}. The "@file{cgi.tpl}" +looks approximately like this: + +@example +<? AutoGen5 Template ?> +<? +IF (not (exist? "template")) ?><? + form-error ?><? + +ELIF (=* (get "template") "/") ?><? + form-error ?><? + +ELIF (define tpl-file (string-append "cgi-tpl/" + (get "template"))) + (access? tpl-file R_OK) ?><? + INCLUDE (. tpl-file) ?><? + +ELIF (set! tpl-file (string-append tpl-file ".tpl")) + (access? tpl-file R_OK) ?><? + INCLUDE (. tpl-file) ?><? + +ELSE ?><? + form-error ?><? +ENDIF ?> +@end example + +@noindent +This forces the template to be found in the "@file{cgi-tpl/}" +directory. Note also that there is no suffix specified in the +pseudo macro (@pxref{pseudo macro}). That tells AutoGen to emit +the output to @file{stdout}. + +The output is actually spooled until it is complete so that, +in the case of an error, the output can be discarded and a proper +error message can be written in its stead. + +@strong{Please also note} that it is advisable, @emph{especially} for network +accessible machines, to configure AutoGen (@pxref{configuring}) with +shell processing disabled (@option{--disable-shell}). That will make it +impossible for any referenced template to hand data to a subshell for +interpretation. + +@c === SECTION MARKER + +@node signal names +@section Signal Names +@cindex Signal Names + +When AutoGen is first built, it tries to use @code{psignal(3)}, +@code{sys_siglist}, @code{strsigno(3)} and @code{strsignal(3)} from the +host operating system. If your system does not supply these, the +AutoGen distribution will. However, it will use the distributed mapping +and this mapping is unlikely to match what your system uses. This can +be fixed. Once you have installed autogen, the mapping can be rebuilt +on the host operating system. To do so, you must perform the +following steps: + +@enumerate +@item +Build and install AutoGen in a place where it will be found in your +search path. +@item +@file{cd $@{top_srcdir@}/compat} +@item +@samp{autogen strsignal.def} +@item +Verify the results by examining the @file{strsignal.h} file produced. +@item +Re-build and re-install AutoGen. +@end enumerate + +If you have any problems or peculiarities that cause this process to +fail on your platform, please send me copies of the header files +containing the signal names and numbers, along with the full path names +of these files. I will endeavor to fix it. There is a shell script +inside of @file{strsignal.def} that tries to hunt down the information. + +@c === SECTION MARKER + +@node installing +@section Installing AutoGen +@cindex Installing + +There are several files that get installed. The number depend +whether or not both shared and archive libraries are to be +installed. The following assumes that everything is installed +relative to @env{$prefix}. You can, of course, use +@command{configure} to place these files where you wish. + +@strong{NB}@: AutoGen does not contain any compiled-in path names. +All support directories are located via option processing, +the environment variable @env{HOME} or finding the directory where +the executable came from. + +The installed files are: + +@enumerate +@item +The executables in @file{bin} (autogen, getdefs and columns). + +@item +The AutoOpts link libraries as @file{lib/libopts.*}. + +@item +An include file in @file{include/options.h}, needed for +Automated Option Processing (see next chapter). + +@item +Several template files and a scheme script in @file{share/autogen}, needed +for Automated Option Processing (@pxref{AutoOpts}), parsing definitions +written with scheme syntax (@pxref{Dynamic Text}), the templates for +producing documentation for your program (@pxref{documentation attributes}), +autoconf test macros, and AutoFSM. + +@item +Info-style help files as @file{info/autogen.info*}. +These files document AutoGen, the option processing +library AutoOpts, and several add-on components. + +@item +The three man pages for the three executables are installed in man/man1. +@end enumerate + +This program, library and supporting files can be installed +with three commands: + +@itemize @bullet +@item +<src-dir>/configure [ <configure-options> ] +@item +make +@item +make install +@end itemize + +However, you may wish to insert @samp{make check} +before the @samp{make install} command. + +If you do perform a @samp{make check} and there are any failures, you +will find the results in @file{<module>/test/FAILURES}. Needless to say, I +would be interested in seeing the contents of those files and any +associated messages. If you choose to go on and analyze one of these +failures, you will need to invoke the test scripts individually. You +may do so by specifying the test (or list of test) in the TESTS make +variable, thus: + +@example +gmake TESTS=test-name.test check +@end example + +I specify @command{gmake} because most makes will not let you override +internal definitions with command line arguments. @command{gmake} does. + +All of the AutoGen tests are written to honor the contents of the +@t{VERBOSE} environment variable. Normally, any commentary generated +during a test run is discarded unless the @t{VERBOSE} environment +variable is set. So, to see what is happening during the test, you +might invoke the following with @i{bash} or @i{ksh}: + +@example +VERBOSE=1 gmake TESTS="for.test forcomma.test" check +@end example + +@noindent +Or equivalently with @i{csh}: + +@example +env VERBOSE=1 gmake TESTS="for.test forcomma.test" check +@end example + +@ignore +END == INSTALLATION == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore +@page +@node AutoOpts +@chapter Automated Option Processing +@cindex autoopts + +AutoOpts 42.1 is bundled with AutoGen. It is a tool that virtually eliminates the +hassle of processing options and keeping man pages, info docs and usage text +up to date. This package allows you to specify several program attributes, +thousands of option types and many option attributes. From this, it then +produces all the code necessary to parse and handle the command line and +configuration file options, and the documentation that should go with your +program as well. +@ignore +START == AUTOOPTS == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +All the features notwithstanding, some applications simply have +well-established command line interfaces. Even still, those programs +may use the configuration file parsing portion of the library. +See the ``AutoOpts Features'' and ``Configuration File Format'' sections. + +@menu +* Features:: AutoOpts Features +* Licensing:: AutoOpts Licensing +* Caveats:: Developer and User Notes +* Quick Start:: Quick Start +* Option Definitions:: Option Definitions +* AutoOpts API:: Programmatic Interface +* Multi-Threading:: Multi-Threading +* option descriptor:: Option Descriptor File +* Using AutoOpts:: Using AutoOpts +* Presetting Options:: Configuring your program +* Config File Format:: Configuration File Format +* shell options:: AutoOpts for Shell Scripts +* AutoInfo:: Automated Info Docs +* AutoMan pages:: Automated Man Pages +* getopt_long:: Using getopt(3C) +* i18n:: Internationalizing AutoOpts +* Naming Conflicts:: Naming Conflicts +* All Attribute Names:: All Attribute Names +* Option Define Names:: Option Definition Name Index +@end menu + +@c === SECTION MARKER + +@node Features +@section AutoOpts Features +@cindex features + +AutoOpts supports option processing; option state saving; and +program documentation with innumerable features. Here, we list +a few obvious ones and some important ones, but the full list is +really defined by all the attributes defined in the @ref{Option Definitions} +section. + +@enumerate +@item +POSIX-compliant short (flag) option processing. + +@item +GNU-style long options processing. Long options +are recognized without case sensitivity, and they may be abbreviated. + +@item +Environment variable initializations, @xref{environrc}. + +@item +Initialization from configuration files (aka RC or INI files), and +saving the option state back into one, @xref{loading rcfile}. + +@item +Config files may be partitioned. One config file may be used by several +programs by partitioning it with lines containing, +@code{[PROGRAM_NAME]} or @code{<?program-name>}, @xref{loading rcfile}. + +@item +Config files may contain AutoOpts directives. +@code{<?auto-options [[option-text]]>} +may be used to set @code{AutoOpts} option processing options. +Viz., @acronym{GNU} usage layout versus @code{AutoOpts} conventional layout, +and @code{misuse-usage} versus @code{no-misuse-usage}, @xref{usage attributes}. + +@item +Options may be marked as @code{@i{dis}-abled} with a disablement prefix. +Such options may default to either an enabled or a disabled state. You +may also provide an enablement prefix, too, e.g., @option{--allow-mumble} +and @option{--prevent-mumble} (@pxref{Common Attributes}). + +@item +Verify that required options are present between the minimum and maximum +number of times on the command line. Verify that conflicting options do not +appear together. Verify that options requiring the presence of other options +are, in fact, used in the presence of other options. +See @xref{Common Attributes}, and @xref{Option Conflict Attributes}. + +@item +There are several @ref{automatic options, automatically supported options}. +They will have short flags if any options have option flags and the flags +are not suppressed. The associated flag may be altered or suppressed by +specifying no value or an alternate character for @code{xxx-value;} in +the option definition file. @code{xxx} is the name of the option below: + +@table @samp +@item --help +@itemx --more-help +These are always available. @samp{--more-help} will pass the full usage +text through a pager. +@item --usage +@vindex usage-opt +This is added to the option list if @code{usage-opt} is specified. +It yields the abbreviated usage to @file{stdout}. +@item --version +This is added to the option list if @code{version = xxx;} is specified. +@item --load-opts +@itemx --save-opts +These are added to the option list if @code{homerc} is specified. Mostly. +If, @code{disable-save} is specified, then @option{--save-opts} is disabled. +@end table + +@item +Various forms of main procedures can be added to the output, +@xref{Generated main}. There are four basic forms: + +@enumerate a +@item +A program that processes the arguments and writes to standard out +portable shell commands containing the digested options. + +@item +A program that will generate portable shell commands to parse the defined +options. The expectation is that this result will be copied into a +shell script and used there. + +@item +A @code{for-each} main that will invoke a named function once for either +each non-option argument on the command line or, if there are none, +then once for each non-blank, non-comment input line read from stdin. + +@item +A main procedure of your own design. Its code can be supplied in the +option description template or by incorporating another template. +@end enumerate + +@item +There are several methods for handling option arguments. +@itemize @bullet +@item +nothing (@pxref{OPT_ARG}) option argument strings are globally available. +@item +user supplied (@pxref{Option Argument Handling}) +@item +stack option arguments (@pxref{Option Argument Handling}) +@item +integer numbers (@pxref{arg-type number}) +@item +true or false valued (@pxref{arg-type boolean}) +@item +enumerated list of names (@pxref{arg-type keyword}) +@item +an enumeration (membership) set (@pxref{arg-type set membership}) +@item +a list of name/value pairs (option @code{subopts}) +(@pxref{arg-type hierarchy}) +@item +a time duration or a specific time and date +@item +validated file name (@pxref{arg-type file name}) +@item +optional option argument (@pxref{arg-optional}) +@end itemize + +@item +The generated usage text can be emitted in either AutoOpts standard format +(maximizing the information about each option), or GNU-ish normal form. The +default form is selected by either specifying or not specifying the +@code{gnu-usage} attribute (@pxref{information attributes}). This can be +overridden by the user himself with the @env{AUTOOPTS_USAGE} environment +variable. If it exists and is set to the string @samp{gnu}, it will force +GNU-ish style format; if it is set to the string @samp{autoopts}, it will +force AutoOpts standard format; otherwise, it will have no effect. + +@item +The usage text and many other strings are stored in a single character array +(@pxref{SCM string-table-new,string table functions}). This reduces fixup +costs when loading the program or library. The downside is that if GCC +detects that any of these strings are used in a printf format, you may get the +warning, @code{embedded '\0' in format}. To eliminate the warning, you must +provide GCC with the @option{-Wno-format-contains-nul} option. + +@item +If you compile with @code{ENABLE_NLS} defined and @code{_()} defined to a +localization function (e.g. @code{gettext(3GNU)}), then the option processing +code will be localizable (@pxref{i18n}). Provided also that you do not define +the @code{no-xlate} attribute to @emph{anything} +(@pxref{presentation attributes}). + +You should also ensure that the @code{ATTRIBUTE_FORMAT_ARG()} gets +@code{#define}-ed to something useful. There is an autoconf macro +named @code{AG_COMPILE_FORMAT_ARG} in @file{ag_macros.m4} that will +set it appropriately for you. If you do not do this, then translated +formatting strings may trigger GCC compiler warnings. + +@item +Provides a callable routine to parse +a text string as if it were from one of the rc/ini/config files, +hereafter referred to as a configuration file. + +@item +By adding a @samp{doc} and @samp{arg-name} attributes to each option, +AutoGen will also be able to produce a man page and the @samp{invoking} +section of a texinfo document. + +@item +Intermingled option processing. AutoOpts options may be intermingled with +command line operands and options processed with other parsing techniques. +This is accomplished by setting the @code{allow-errors} +(@pxref{program attributes}) attribute. When processing reaches a point +where @code{optionProcess} (@pxref{libopts-optionProcess}) needs to be called +again, the current option can be set with @code{RESTART_OPT(n)} +(@pxref{RESTART_OPT}) before calling @code{optionProcess}. + +See: @xref{library attributes}. + +@item +Library suppliers can specify command line options that their +client programs will accept. They specify option definitions +that get @code{#include}-d into the client option definitions +and they specify an "anchor" option that has a callback and must be invoked. +That will give the library access to the option state for their options. + +@item +library options. An AutoOpt-ed library may export its options for use in +an AutoOpt-ed program. This is done by providing an option definition file +that client programs @code{#include} into their own option definitions. +See ``AutoOpt-ed Library for AutoOpt-ed Program'' (@pxref{lib and program}) +for more details. +@end enumerate + +@c === SECTION MARKER + +@node Licensing +@section AutoOpts Licensing +@cindex Licensing + +When AutoGen is installed, the AutoOpts project is installed with it. +AutoOpts includes various AutoGen templates and a pair of shared +libraries. These libraries may be used under the terms of version 3 +of the GNU Lesser General Public License (LGPL). + +One of these libraries (@code{libopts}) is needed by programs that are built +using AutoOpts generated code. This library is available as a separate +``tear-off'' source tarball. It is redistributable for use under either of +two licenses: The above mentioned GNU Lesser General Public License, and +the advertising-clause-free BSD license. Both of these license terms are +incorporated into appropriate COPYING files included with the @code{libopts} +source tarball. This source may be incorporated into your package with +the following simple commands: + +@example +rm -rf libopts libopts-* +gunzip -c `autoopts-config libsrc` | \ + tar -xvf - +mv libopts-*.*.* libopts +@end example + +View the @file{libopts/README} file for further integration information. + +@c === SECTION MARKER + +@page +@node Caveats +@section Developer and User Notes + +The formatting of the usage message can be controlled with the use of the +@env{AUTOOPTS_USAGE} environment variable. If it contains any of five +possible comma separated values, it will affect @file{libopts} behavior. +Any extraneous or conflicting data will cause its value to be ignored. + +If the program attributes @code{long-usage} and @code{short-usage} have been +specified (@pxref{usage attributes,Usage and Version Info Display}), these +strings are used for displaying full usage and abbreviated usage. +``Full usage'' is used when usage is requested, ``abbreviated usage'' +when a usage error is detected. If these strings are not provided, +the usage text is computed. + +The @env{AUTOOPTS_USAGE} environment variable may be set to the comma and/or +white space separated list of the following strings: + +@table @samp +@item compute +Ignore the provision of @code{long-usage} and @code{short-usage} attributes, +and compute the usage strings. This is useful, for example, if you wish to +regenerate the basic form of these strings and either tweak them or translate +them. The methods used to compute the usage text are not suitable for +translation. + +@item gnu +@cindex gnu +The format of the usage text will be displayed in GNU-normal form. +The default display for @option{--version} will be to include a note +on licensing terms. + +@item autoopts +@cindex autoopts +The format of the extended usage will be in AutoOpts' native layout. The +default version display will be one line of text with the last token the +version. @code{gnu} and @code{autoopts} conflict and may not be used +together. + +@item no-misuse-usage +@cindex no-misuse-usage +When an option error is made on the command line, the abbreviated usage text +will be suppressed. An error message and the method for getting full usage +information will be displayed. + +@item misuse-usage +@cindex misuse-usage +When an option error is made on the command line, the abbreviated usage text +will be shown. @code{misuse-usage} and @code{no-misuse-usage} conflict and +may not be used together. +@end table + +@code{misuse-usage} and @code{autoopts} are the defaults. +These defaults may be flipped to @code{no-misuse-usage} and @code{gnu} +by specifying @code{gnu-usage} and @code{no-misuse-usage} +program attributes, respectively, in the option definition file. + +@noindent +@i{Note for developers}: + +The templates used to implement AutoOpts depend heavily upon token pasting. +That mens that if you name an option, @code{debug}, for example, the generated +header will expect to be able to emit @code{#define} macros such as this: +@example +#define DESC(n) (autogenOptions.pOptDesc[INDEX_OPT_## n]) +@end example +and expect @code{DESC(DEBUG)} to expand correctly into +@code{(autogenOptions.pOptDesc[INDEX_OPT_DEBUG])}. +If @code{DEBUG} is @code{#defined} to something else, then +that something else will be in the above expansion. + +If you discover you are having strange problems like this, +you may wish to use some variation of the @code{guard-option-names} +@xref{program attributes}. + +@c === SECTION MARKER + +@page +@node Quick Start +@section Quick Start +@cindex example, simple AutoOpts + +Since it is generally easier to start with a simple example than it is +to look at the options that AutoGen uses itself, here is a very simple +AutoOpts example. You can copy this example out of the Info file and +into a source file to try it. You can then embellish it into what you +really need. For more extensive examples, you can also examine the help +output and option definitions for the commands @command{columns}, +@command{getdefs} and @command{autogen} itself. + +If you are looking for a more extensive example, +you may search the autogen sources for files named @file{*opts.def}. +@command{xml2ag} is ridiculous and @command{autogen} is very lengthy, +but @command{columns} and @command{getdefs} are not too difficult. +The @command{sharutils} sources are fairly reasonable, too. + +@menu +* quick ao problem:: Example option requirements +* quick ao def:: Example option definitions +* quick ao build:: Build the example options +* quick ao help:: Example option help text +* quick ao usage:: Using the example options +* quick ao docs:: Example option documentation +@end menu + +@node quick ao problem +@subsection Example option requirements + +For our simple example, assume you have a program named @command{check} +that takes two options: + +@enumerate +@item +A list of directories to check over for whatever it is @command{check} does. +You want this option available as a POSIX-style flag option +and a GNU long option. You want to allow as many of these +as the user wishes. +@item +An option to show or not show the definition tree being used. +Only one occurrence is to be allowed, specifying one or the other. +@end enumerate + +@node quick ao def +@subsection Example option definitions + +@noindent +First, specify your program attributes and its options to AutoOpts, +as with the following example. + +@example +@ignore +END == AUTOOPTS == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore +AutoGen Definitions options; +prog-name = check; +prog-title = "Checkout Automated Options"; +long-opts; +gnu-usage; /* GNU style preferred to default */ + +main = @{ main-type = shell-process; @}; + +flag = @{ + name = check-dirs; + value = L; /* flag style option character */ + arg-type = string; /* option argument indication */ + max = NOLIMIT; /* occurrence limit (none) */ + stack-arg; /* save opt args in a stack */ + descrip = "Checkout directory list"; + doc = 'name of each directory that is to be "checked out".'; +@}; + +flag = @{ + name = show_defs; + descrip = "Show the definition tree"; + disable = dont; /* mark as enable/disable type */ + /* option. Disable as `dont-' */ + doc = 'disable, if you do not want to see the tree.'; +@}; +@end example + +@node quick ao build +@subsection Build the example options + +This program will produce a program that digests its options and +writes the values as shell script code to stdout. +Run the following short script to produce this program: +@example +base=check +BASE=`echo $base | tr '[a-z-]' '[A-Z_]'` +cflags="-DTEST_$@{BASE@} `autoopts-config cflags`" +ldflags="`autoopts-config ldflags`" +autogen $@{base@}.def +cc -o $@{base@} -g $@{cflags@} $@{base@}.c $@{ldflags@} +./$@{base@} --help +@end example + +@node quick ao help +@subsection Example option help text + +Running the build commands yields: + +@example + +exit 0 +@end example +@ignore +START == AUTOOPTS-MAIN == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@node quick ao usage +@subsection Using the example options + +Normally, however, you would not use the @code{main} clause. Instead, +the file would be named something like @file{checkopt.def}, you would +compile @file{checkopt.c} the usual way, and link the object with the rest +of your program. + +The options are processed by calling @code{optionProcess} +(@pxref{libopts-optionProcess}): + +@example +main( int argc, char** argv ) +@{ + @{ + int optct = optionProcess( &checkOptions, argc, argv ); + argc -= optct; + argv += optct; + @} +@end example + +The options are tested and used as in the following fragment. +@code{ENABLED_OPT} is used instead of @code{HAVE_OPT} for the +@option{--show-defs} option because it is an enabled/disabled option type: + +@example + if ( ENABLED_OPT( SHOW_DEFS ) + && HAVE_OPT( CHECK_DIRS )) @{ + int dirct = STACKCT_OPT( CHECK_DIRS ); + char** dirs = STACKLST_OPT( CHECK_DIRS ); + while (dirct-- > 0) @{ + char* dir = *dirs++; + ... +@end example + +@node quick ao docs +@subsection Example option documentation + +The @code{doc} clauses are used in the flag stanzas for man pages and texinfo +invoking documentation. With the definition file described above, the two +following commands will produce the two documentation files @file{check.1} and +@file{invoke-check.texi}. The latter file will be generated as a chapter, +rather than a section or subsection. + +@example +autogen -Tagman-cmd check.def +autogen -DLEVEL=chapter -Tagtexi-cmd -binvoke-check.texi check.def +@end example + +@noindent +The result of which is left as an exercise for the reader. + +A lot of magic happens to make this happen. +The rest of this chapter will describe the myriad of option attributes +supported by AutoOpts. However, keep in mind that, in general, you won't +need much more than what was described in this "quick start" section. + +@node Option Definitions +@section Option Definitions +@cindex Option Definitions + +AutoOpts uses an AutoGen definitions file for the definitions of the +program options and overall configuration attributes. +The complete list of program and option attributes is quite extensive, +so if you are reading to understand how to use AutoOpts, I recommend +reading the "Quick Start" section (@pxref{Quick Start}) and paying +attention to the following: + +@enumerate +@item +@code{prog-name}, @code{prog-title}, and @code{argument}, program +attributes, @xref{program attributes}. +@item +@code{name} and @code{descrip} option attributes, @xref{Required Attributes}. +@item +@code{value} (flag character) and @code{min} (occurrence counts) +option attributes, @xref{Common Attributes}. +@item +@code{arg-type} from the option argument specification section, +@xref{Option Arguments}. +@item +Read the overall how to, @xref{Using AutoOpts}. +@item +Highly recommended, but not required, are the several "man" and +"info" documentation attributes, @xref{documentation attributes}. +@end enumerate + +Keep in mind that the majority are rarely used and can be safely +ignored. However, when you have special option processing requirements, +the flexibility is there. + +@menu +* program attributes:: Program Description Attributes +* library attributes:: Options for Library Code +* information attributes:: Program Information Attributes +* Generated main:: Generating main procedures +* option attributes:: Option Attributes +* Option Arguments:: Option Argument Specification +* Option Argument Handling:: Option Argument Handling +* Internationalizing Options:: Internationalizing Options +* documentation attributes:: Man and Info doc Attributes +* automatic options:: Automatically Supported Options +* standard options:: Library of Standard Options +@end menu + +@node program attributes +@subsection Program Description Attributes +@cindex program attributes + +The following global definitions are used to define attributes of the entire +program. These generally alter the configuration or global behavior of the +AutoOpts option parser. The first two are required of every program. The +third is required if there are to be any left over arguments (operands) +after option processing. The rest have been grouped below. Except as noted, +there may be only one copy of each of these definitions: + +@table @samp + +@item prog-name +@vindex prog-name +This attribute is required. Variable names derived from this name +are derived using @code{string->c_name!} (@pxref{SCM string->c-name!}). + +@item prog-title +@vindex prog-title +This attribute is required and may be any descriptive text. + +@item argument +@vindex argument +This attribute is required if your program uses operand arguments. +It specifies the syntax of the arguments that @strong{follow} the options. +It may not be empty, but if it is not supplied, then option processing +must consume all the arguments. If it is supplied and starts with an +open bracket (@code{[}), then there is no requirement on the presence or +absence of command line arguments following the options. Lastly, if it +is supplied and does not start with an open bracket, then option +processing must @strong{not} consume all of the command line arguments. + +@item config-header +@vindex config-header +If your build has a configuration header, it must be included before +anything else. Specifying the configuration header file name with this +attribute will cause that to happen. +@end table + +@menu +* usage attributes:: Usage and Version Info Display +* config attributes:: Program Configuration +* programming attributes:: Programming Details +* presentation attributes:: User Presentation Attributes +@end menu + +@c +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +@c +@node usage attributes +@subsubsection Usage and Version Info Display + +These will affect the way usage is seen and whether or not version +information gets displayed. + +@table @samp +@item full-usage +@vindex full-usage +If this attribute is provided, it may specify the full length +usage text, or a variable name assignable to a @code{char const *} pointer, +or it may be empty. The meanings are determined by the length. +@itemize @bullet +@item +If not provided, the text will be computed as normal. +@item +If the length is zero, then the usage text will be derived from +the current settings and inserted as text into the generated .c file. +@item +If the length is 1 to 32 bytes, then it is presumed to be a variable +name that either points to or is an array of const chars. +@item +If it is longer than that, it is presumed to be the help text itself. +This text will be inserted into the generated .c file. +@end itemize + +This string should be readily translatable. Provision will be made +to translate it if this is provided, if the source code is compiled with +@code{ENABLE_NLS} defined, and @code{no-xlate} has not been set to the +value @emph{anything}. The untranslated text will be handed to +@code{dgettext("libopts", @i{txt})} and then @code{gettext(@i{txt})} +for translation, one paragraph at a time. + +To facilitate the creation and maintenance of this text, you can +force the string to be ignored and recomputed by specifying +@example +AUTOOPTS_USAGE=compute +@end example +@noindent +in the environment and requesting help or usage information. +See @xref{Caveats, Developer and User Notes}. + +@item short-usage +@vindex short-usage +If this attribute is provided, it is used to specify an abbreviated +version of the usage text. This text is constructed in the same way +as the @code{full-usage}, described above. + +@item gnu-usage +@vindex gnu-usage +AutoOpts normaly displays usage text in a format that provides more +information than the standard GNU layout, but that also means it is +not the standard GNU layout. This attribute changes the default to +GNU layout, with the @env{AUTOOPTS_USAGE} environment variable used +to request @code{autoopts} layout. +See @xref{Caveats, Developer and User Notes}. + +@item usage-opt +@vindex usage-opt +I apologize for too many confusing usages of usage. +This attribute specifies that @option{--usage} and/or @option{-u} be +supported. The help (usage) text displayed will be abbreviated +when compared to the default help text. + +@item no-misuse-usage +@vindex no-misuse-usage +When there is a command line syntax error, by default AutoOpts will +display the abbreviated usage text, rather than just a one line +``you goofed it, ask for usage'' message. You can change the default +behavior for your program by supplying this attribute. The user may +override this choice, again, with the @env{AUTOOPTS_USAGE} environment +variable. See @xref{Caveats, Developer and User Notes}. + +@item prog-group +@vindex prog-group +The version text in the @file{getopt.tpl} template will include this +text in parentheses after the program name, when this attribute is specified. +For example: +@example +mumble (stumble) 1.0 +@end example +@noindent +says that the @samp{mumble} program is version 1.0 and is part of the +@samp{stumble} group of programs. + +@item usage +@vindex usage +If your program has some cleanup work that must be done before exiting +on usage mode issues, or if you have to customize the usage message in +some way, specify this procedure and it will be called instead of the +default @code{optionUsage()} function. For example, if a program is +using the curses library and needs to invoke the usage display, then +you must arrange to call @code{endwin()} before invoking the library +function @code{optionUsage()}. This can be handled by specifying your +own usage function, thus: +@example +void +my_usage(tOptions * opts, int ex) +@{ + if (curses_window_active) + endwin(); + optionUsage(opts, ex); +@} +@end example + +@item version +@vindex version +Specifies the program version and activates the VERSION option, +@xref{automatic options}. +@end table + +@c +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +@c +@node config attributes +@subsubsection Program Configuration + +Programs may be ``pre-configured'' before normal command line options +are processed (See @pxref{Immediate Action, Immediate Action Attributes}). +How configuration files and environment variables are handled get +specified with these attributes. + +@table @samp +@item disable-load +@itemx disable-save +@vindex disable-load +@vindex disable-save +Indicates that the command line usage of @option{--load-opts} and/or +@option{--save-opts} are disallowed. + +@item environrc +@vindex environrc +Indicates looking in the environment for values of variables named, +@env{PROGRAM_OPTNAME} or @env{PROGRAM}, where @env{PROGRAM} is the +upper cased @var{C-name} of the program and @samp{OPTNAME} is the +upper cased @var{C-name} of a specific option. The contents of +the @env{PROGRAM} variable, if found, are tokenized and processed. +The contents of @env{PROGRAM_OPTNAME} environment variables are taken +as the option argument to the option nameed @option{--optname}. + +@item homerc +@vindex homerc +Specifies that option settings may be loaded from and stored into +configuration files. Each instance of this attribute is either a directory +or a file using a specific path, a path based on an environment variable or +a path relative to installation directories. The method used depends on +the name. If the one entry is empty, it enables the loading and storing of +settings, but no specific files are searched for. Otherwise, a series of +configuration files are hunted down and, if found, loaded. + +If the first character of the @samp{homerc} value is not the dollar +character (@code{$}), then it is presumed to be a path name based on the +current directory. Otherwise, the method depends on the second character: + +@table @code +@item $ +The path is relative to the directory where the executable was found. +@item @@ +The path is relative to the package data directory, e.g. +@file{/usr/local/share/autogen}. +@item [a-zA-Z] +The path is derived from the named environment variable. +@end table + +Use as many as you like. The presence of this attribute +activates the @option{--save-opts} and @option{--load-opts} options. +However, saving into a file may be disabled with the @samp{disable-save}. +@xref{loading rcfile}. +See the @code{optionMakePath(3AGEN)} man page for excruciating details. + +@item rcfile +@vindex rcfile +Specifies the configuration file name. This is only useful if you +have provided at least one @code{homerc} attribute. +@example +default: .<prog-name>rc +@end example + +@item vendor-opt +@vindex vendor-opt +This option implements the @option{-W} vendor option command line option. + +For POSIX specified utilities, the options are constrained to the options +that are specified by POSIX. Extensions should be handled with @option{-W} +command line options, the short flag form. Long option name processing +must be disabled. In fact, the @code{long-opts} attribute must not be +provided, and some options must be specified without flag values. + +The @option{-W long-name} is processed by looking up the long option +name that follows it. It cannot be a short flag because that would +conflict with the POSIX flag name space. It will be processed as if +long options were accepted and @option{--long-name} were found on the +command line. +@end table + +@c +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +@c +@node programming attributes +@subsubsection Programming Details + +These attributes affect some of the ways that the option data are +used and made available to the program. + +@table @samp +@item config-header +@vindex config-header +The contents of this attribute should be just the name of the configuration +file. A "#include" naming this file will be inserted at the top of the +generated header. + +@item exit-name +@itemx exit-desc +@vindex exit-name +@vindex exit-desc +These values should be defined as indexed values, thus: +@example +exit-name[0] = success; +exit-desc[0] = 'Successful program execution.'; +exit-name[1] = failure; +exit-desc[1] = 'The operation failed or command syntax was not valid.'; +@end example +By default, all programs have these effectively defined for them. +They may be overridden by explicitly defining any or all of these values. +Additional names and descriptions may be defined. +They will cause an enumeration to be emitted, like this one +for @command{getdefs}: +@example +typedef enum @{ + GETDEFS_EXIT_SUCCESS = 0, + GETDEFS_EXIT_FAILURE = 1 +@} getdefs_exit_code_t; +@end example +@noindent +which will be augmented by any @code{exit-name} definitions beyond @samp{1}. + +Some of the generated code will exit non-zero if there is an allocation error. +This exit will always be code @samp{1}, unless there is an exit named @samp{no_mem} +or @samp{nomem}. In that case, that value will be used. Additionally, if +there is such a value, and if @code{die-code} is specified, then a function +@code{nomem_err(size_t len, char const * what)} will be emitted as an inline +function for reporting out-of-memory conditions. + +@item usage-message +@vindex usage-message +This attribute will cause two procedures to be added to the code file: +@code{usage_message()} and @code{vusage_message()}, with any applicable prefix +(see @code{prefix}, below). They are declared in the +generated header, thus: +@example +noreturn extern void vusage_message(char const * fmt, va_list ap); +noreturn extern void usage_message(char const * fmt, ...); +@end example +@noindent +These functions print the message to @file{stderr} and invoke the usage +function with the exit code set to @code{1} (@code{EXIT_FAILURE}). + +@item die-code +@vindex die-code +This tells AutoOpts templates to emit code for @code{vdie()}, @code{die()}, +@code{fserr()}, and, possibly the @code{nomem_err()} functions. The latter is +emitted if an exit name of @samp{no-mem} or @samp{nomem} is specified. If the +@code{die-code} is assigned a text value, then that code will be inserted in +the @code{vdie} function immediately before it prints the death rattle +message. + +The profiles for these functions are: +@example +noreturn extern void vdie( int exit_code, char const * fmt, va_list); +noreturn extern void die( int exit_code, char const * fmt, ...); +noreturn extern void fserr(int exit_code, char const * op, char const * fname); +noreturn static inline void +nomem_err(size_t sz, char const * what) @{...@} +@end example + +@item export +@vindex export +This string is inserted into the .h interface file. Generally used for +global variables or @code{#include} directives required by +@code{flag-code} text and shared with other program text. +Do not specify your configuration header (@file{config.h}) in this +attribute or the @code{include} attribute. Instead, use +@code{config-header}, above. + +@item guard-option-names +@vindex guard-option-names +AutoOpts generates macros that presume that there are no @command{cpp} macros +with the same name as the option name. For example, if you have an option +named, @option{--debug}, then you must not use @code{#ifdef DEBUG} in your +code. If you specify this attribute, every option name will be guarded. If +the name is @code{#define}-d, then a warning will be issued and the name +undefined. If you do not specify this and there is a conflict, you will get +strange error messages. + +This attribute may be set to any of four recognized states: + +@itemize @bullet +@item +Not defined. AutoOpts will behave as described above. + +@item +Defined, but set to the empty string. Text will be emitted into the header +to undefine (@code{#undef}) any conflicting preprocessor macros. The code +will include compiler warnings (via @code{#warning}). Some compilers are +not ANSI-C-99 compliant yet and will error out on those warnings. You may +compile with @option{-DNO_OPTION_NAME_WARNINGS} to silence or mostly silence +them. + +@item +Defined and set to the string, @code{no-warning}. All of the needed +@code{#undef}s will be emitted, without any conflict checking @code{#warning} +directives emitted. + +@item +Defined and set to the string, @code{full-enum}. The option manipulation +preprocessor macros will not token paste the option names to the index +enumeration prefix. e.g. you will need to use @code{HAVE_OPT(INDEX_OPT_DEBUG)} +instead of @code{HAVE_OPT(DEBUG)}. +@end itemize + +@item include +@vindex include +This string is inserted into the .c file. Generally used for global +variables required only by @code{flag-code} program text. + +@item no-libopts +@vindex no-libopts +If you are going to handle your option processing with the @file{getopt.tpl} +template instead of using libopts, then specify this attribute. It will +suppress mention of @option{--more-help} in the generated documentation. +(@code{getopt_long} does not support @option{--more-help}.) + +@item prefix +@vindex prefix +This value is inserted into @strong{all} global names. This will +disambiguate them if more than one set of options are to be compiled +into a single program. +@end table + +@c +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +@c +@node presentation attributes +@subsubsection User Presentation Attributes + +Attributes that affect the user's experience. + +@table @samp +@item allow-errors +@vindex allow-errors +The presence of this attribute indicates ignoring any command line +option errors. This may also be turned on and off by invoking the +macros @code{ERRSKIP_OPTERR} and @code{ERRSTOP_OPTERR} from the +generated interface file. + +@item long-opts +@vindex long-opts +@cindex named option mode +Presence indicates GNU-standard long option processing. Partial name +matches are accepted, if they are at least two characters long and the +partial match is unique. The matching is not case sensitive, and the +underscore, hyphen and carat characters are all equivalent (they match). + +If any options do not have an option value (flag character) specified, +and least one does specify such a value, then you must specify +@code{long-opts}. If none of your options specify an option value +(flag character) and you do not specify @code{long-opts}, then command +line arguments are processed in "named option mode". This means that: + +@itemize @bullet +@item +Every command line argument must be a long option. +@item +The flag markers @option{-} and @option{--} are completely optional. +@item +The @code{argument} program attribute is disallowed. +@item +One of the options may be specified as the default +(as long as it has a required option argument). +@end itemize + +@item no-xlate +@vindex no-xlate +Modifies when or whether option names get translated. If provided, +it must be assigned one of these values: +@table @samp +@item opt-cfg +to suppress option name translation for configuration file and and environment +variable processing. +@item opt +to suppress option name translation completely. The usage text will +always be translated if @code{ENABLE_NLS} is defined and you have +translations for that text. +@item anything +Specifies disabling all internationalization support for option code, completely. +@end table +See also the various @code{XLAT} interface entries in the +AutoOpts Programmatic Interface section (@pxref{AutoOpts API}). + +@item reorder-args +@vindex reorder-args +Normally, POSIX compliant commands do not allow for options to be interleaved +with operands. If this is necessary for historical reasons, there are two +approaches available: +@itemize @bullet +@item +Allow @code{optionProcess} to return the index of the operand like it normally +does and process the operand(s). When an operand is encountered that starts +with a hyphen, then set the AutoOpts current index with the @code{RESTART_OPT} +macro (see @pxref{RESTART_OPT}), and re-invoke @code{optionProcess}. This +will also allow you to process the operands in context. + +@item +Specify this attribute. AutoOpts will re-order the command arguments +so that the operands appear (in the original order) at the end of +the argument list. Differing configuration state is not possible +to detect after all options have been processed. +@end itemize + +@item resettable +@vindex resettable +Specifies that the @option{--reset-option} command line option is to be +supported. This makes it possible to suppress any setting that might be +found in a configuration file or environment variable. +@end table + +@node library attributes +@subsection Options for Library Code +@cindex library attributes + +Some libraries provide their own code for processing command line +options, and this may be used by programs that utilize AutoOpts. +You may also wish to write a library that gets configured with AutoOpts +options and config files. Such a library may either supply its own +configury routine and process its own options, or it may export its +option descriptions to programs that also use AutoOpts. This section +will describe how to do all of these different things. + +@menu +* lib and program:: AutoOpt-ed Library for AutoOpt-ed Program +* lib called:: AutoOpt-ed Library for Regular Program +* prog calls lib:: AutoOpt-ed Program Calls Regular Library +@end menu + +@node lib and program +@subsubsection AutoOpt-ed Library for AutoOpt-ed Program + +The library source code must provide an option definition file that consists +of only the attribute @code{library} +@vindex library +and @code{flag} entries. The @code{library} attribute does not need any +associated value, so it will generally appeary by itself on a line folowed +by a semi-colon. The first @code{flag} entry must contain the following +attributes: + +@table @samp +@item name +This name is used in the construction of a global pointer of type +@code{tOptDesc const*}. It is always required. +@item documentation +@vindex documentation +It tells @code{AutoOpts} that this option serves no normal purpose. +It will be used to add usage clarity and to locate option descriptors +in the library code. +@item descrip +This is a string that is inserted in the extended usage display +before the options specific to the current library. It is always required. +@item lib-name +@vindex lib-name +This should match the name of the library. This string is also used in +the construction of the option descriptor pointer name. In the end, it +looks like this: +@example +extern tOptDesc const* <<lib-name>>_<<name>>_optDesc_p; +@end example +@noindent +and is used in the macros generated for the library's @file{.h} file. +@end table + +In order to compile this @code{AutoOpts} using library, you must create a +special header that is not used by the client program. This is accomplished +by creating an option definition file that contains essentially exactly the +following: + +@example +AutoGen definitions options; +prog-name = does-not-matter; // but is always required +prog-title = 'also does not matter'; // also required +config-header = 'config.h'; // optional, but common +library; +#include library-options-only.def +@end example + +@noindent +and nothing else. AutoGen will produce only the @file{.h} file. +You may now compile your library, referencing just this @file{.h} file. +The macros it creates will utilize a global variable that will be defined +by the @code{AutoOpts}-using client program. That program will need to +have the following @code{#include} in @i{its} option definition file: + +@example +#include library-options-only.def +@end example + +@noindent +All the right things will magically happen so that the global variables +named @var{<<lib-name>>_<<name>>_optDesc_p} are initialized correctly. +For an example, please see the @code{AutoOpts} test script: +@file{autoopts/test/library.test}. + +@node lib called +@subsubsection AutoOpt-ed Library for Regular Program + +In this case, your library must provide an option processing function +to a calling program. This is accomplished by setting the @code{allow-errors} +global option attribute. Each time your option handling function is called, +you must determine where your scan is to resume and tell the AutoOpts library +by invoking: + +@example +RESTART_OPT(next_arg_index); +@end example + +@noindent +and then invoke @code{not_opt_index = optionProcess(...)}. +The @code{not_opt_index} value can be used to set @code{optind}, +if that is the global being used to scan the program argument array. + +In this method, do @strong{NOT} utilize the global @code{library} attribute. +Your library must specify its options as if it were a complete program. +You may choose to specify an alternate @code{usage()} function so that +usage for other parts of the option interface may be displayed as well. +See ``Program Information Attributes'' (@pxref{information attributes}). + +At the moment, there is no method for calling @code{optionUsage()} telling +it to produce just the information about the options and not the program +as a whole. Some later revision after somebody asks. + +@node prog calls lib +@subsubsection AutoOpt-ed Program Calls Regular Library + +As with providing an @code{AutoOpt}-ed library to a non-@code{AutoOpt}-ed +program, you must write the option description file as if you were writing +all the options for the program, but you should specify the +@code{allow-errors} global option attribute and you will likely want an +alternate @code{usage()} function (see ``Program Information Attributes'' +@pxref{information attributes}). In this case, though, when +@code{optionProcess()} returns, you need to test to see if there might be +library options. If there might be, then call the library's exported +routine for handling command line options, set the next-option-to-process +with the @code{RESTART_OPT()} macro, and recall @code{optionProcess()}. +Repeat until done. + +@node information attributes +@subsection Program Information Attributes +@cindex information attributes + +These attributes are used to define how and what information is displayed +to the user of the program. + +@table @samp +@item copyright +@vindex copyright +The @code{copyright} is a structured value containing three to five +values. If @code{copyright} is used, then the first three are required. + +@enumerate +@item +@vindex date +@file{date} - the list of applicable dates for the copyright. +@item +@vindex owner +@file{owner} - the name of the copyright holder. +@item +@vindex type +@file{type} - specifies the type of distribution license. +AutoOpts/AutoGen supports the text of the GNU Public License (@file{gpl}), +the GNU Lesser General Public License with Library extensions +(@file{lgpl}), the Modified Free BSD license (@file{mbsd}) and a few others. +Other licenses may be specified, but you must provide your own license file. +The list of license files provided by AutoOpts may be seen by typing: +@example +ls $(autoopts-config pkgdatadir)/*.lic +@end example +@item +@vindex text +@file{text} - the text of the copyright notice. This must be provided +if @file{type} is set to @file{NOTE}. +@item +@vindex author +@file{author} - in case the author name is to appear in the documentation +and is different from the copyright owner. +@item +@vindex eaddr +@file{eaddr} - email address for receiving praises and complaints. +Typically that of the author or copyright holder. +@end enumerate +@* +An example of this might be: +@example +copyright = @{ + date = "1992-2015"; + owner = "Bruce Korb"; + eaddr = 'bkorb@@gnu.org'; + type = GPL; +@}; +@end example + +@item detail +@vindex detail +This string is added to the usage output when the HELP option is +selected. + +@item explain +@vindex explain +Gives additional information whenever the usage routine is invoked. + +@item package +@vindex package +The name of the package the program belongs to. This will appear +parenthetically after the program name in the version and usage output, +e.g.: @code{autogen @i{(GNU autogen)} - The Automated Program Generator}. + +@item preserve-case +@vindex preserve-case +This attribute will not change anything except appearance. Normally, the +option names are all documented in lower case. However, if you specify this +attribute, then they will display in the case used in their specification. +Command line options will still be matched without case sensitivity. +This is useful for specifying option names in camel-case. + +@item prog-desc @strong{and} +@itemx opts-ptr +@vindex prog-desc +@vindex opts-ptr +These define global pointer variables that point to the program +descriptor and the first option descriptor for a library option. This +is intended for use by certain libraries that need command line and/or +initialization file option processing. These definitions have no effect +on the option template output, but are used for creating a library +interface file. Normally, the first "option" for a library will be a +documentation option that cannot be specified on the command line, but +is marked as @code{settable}. The library client program will invoke the +@code{SET_OPTION} macro which will invoke a handler function that will +finally set these global variables. + +@item usage +@vindex usage +Optionally names the usage procedure, if the library routine +@code{optionUsage()} does not work for you. If you specify +@code{my_usage} as the value of this attribute, for example, you will +use a procedure by that name for displaying usage. Of course, you will +need to provide that procedure and it must conform to this profile: +@example +void @i{my_usage}( tOptions* pOptions, int exitCode ) +@end example + +@item gnu-usage +@vindex gnu-usage +Normally, the default format produced by the @code{optionUsage} procedure +is @i{AutoOpts Standard}. By specifying this attribute, the default format +will be @i{GNU-ish style}. Either default may be overridden by the user with +the @env{AUTOOPTS_USAGE} environment variable. If it is set to @code{gnu} +or @code{autoopts}, it will alter the style appropriately. This attribute +will conflict with the @code{usage} attribute. + +@item reorder-args +@vindex reorder-args +Some applications traditionally require that the command operands be +intermixed with the command options. In order to handle that, the arguments +must be reordered. If you are writing such an application, specify this +global option. All of the options (and any associated option arguments) +will be brought to the beginning of the argument list. New applications +should not use this feature, if at all possible. This feature is +@i{disabled} if @env{POSIXLY_CORRECT} is defined in the environment. +@end table + +@node Generated main +@subsection Generating main procedures +@cindex main procedure + +When AutoOpts generates the code to parse the command line options, it has +the ability to produce any of several types of @code{main()} procedures. +This is done by specifying a global structured value for +@vindex main +@code{main}. The values that it contains are dependent on the value set for +the one value it must have: @code{main-type}. + +@vindex main-type +The recognized values for @code{main-type} are @code{guile}, +@code{shell-process}, @code{shell-parser}, @code{main}, @code{include}, +@code{invoke}, and @code{for-each}. + +@menu +* main guile:: guile: main and inner_main procedures +* main shell-process:: shell-process: emit Bourne shell results +* main shell-parser:: shell-parser: emit Bourne shell script +* main main:: main: user supplied main procedure +* main include:: include: code emitted from included template +* main invoke:: invoke: code emitted from AutoGen macro + +The @code{for-each} main procedure has a number of attributes that +must be specified: + +* main for-each:: for-each: perform function on each operand +* main-for-each-proc:: procedure to handle each argument +* main-for-each-type:: handler procedure type +* main-for-each-code:: code for handler procedure +* main-for-each-opts:: for-each main procedure options +@end menu + +@node main guile +@subsubsection guile: main and inner_main procedures + +When the @code{main-type} is specified to be @code{guile}, +a @code{main()} procedure is generated that calls @code{gh_enter()}, providing +it with a generated @code{inner_main()} to invoke. If you must perform +certain tasks before calling @code{gh_enter()}, you may specify such code +in the value for the +@vindex before-guile-boot +@code{before-guile-boot} attribute. + +The @code{inner_main()} procedure itself will process the command line +arguments (by calling @code{optionProcess()}, +@pxref{libopts-optionProcess}), and then either invoke the code +specified with the +@vindex guile-main +@code{guile-main} attribute, or else export the parsed options to Guile +symbols and invoke the @code{scm_shell()} function from the Guile library. +This latter will render the program nearly identical to the stock +@code{guile(1)} program. + +@node main shell-process +@subsubsection shell-process: emit Bourne shell results + +This will produce a @code{main()} procedure that parses the command line +options and emits to @file{stdout} Bourne shell commands that puts the +option state into environment variables. This can be used within a +shell script as follows: + +@example +unset OPTION_CT +eval "`opt_parser \"$@@\"`" +test $@{OPTION_CT@} -gt 0 && shift $@{OPTION_CT@} +@end example + +If the option parsing code detects an error or a request for usage or version, +it will emit a command to exit with an appropriate exit code to @file{stdout}. +This form of @code{main} will cause all messages, including requested usage +and version information, to be emitted to @file{stderr}. Otherwise, a numeric +value for @code{OPTION_CT} is guaranteed to be emitted, along with assignments +for all the options parsed, something along the lines of the following will be +written to @file{stdout} for evaluation: + +@example +OPTION_CT=4 +export OPTION_CT +MYPROG_SECOND='first' +export MYPROG_SECOND +MYPROG_ANOTHER=1 # 0x1 +export MYPROG_ANOTHER +@end example + +@noindent +If the arguments are to be reordered, however, then the resulting set +of operands will be emitted and @env{OPTION_CT} will be set to zero. +For example, the following would be appended to the above: + +@example +set -- 'operand1' 'operand2' 'operand3' +OPTION_CT=0 +@end example + +@noindent +@env{OPTION_CT} is set to zero since it is not necessary to shift +off any options. + +@node main shell-parser +@subsubsection shell-parser: emit Bourne shell script + +This will produce a @code{main()} procedure that emits a shell script +that will parse the command line options. That script can be emitted +to @file{stdout} or inserted or substituted into a pre-existing shell +script file. Improbable markers are used to identify previously inserted +parsing text: + +@example +# # # # # # # # # # -- do not modify this marker -- +@end example + +@noindent +The program is also pretty insistent upon starting its parsing script +on the second line. + +@node main main +@subsubsection main: user supplied main procedure + +You must supply a value for the @code{main-text} attribute. +You may also supply a value for +@vindex option-code +@code{option-code}. If you do, then the @code{optionProcess} invocation +will not be emitted into the code. AutoOpts will wrap the @code{main-text} +inside of: + +@example +int +main( int argc, char** argv ) +@{ + int res = <<success-exit-code>>; + @{ // replaced by option-code, if that exists + int ct = optionProcess( &<<prog-name>>Options, argc, argv); + argc -= ct; + argv += ct; + @} +<<main-text>> + return res; +@} +@end example + +@noindent +so you can most conveniently set the value with a @code{here string} +(@pxref{here-string}): + +@example +code = <<- _EndOfMainProc_ + <<your text goes here>> + _EndOfMainProc_; +@end example + +@node main include +@subsubsection include: code emitted from included template + +You must write a template to produce your main procedure. +You specify the name of the template with the @code{tpl} attribute +and it will be incorporated at the point where AutoOpts is ready +to emit the @code{main()} procedure. + +This can be very useful if, in your working environment, you have +many programs with highly similar @code{main()} procedures. All you need +to do is parameterize the variations and specify which variant is needed +within the @code{main} AutoOpts specification. Since you are coding +the template for this, the attributes needed for this variation would +be dictated by your template. + +Here is an example of an @code{include} variation: + +@example +main = @{ + main-type = include; + tpl = "main-template.tpl"; +@}; +@end example + +@node main invoke +@subsubsection invoke: code emitted from AutoGen macro + +You must write a template to produce your main procedure. That template +must contain a definition for the function specified with the @code{func} +attribute to this @code{main()} procedure specification. This +variation operates in much the same way as @code{include} +(@pxref{main include}) method. + +@node main for-each +@subsubsection for-each: perform function on each operand + +This produces a main procedure that invokes a procedure once for each operand +on the command line (non-option arguments), @strong{OR} once for each +non-blank, non-comment @code{stdin} input line. Leading and trailing white +space is trimmed from the input line and comment lines are lines that are +empty or begin with a comment character, defaulting to a hash ('#') character. + +@strong{NB}: +The @code{argument} program attribute (@pxref{program attributes}) +must begin with the @code{[} character, to indicate that there are +command operands, but that they are optional. + +@noindent +For an example of the produced main procedure, in the @file{autoopts/test} +build directory, type the following command and look at @file{main.c}: +@example +make verbose TESTS=main.test +@end example + +@node main-for-each-proc +@unnumberedsubsubsec procedure to handle each argument + +@vindex handler-proc +The @code{handler-proc} attribute is required. It is used to name the +procedure to call. That procedure is presumed to be external, but if +you provide the code for it, then the procedure is emitted as a static +procedure in the generated code. + +This procedure should return 0 on success, a cumulative error code on warning +and exit without returning on an unrecoverable error. As the cumulative +warning codes are @i{or}-ed together, the codes should be some sort of bit +mask in order to be ultimately decipherable (if you need to do that). + +If the called procedure needs to cause a fail-exit, it is expected to call +@code{exit(3)} directly. If you want to cause a warning exit code, then this +handler function should return a non-zero status. That value will be +@strong{OR}-ed into a result integer for computing the final exit code. E.g., +here is part of the emitted code: + +@example + int res = 0; + if (argc > 0) @{ + do @{ + res |= @var{my_handler}( *(argv++) ); + @} while (--argc > 0); + @} else @{ ... +@end example + +@node main-for-each-type +@unnumberedsubsubsec handler procedure type + +@vindex handler-type +If you do not supply the @code{handler-type} attribute, your handler +procedure must be the default type. The profile of the procedure must be: + +@example +int @var{my_handler}(char const * pz_entry); +@end example + +@noindent +However, if you do supply this attribute, you may set the value to any of +four alternate flavors: + +@table @samp +@item name-of-file +This is essentially the same as the default handler type, except that before +your procedure is invoked, the generated code has verified that the string +names an existing file. The profile is unchanged. + +@item file-X +Before calling your procedure, the file is f-opened according to the @code{X}, +where @code{X} may be any of the legal modes for @code{fopen(3C)}. In this +case, the profile for your procedure must be: + +@example +int @var{my_handler}(char const * pz_fname, FILE * entry_fp); +@end example + +@noindent +When processing inputs as file pointer stream files, there are several +ways of treating standard input. It may be an ordinary input file, +or it may contain a list of files to operate on. + +If the file handler type is more specifically set to @samp{file-r} and +a command line operand consists of a single hyphen, then @var{my_handler} +will be called with @code{entry_fp} set to @code{stdin} and the @code{pz_fname} +set to the translatable string, "standard input". Consequently, +in this case, if the input list is being read from @code{stdin}, a line +containing a hyphen by itself will be ignored. + +@item stdin-input +This attribute specifies that standard input is a data input file. +By default, @code{for-each} main procedures will read standard input for +operands if no operands appear on the command line. If there are operands +after the command line options, then standard input is typically ignored. +It can always be processed as an input data file, however, if a single bare +hyphen is put on the command line. + +@item text-of-file +@itemx some-text-of-file +Before calling your procedure, the contents of the file are read or mapped +into memory. (Excessively large files may cause problems.) The +@samp{some-text-of-file} disallows empty files. Both require regular files. +In this case, the profile for your procedure must be: + +@example +program_exit_code_t +@var{my_handler}(char const * fname, char * file_text, + size_t text_size); +@end example + +@noindent +Note that though the @code{file_text} is not @code{const}, any changes made to +it are not written back to the original file. It is merely a memory image of +the file contents. Also, the memory allocated to hold the text is +@code{text_size + 1} bytes long and the final byte is always @code{NUL}. The +file contents need not be text, as the data are read with the @code{read(2)} +system call. + +@code{file_text} is automatically freed, unless you specify a +@vindex handler-frees +@code{handler-frees} attribute. Then your code must @code{free(3)} the text. +@end table + +If you select one of these file type handlers, then on access or usage errors +the @code{PROGRAM_EXIT_FAILURE} exit code will, by default, be or-ed +into the final exit code. This can be changed by specifying the +global @code{file-fail-code} attribute and naming a different value. +That is, something other than @code{failure}. You may choose @code{success}, +in which case file access issues will not affect the exit code and the error +message will not be printed. + +@node main-for-each-code +@unnumberedsubsubsec code for handler procedure + +@vindex MYHANDLER-code +With the @code{MYHANDLER-code} attribute, you provide the code for +your handler procedure in the option definition file. Note that the +spelling of this attribute depends on the name provided with the +@code{handler-proc} attribute, so we represent it here with +@code{MYHANDLER} as a place holder. As an example, your @code{main()} +procedure specification might look something like this: + +@example +main = @{ + main-type = for-each; + handler-proc = @var{MYHANDLER}; + @var{MYHANDLER}-code = <<- EndOfMyCode + /* whatever you want to do */ + EndOfMyCode; +@}; +@end example + +@noindent +and instead of an emitted external reference, a procedure will be emitted +that looks like this: + +@example +static int +@var{MYHANDLER}( char const* pz_entry ) +@{ + int res = 0; + <<@var{MYHANDLER}-code goes here>> + return res; +@} +@end example + +@node main-for-each-opts +@unnumberedsubsubsec for-each main procedure options + +These attributes affect the main procedure and how it processes +each argument or input line. + +@table @samp +@item interleaved +@vindex interleaved +If this attribute is specified, then options and operands may be +interleaved. Arguments or input lines beginning with a hyphen will +cause it to be passed through to an option processing function and +will take effect for the remainder of the operands (or input lines) +processed. + +@item main-init +@vindex main-init +This is code that gets inserted after the options have been processed, but +before the handler procs get invoked. + +@item main-fini +@vindex main-fini +This is code that gets inserted after all the entries have been processed, +just before returning from @code{main()}. + +@item comment-char +@vindex comment-char +When reading operands from standard input, if you wish comment lines to +start with a character other than a hash (@code{#}) character, then +specify one character with this attribute. If string value is empty, +then only blank lines will be considered comments. +@end table + +@node option attributes +@subsection Option Attributes +@cindex option attributes + +For each option you wish to specify, you must have a block macro named +@code{flag} defined. There are two required attributes: @code{name} and +@code{descrip}. If any options do not have a @code{value} (traditional flag +character) attribute, then the @code{long-opts} program attribute must also +be defined. As a special exception, if no options have a @code{value} +@strong{and} @code{long-opts} is not defined @strong{and} @code{argument} is +not defined, then all arguments to the program are named options. In this +case, the @option{-} and @option{--} command line option markers are optional. + +@menu +* Required Attributes:: Required Attributes +* Common Attributes:: Common Option Attributes +* Immediate Action:: Immediate Action Attributes +* Option Conflict Attributes:: Option Conflict Attributes + +These option attributes do not fit well with the above categories. + +* opt-attr settable:: Program may set option +* opt-attr no-preset:: Option cannot be pre-configured +* opt-attr equivalence:: Option Equivalence Class +* opt-attr aliases:: Option Aliasing +* opt-attr default option:: Default Option +* opt-attr documentation:: Option Sectioning Comment +* opt-attr translators:: Translator Notes +@end menu + +@node Required Attributes +@subsubsection Required Attributes +@cindex Required Attributes + +Every option must have exactly one copy of both of these attributes. + +@table @samp +@item name +@vindex name +Long name for the option. Even if you are not accepting long options +and are only accepting flags, it must be provided. AutoOpts generates +private, named storage that requires this name. This name also causes +a @code{#define}-d name to be emitted. It must not conflict with any +other names you may be using in your program. + +For example, if your option name is, @code{debug} or @code{munged-up}, +you must not use the @code{#define} names @code{DEBUG} (or +@code{MUNGED_UP}) in your program for non-AutoOpts related purposes. +They are now used by AutoOpts. + +Sometimes (most especially under Windows), you may get a surprise. +For example, @code{INTERFACE} is apparently a user space name that +one should be free to use. Windows usurps this name. To solve this, +you must do one of the following: + +@enumerate +@item +Change the name of your option +@item +add the program attribute (@pxref{program attributes}): + +@example +export = '#undef INTERFACE'; +@end example +@item +add the program attribute: + +@example +guard-option-names; +@end example +@end enumerate + +@item descrip +@vindex descrip +Except for documentation options, a @strong{very} brief description of the +option. About 40 characters on one line, maximum, not counting any texinfo +markups. Texinfo markups are stripped before printing in the usage text. It +appears on the @code{usage()} output next to the option name. + +If, however, the option is a documentation option, it will appear on one or +more lines by itself. It is thus used to visually separate and comment upon +groups of options in the usage text. +@end table + +@node Common Attributes +@subsubsection Common Option Attributes +@cindex Common Option Attributes + +These option attributes are optional. Any that do appear in the +definition of a flag, may appear only once. + +@table @samp +@item value +@vindex value +The flag character to specify for traditional option flags, e.g., @option{-L}. + +@item max +@vindex max +Maximum occurrence count (invalid if @var{disable} present). +The default maximum is 1. @code{NOLIMIT} can be used for the value, +otherwise it must be a number or a @code{#define} that evaluates to a number. + +@item min +@vindex min +Minimum occurrence count. If present, then the option @strong{must} +appear on the command line. Do not define it with the value zero (0). + +@item must-set +@vindex must-set +If an option must be specified, but it need not be specified on +the command line, then specify this attribute for the option. + +@item deprecated +@vindex deprecated +There are two effects to this attribute: the usage text will not +show the option, and the generated documentation will mark it with: +@emph{NOTE: THIS OPTION IS DEPRECATED}. + +@item disable +@vindex disable +Prefix for disabling (inverting sense of) the option. Only useful +if long option names are being processed. When an option has this +attribute, the test @code{ENABLED_OPT(OPTNAME)} is false when either +of the following is true: +@itemize @bullet +@item +The option has not been specified and the @code{enable} attribute has +not been specified. +@item +The option has been specified with this disabling prefix. +@end itemize +To detect that the option has been specified with the disabling +prefix, you must use: +@example +HAVE_OPT(OPTNAME) && ! ENABLED_OPT(OPTNAME) +@end example + +@item enable +@vindex enable +Long-name prefix for enabling the option (invalid if @var{disable} +@strong{not} present). Only useful if long option names are being +processed. + +@item enabled +@vindex enabled +If default is for option being enabled. (Otherwise, the OPTST_DISABLED +bit is set at compile time.) Only useful if the option can be disabled. + +@item ifdef +@itemx ifndef +@itemx omitted-usage +@vindex ifdef +@vindex ifndef +@vindex omitted-usage +If an option is relevant on certain platforms or when certain features +are enabled or disabled, you can specify the compile time flag used +to indicate when the option should be compiled in or out. For example, +if you have a configurable feature, @code{mumble} that is indicated +with the compile time define, @code{WITH_MUMBLING}, then add: + +@example +ifdef = WITH_MUMBLING; +@end example + +@noindent +Take care when using these. There are several caveats: + +@itemize @bullet +@item +The case and spelling must match whatever is specified. +@item +Do not confuse these attributes with the AutoGen directives of the +same names, @xref{Directives}. These cause C preprocessing directives +to be inserted into the generated C text. +@item +Only one of @code{ifdef} and @code{ifndef} may apply to any one option. +@item +The @code{VALUE_OPT_} values are @code{#define}-d. If @code{WITH_MUMBLING} +is not defined, then the associated @code{VALUE_OPT_} value will not be +@code{#define}-d either. So, if you have an option named, @code{MUMBLING} +that is active only if @code{WITH_MUMBLING} is @code{#define}-d, then +@code{VALUE_OPT_MUMBLING} will be @code{#define}-d iff @code{WITH_MUMBLING} +is @code{#define}-d. Watch those switch statements. +@item +If you specify @code{omitted-usage}, then the option will be recognized +as disabled when it is configured out of the build, but will yield the +message, ``This option has been disabled.'' You may specify an alternate +message by giving @code{omitted-usage} a string value. e.g.: +@example +omitted-usage = 'you cannot do this'; +@end example +@end itemize + +@item no-command +@vindex no-command +This option specifies that the option is not allowed on the command line. +Such an option may not take a @code{value} (flag character) attribute. The +program must have the @code{homerc} (@pxref{program attributes}) option set. +@end table + +@node Immediate Action +@subsubsection Immediate Action Attributes +@cindex immediate action + +Certain options may need to be processed early. For example, in order to +suppress the processing of configuration files, it is necessary to process the +command line option @option{--no-load-opts} @strong{before} the config files +are processed. To accommodate this, certain options may have their enabled or +disabled forms marked for immediate processing. The consequence of this is +that they are processed ahead of all other options in the reverse of normal +order. + +Normally, the first options processed are the options specified in the first +@code{homerc} file, followed by then next @code{homerc} file through to the +end of config file processing. Next, environment variables are processed and +finally, the command line options. The later options override settings +processed earlier. That actually gives them higher priority. Command line +immediate action options actually have the lowest priority of all. They would +be used only if they are to have an effect on the processing of subsequent +options. + +@table @samp +@item immediate +@vindex immediate +Use this option attribute to specify that the enabled form of the option +is to be processed immediately. The @code{help} and @code{more-help} +options are so specified. They will also call @code{exit()} upon +completion, so they @strong{do} have an effect on the processing +of the remaining options :-). + +@item immed-disable +@vindex immed-disable +Use this option attribute to specify that the disabled form of the +option is to be processed immediately. The @code{load-opts} option is +so specified. The @option{--no-load-opts} command line option will +suppress the processing of config files and environment variables. +Contrariwise, the @option{--load-opts} command line option is +processed normally. That means that the options specified in that file +will be processed after all the @code{homerc} files and, in fact, after +options that precede it on the command line. + +@item also +If either the @code{immediate} or the @code{immed-disable} attributes +are set to the string, @code{also}, then the option will actually be +processed twice: first at the immediate processing phase and again +at the normal time. +@end table + +@node Option Conflict Attributes +@subsubsection Option Conflict Attributes +@cindex Option Conflict Attributes + +These attributes may be used as many times as you need. +They are used at the end of the option processing to verify +that the context within which each option is found does not +conflict with the presence or absence of other options. + +This is not a complete cover of all possible conflicts and +requirements, but it simple to implement and covers the +more common situations. + +@table @samp +@cindex flags-must +@item flags-must +one entry for every option that @strong{must} be present +when this option is present + +@cindex flags-cant +@item flags-cant +one entry for every option that @strong{cannot} be present +when this option is present +@end table + +@node opt-attr settable +@subsubsection Program may set option +@vindex settable +If the option can be set outside of option processing, specify +@code{settable}. If this attribute is defined, special macros for setting +this particular option will be inserted into the interface file. For example, +@code{TEMPL_DIRS} is a settable option for AutoGen, so a macro named +@code{SET_OPT_TEMPL_DIRS(a)} appears in the interface file. This attribute +interacts with the @var{documentation} attribute. + +@node opt-attr no-preset +@subsubsection Option cannot be pre-configured +@vindex no-preset +@cindex configuration file +If presetting this option is not allowed, specify @code{no-preset}. +(Thus, environment variables and values set in configuration files will be +ignored.) + +@node opt-attr equivalence +@subsubsection Option Equivalence Class +@vindex equivalence +Generally, when several options are mutually exclusive and basically serve the +purpose of selecting one of several processing modes, specify the +@code{equivalence} attribute. These options will be considered an +equivalence class. Sometimes, it is just easier to deal with them as such. +All members of the equivalence class must contain the same equivalenced-to +option, including the equivalenced-to option itself. Thus, it must be a class +member. + +For an option equivalence class, there is a single occurrence counter for +the class. It can be referenced with the interface macro, +@code{COUNT_OPT(BASE_OPTION)}, where @var{BASE_OPTION} is the equivalenced-to +option name. + +Also, please take careful note: since the options are mapped to the +equivalenced-to option descriptor, any option argument values are mapped to +that descriptor also. Be sure you know which ``equivalent option'' was +selected before getting an option argument value! + +During the presetting phase of option processing +(@pxref{Presetting Options}), equivalenced options may be specified. +However, if different equivalenced members are specified, only the last +instance will be recognized and the others will be discarded. A conflict +error is indicated only when multiple different members appear on the +command line itself. + +As an example of where equivalenced options might be useful, @code{cpio(1)} +has three options @option{-o}, @option{-i}, and @option{-p} that define the +operational mode of the program (@code{create}, @code{extract} and +@code{pass-through}, respectively). They form an equivalence class from +which one and only one member must appear on the command line. If +@code{cpio} were an AutoOpt-ed program, then each of these option +definitions would contain: + +@example +equivalence = create; +@end example + +and the program would be able to determine the operating mode +with code that worked something like this: + +@example +switch (WHICH_IDX_CREATE) @{ +case INDEX_OPT_CREATE: ... +case INDEX_OPT_EXTRACT: ... +case INDEX_OPT_PASS_THROUGH: ... +default: /* cannot happen */ +@} +@end example + +@node opt-attr aliases +@subsubsection Option Aliasing + +Sometimes, for backwards compatibility or tradition or just plain convenience, +it works better to define one option as a pure alias for another option. +For such situations, provide the following pieces of information: +@example +flag = @{ + name = @i{aliasing-option-name}; + value = @i{aliasing-flag-char}; // optional ! + aliases = @i{aliased-to-option}; +@}; +@end example +Do not provide anything else. The usage text for such an option will be: +@example + This is an alias for @i{aliased-to-option} +@end example + +@node opt-attr default option +@subsubsection Default Option +@vindex default +If your program processes its arguments in named option mode (See +@code{long-opts} in @ref{program attributes}), then you may select +@strong{one} of your options to be the default option. Do so by using +attribute @code{default} with one of the options. The option so specified +must have an @code{arg-type} (@pxref{Option Arguments}) specified, but not the +@code{arg-optional} (@pxref{arg-optional}) attribute. That is to say, the +option argument must be required. + +If you have done this, then any arguments that do not match an option name and +do not contain an equal sign (@code{=}) will be interpreted as an option +argument to the default option. + +@node opt-attr documentation +@subsubsection Option Sectioning Comment +This attribute means the option exists for the purpose of separating option +description text in the usage output and texi documentation. Without this +attribute, every option is a separate node in the texi docs. With this +attribute, the documentation options become texi doc nodes and the options are +collected under them. Choose the name attribute carefully because it will +appear in the texi documentation. + +Libraries may also choose to make it settable so that the library can +determine which command line option is the first one that pertains to the +library. + +@vindex documentation +If the @samp{documentation} attribute is present, then all other +attributes are disabled except @code{settable}, @code{call-proc} and +@code{flag-code}. @code{settable} must be and is only specified if +@code{call-proc}, @code{extract-code} or @code{flag-code} has been specified. +When present, the @code{descrip} attribute will be displayed only when the +@option{--help} option has been specified. It will be displayed flush to the +left hand margin and may consist of one or more lines of text, filled to 72 +columns. + +The name of the option will not be printed in the help text. It @i{will}, +however, be printed as section headers in the texi documentation. If the +attribute is given a non-empty value, this text will be reproduced in the man +page and texi doc immediately after the @code{descrip} text. + +@node opt-attr translators +@subsubsection Translator Notes +@vindex translators +If you need to give the translators a special note about a particular option, +please use the @code{translators} attribute. The attribute text will be +emitted into the generated @code{.c} text where the option related strings get +defined. To make a general comment about all of the option code, add comments +to an @code{include} attribute (@pxref{program attributes}). Do @strong{not} +use this attribute globally, or it will get emitted into every option +definition block. + +@node Option Arguments +@subsection Option Argument Specification +@cindex Option Arguments + +Command line options come in three flavors: options that do not +take arguments, those that do and those that may. Without an +"arg-type" attribute, AutoOpts will not process an argument to an +option. If "arg-type" is specified and "arg-optional" is also +specified, then the next command line token will be taken to +be an argument, unless it looks like the name of another option. + +If the argument type is specified to be anything other than "str[ing]", then +AutoOpts will specify a callback procedure to handle the argument. Some of +these procedures will be created and inserted into the generated @file{.c} +file, and others are already built into the @file{libopts} library. +Therefore, if you write your own callback procedure +(@pxref{Option Argument Handling}), then you must either not specify an +"arg-type" attribute, or else specify it to be of type "str[ing]". Your +callback function will be able to place its own restrictions on what that +string may contain or represent. + +Option argument handling attributes depend upon the value set for the +@vindex arg-type +@code{arg-type} attribute. It specifies the type of argument the option +will take. If not present, the option cannot take an argument. If present, +it must be an entry in the following table. The first three letters is +sufficient. + +@menu +* arg-type string:: Arg Type String +* arg-type number:: Arg Type Number +* arg-type boolean:: Arg Type Boolean +* arg-type keyword:: Arg Type Keyword +* arg-type set membership:: Arg Type Set Membership +* arg-type hierarchy:: Arg Type Hierarchical +* arg-type file name:: Arg Type File Name +* arg-type time-duration:: Arg Type Time Duration +* arg-type time-date:: Arg Type Time and Date + +Supporting attributes for particular argument types: + +* arg-keyword:: Keyword list +* arg-optional:: Option Argument Optional +* arg-default:: Default Option Argument Value +@end menu + +@node arg-type string +@subsubsection Arg Type String +@code{arg-type = string;} + +The argument may be any arbitrary string, though your program or option +callback procedure may place additional constraints upon it. + + +@node arg-type number +@subsubsection Arg Type Number +@code{arg-type = number;} + +The argument must be a correctly formed integer, without any trailing U's or +L's. AutoOpts contains a library procedure to convert the string to a number. +If you specify range checking with @code{arg-range} (see below), then AutoOpts +produces a special purpose procedure for this option. + +@table @samp +@item scaled +@vindex scaled +@code{scaled} marks the option so that suffixes of @samp{k}, @samp{K}, +@samp{m}, @samp{M}, @samp{g}, @samp{G}, @samp{t}, and @samp{T} will multiply +the given number by a power of 1000 or 1024. Lower case letters scale by a +power of 1000 and upper case scale by a power of 1024. + +@item arg-range +@vindex arg-range +@code{arg-range} is used to create a callback procedure for validating the +range of the option argument. It must match one of the range entries. Each +@code{arg-range} should consist of either an integer by itself or an integer +range. The integer range is specified by one or two integers separated by the +two character sequence, @code{->}. Be sure to quote the entire range string. +The definitions parser will not accept the range syntax as a single string +token. + +The generated procedure imposes the range constraints as follows: +@itemize @bullet +@item +A number by itself will match that one value. +@item +The high end of the range may not be @code{INT_MIN}, both for obvious +reasons and because that value is used to indicate a single-valued match. +@item +An omitted lower value implies a lower bound of INT_MIN. +@item +An omitted upper value implies a upper bound of INT_MAX. +@item +The argument value is required. It may not be optional. +@item +The value must match one of the entries. If it can match more than one, +then you have redundancies, but no harm will come of it. +@end itemize +@end table + + +@node arg-type boolean +@subsubsection Arg Type Boolean +@code{arg-type = boolean;} + +The argument will be interpreted and always yield either AG_TRUE or +AG_FALSE. False values are@: the empty string, the number zero, or a +string that starts with @code{f}, @code{F}, @code{n} or @code{N} +(representing False or No). Anything else will be interpreted as True. + + +@node arg-type keyword +@subsubsection Arg Type Keyword +@code{arg-type = keyword;} + +The argument must match a specified list of strings (@pxref{arg-keyword}). +Assuming you have named the option, @code{optn-name}, the strings will be +converted into an enumeration of type @code{te_Optn_Name} with the values +@code{OPTN_NAME_KEYWORD}.* If you have @strong{not} specified a default +value, the value @code{OPTN_NAME_UNDEFINED} will be inserted with the value +zero. The option will be initialized to that value. You may now use this +in your code as follows: + +@example +te_Optn_Name opt = OPT_VALUE_OPTN_NAME; +switch (opt) @{ +case OPTN_NAME_UNDEFINED: /* undefined things */ break; +case OPTN_NAME_KEYWORD: /* `keyword' things */ break; +default: /* utterly impossible */ ; +@} +@end example + +AutoOpts produces a special purpose procedure for this option. +You may not specify an alternate handling procedure. + +If you have need for the string name of the selected keyword, you +may obtain this with the macro, @code{OPT_OPTN_NAME_VAL2STR(val)}. +The value you pass would normally be @code{OPT_VALUE_OPTN_NAME}, +but anything with numeric value that is legal for @code{te_Optn_Name} +may be passed. Anything out of range will result in the string, +@samp{"*INVALID*"} being returned. The strings are read only. +It may be used as in: + +@example +te_Optn_Name opt = OPT_VALUE_OPTN_NAME; +printf( "you selected the %s keyword\n", + OPT_OPTN_NAME_VAL2STR(opt) ); +@end example + +* Note: you may replace the @code{OPTN_NAME} enumeration prefix with +another prefix by specifying a +@vindex prefix-enum +@code{prefix-enum} attribute. + +Finally, users may specify the argument either by name or by number. +Since the numeric equivalents change by having new entries inserted +into the keyword list, this would not be a recommended practice. +However, either @code{-1} or @code{~0} will always be equivalent to +specifying the last keyword. + +@node arg-type set membership +@subsubsection Arg Type Set Membership +@code{arg-type = set;} + +The argument must be a list of names each of which must match the strings +``@code{all}'', ``@code{none}'' or one of the keywords (@pxref{arg-keyword}) +specified for this option. @code{all} will turn on all membership bits and +@code{none} will turn them all off. Specifying one of the keywords will set +the corresponding set membership bit on (or off, if negated) . Literal +numbers may also be used and may, thereby, set or clear more than one bit. + +The membership result starts with the previous (or initialized) result. To +clear previous results, either start the membership string with @samp{none +} +or with the equals character (@samp{=}). To invert (bit flip) the final +result (regardless of whether the previous result is carried over or not), +start the string with a carat character (@samp{^}). If you wish to invert the +result and start without a carried over value, use one of the following: +@code{=^} or @code{^none+}. These are equivalent. + +The list of names or numbers must be separated by one of the following +characters: @samp{+-|!,} or whitespace. The comma is equivalent to +whitespace, except that only one may appear between two entries and it may not +appear in conjunction with the @var{or} bar (@samp{|}). The @samp{+|} leading +characters or unadorned name signify adding the next named bit to the mask, +and the @samp{-!} leading characters indicate removing it. + +The number of keywords allowed is constrained by the number of bits in a +pointer, as the bit set is kept in a @code{void *} pointer. + +If, for example, you specified @code{first} in your list of keywords, +then you can use the following code to test to see if either @code{first} +or @code{all} was specified: + +@example +uintptr_t opt = OPT_VALUE_OPTN_NAME; +if (opt & OPTN_NAME_FIRST) + /* OPTN_NAME_FIRST bit was set */ ; +@end example + +AutoOpts produces a special purpose procedure for this option. +To set multiple bits as the default (initial) value, you must +specify an initial numeric value (which might become inaccurate over +time), or else specify @code{arg-default} multiple times. Do not +specify a series of names conjoined with @code{+} symbols as the +value for any of the @code{arg-default} attributes. That works for +option parsing, but not for the option code generation. + +@node arg-type hierarchy +@subsubsection Arg Type Hierarchical +@code{arg-type = hierarchy;} +@* +@code{arg-type = nested;} + +This denotes an option with a structure-valued argument, a.k.a. +@code{subopts} in @code{getopts} terminology. The argument is parsed +and the values made available to the program via the find and +find next calls (@xref{libopts-optionFindValue}, +@xref{libopts-optionGetValue}, and +@pxref{libopts-optionFindNextValue}). + +@example +tOptionValue * val = optionGetValue(VALUE_OPT_OPTN_NAME, "name"); +while (val != NULL) @{ + process(val); + val = optionNextValue(VALUE_OPT_OPTN_NAME, val); + if (wrong_name(val, "name")) + break; +@} +@end example + + +@node arg-type file name +@subsubsection Arg Type File Name +@code{arg-type = file;} + +This argument type will have some validations on the argument and, +optionally, actually open the file. You must specify several additonal +attributes for the option: + +@table @samp +@item file-exists +@vindex file-exists +If not specified or empty, then the directory portion of the name is checked. +The directory must exist or the argument is rejected and the usage procedure +is invoked. + +Otherwise, both the directory as above and the full name is tested for +existence. If the value begins with the two letters @code{no}, then the file +must not pre-exist. Otherwise, the file is expected to exist. + +@item open-file +@vindex open-file +If not specified or empty, the file is left alone. +If the value begins with the four letters @code{desc}[@i{riptor}], then +@code{open(2)} is used and @code{optArg.argFd} is set. Otherwise, the +file is opened with @code{fopen} and @code{optArg.argFp} is set. + +@item file-mode +@vindex file-mode +If @code{open-file} is set and not empty, then you must specify the open mode. +Set the value to the flag bits or mode string as appropriate for the open +type. +@end table + + +@node arg-type time-duration +@subsubsection Arg Type Time Duration +@code{arg-type = time-duration;} + +The argument will be converted into a number of seconds. It may be +a multi-part number with different parts being multiplied into a seconds +value and added into the final result. Valid forms are in the table +below. Upper cased letters represent numbers that must be used in the +expressions. + +@table @samp +@item [[HH:]MM:]SS +@code{HH} is multiplied by @code{3600} and @code{MM} multiplied by @code{60} +before they are added to @code{SS}. This time specification may not be +followed by any other time specs. @code{HH} and @code{MM} are both optional, +though @code{HH} cannot be specified without @code{MM}. + +@item DAYS d +@code{DAYS} is multiplied by the number of seconds in a day. This value may +be followed by (and added to) values specified by @code{HH:MM:SS} or the +suffixed values below. If present, it must always be first. + +@item HRS h +@code{HRS} is multiplied by the number of seconds in an hour. This value may +be followed by (and added to) values specified by @code{MM:SS} or the +suffixed values below. + +@item MINS m +@code{MINS} is multiplied by the number of seconds in a minute. This value +may be followed by (and added to) a count of seconds. + +@item SECS s +This value can only be the last value in a time specification. The @code{s} +suffix is optional. +@end table + +@example + 5 d 1:10:05 ==> 5 days + 1 hour 10 minutes and 5 seconds + 5 d 1 h 10 m 5 ==> yields: 436205 seconds + 5d1h10m5s ==> same result -- spaces are optional. +@end example + +When saved into a config file, the value will be stored as a simple count +of seconds. There are actually more (many) accepted time duration strings. +The full documentation can be found with ISO-8601 documentation and the +more extedded documentation when @code{parse_duration()} becomes more widely +available. + + +@node arg-type time-date +@subsubsection Arg Type Time and Date +@code{arg-type = time-date;} + +The argument will be converted into the number of seconds since the epoch. +The conversion rules are very complicated, please see the +@file{getdate_r(3GNU)} man page. There are some additional restrictions: + +@enumerate +@item +Your project must be compiled with @code{PKGDATADIR} defined and naming a +valid directory. +@item +The @env{DATEMSK} environment variable will be set to the @file{datemsk} file +within that directory. +@end enumerate + +If that file is not accessible for any reason, the string will be +parsed as a time duration (@pxref{arg-type time-duration}) instead of a +specific date and time. + +@node arg-keyword +@subsubsection Keyword list +@vindex keyword +If the @code{arg-type} is @code{keyword} (@pxref{arg-type keyword}) or +@code{set-membership} (@pxref{arg-type set membership}), then you must specify +the list of keywords by a series of @code{keyword} entries. The interface +file will contain values for @env{@i{<OPTN_NAME>}_@i{<KEYWORD>}} for each +keyword entry. @code{keyword} option types will have an enumeration and +@code{set-membership} option types will have a set of unsigned bits +@code{#define}-d. + +If the @code{arg-type} is specifically @code{keyword}, you may also add +special handling code with a +@vindex extra-code +@code{extra-code} attribute. After @code{optionEnumerationVal} has +converted the input string into an enumeration, you may insert code to +process this enumeration value (@code{pOptDesc->optArg.argEnum}). + +@node arg-optional +@subsubsection Option Argument Optional +@vindex arg-optional +The @code{arg-optional} attribute indicates that the argument to the option is +optional (need not be specified on the command line). This is only valid if +the @var{arg-type} is @code{string} (@pxref{arg-type string}) or +@code{keyword} (@pxref{arg-type keyword}). If it is @code{keyword}, then this +attribute may also specify the default keyword to assume when the argument is +not supplied. If left empty, @var{arg-default} (@pxref{arg-default}) or the +zero-valued keyword will be used. + +The syntax rules for identifying the option argument are: +@itemize @bullet +@item +If the option is specified with a flag character and there is a character +following the flag character, then string following that flag character is the +option argument. +@item +If the flag character is the last character in an argument, then +the first character of the next argument is examined. If it is a hyphen, +then the option is presumed to not have an argument. Otherwise, the entire +next argument is the argument for the option. +@item +If the option is specified with a long option name and that name is ended with +an equal sign character (@code{=}), then everything after that character is the +option argument. +@item +If the long name is ended by the end of the argument, then the first character +of the next argument is examined, just as with the flag character ending an +argument string. +@end itemize + +This is overridden and the options are required if the libopts library +gets configured with @option{--disable-optional-args}. + +@node arg-default +@subsubsection Default Option Argument Value +@vindex arg-default +This specifies the default option argument value to be used when the option is +not specified or preset. You may specify multiple @code{arg-default} values +if the argument type is @code{set membership}. + +@node Option Argument Handling +@subsection Option Argument Handling +@cindex Option Argument Handling + +AutoOpts will either specify or automatically generate callback procedures +for options that take specialized arguments. The only option argument types +that are not specialized are plain string arguments and no argument at all. +For options that fall into one of those two categories, you may specify your +own callback function, as specified below. If you do this and if you +specify that options are resettable (@pxref{automatic options}), then your +option handling code @strong{must} look for the @samp{OPTST_RESET} bit in +the @code{fOptState} field of the option descriptor. + +If the option takes a string argument, then the @code{stack-arg} attribute can +be used to specify that the option is to be handled by the @code{libopts} +@code{stackOptArg()} and @code{unstackOptArg()} library procedures (see +below). In this case, you may not provide option handling code. + +Finally, @samp{documentation} options (@pxref{opt-attr documentation}) may +also be marked as @option{settable} (@pxref{opt-attr settable}) and have +special callback functions (either @samp{flag-code}, @samp{extract-code}, +or @samp{call-proc}). + +@table @samp +@item flag-code +@vindex flag-code +statements to execute when the option is encountered. This may be used in +conjunction with option argument types that cause AutoOpts to emit handler +code. If you do this, the @samp{flag-code} with index zero (0) is emitted +into the handler code @emph{before} the argument is handled, and the entry +with index one (1) is handled afterward. + +The generated procedure will be laid out something like this: + +@example +static void +doOpt<name>(tOptions* pOptions, tOptDesc* pOptDesc) +@{ +<flag-code[0]> +<AutoOpts defined handler code> +<flag-code[1]> +@} +@end example + +Only certain fields within the @code{tOptions} and @code{tOptDesc} +structures may be accessed. @xref{Option Processing Data}. When writing +this code, you must be very careful with the @code{pOptions} pointer. The +handler code is called with this pointer set to special values for handling +special situations. Your code must handle them. As an example, +look at @code{optionEnumerationVal} in @file{enum.c}. + +@item extract-code +@vindex extract-code +This is effectively identical to @code{flag-code}, except that the +source is kept in the output file instead of the definitions file +and you cannot use this in conjunction with options with arguments, +other than string arguments. + +A long comment is used to demarcate the code. You must not modify +that marker. @i{Before} regenerating the option code file, +the old file is renamed from MUMBLE.c to MUMBLE.c.save. The template +will be looking there for the text to copy into the new output file. + +@item call-proc +@vindex call-proc +external procedure to call when option is encountered. The calling +sequence must conform to the sequence defined above for the generated +procedure, @code{doOpt<name>}. It has the same restrictions +regarding the fields within the structures passed in as arguments. +@xref{Option Processing Data}. + +@item flag-proc +@vindex flag-proc +Name of another option whose @code{flag-code} can be executed +when this option is encountered. + +@item stack-arg +@vindex stack-arg +Call a special library routine to stack the option's arguments. Special +macros in the interface file are provided for determining how many of the +options were found (@code{STACKCT_OPT(NAME)}) and to obtain a pointer to a +list of pointers to the argument values (@code{STACKLST_OPT(NAME)}). +Obviously, for a stackable argument, the @code{max} attribute +(@pxref{Common Attributes}) needs to be set higher than @code{1}. + +If this stacked argument option has a disablement prefix, then the entire +stack of arguments will be cleared by specifying the option with that +disablement prefix. + +@item unstack-arg +@vindex unstack-arg +Call a special library routine to remove (@code{unstack}) strings +from a @code{stack-arg} option stack. This attribute must name +the option that is to be @code{unstacked}. Neither this option nor +the stacked argument option it references may be equivalenced to +another option. +@end table + +@node Internationalizing Options +@subsection Internationalizing Options +@cindex Internationalizing Options + +Normally, AutoOpts produces usage text that is difficult to translate. It is +pieced together on the fly using words and phrases scattered around here and +there, piecing together toe document. This does not translate well. + +Incorporated into this package are some ways around the problem. First, you +should specify the @code{full-usage} and @code{short-usage} program attributes +(@pxref{program attributes}). This will enable your translators to translate +the usage text as a whole. + +Your translators will also be able to translate long option names. The option +name translations will then become the names searched for both on the command +line and in configuration files. However, it will not affect the names of +environment variable names used to configure your program. + +If it is considered desireable to keep configuration files in the @code{C} +locale, then several macros are available to suppress or delay the +translations of option names at run time. These are all disabled if +@code{ENABLE_NLS} is not defined at compile time or if @code{no-xlate} has +been set to the value @emph{anything}. These macros @strong{must} +be invoked before the first invocation of @code{optionProcess}. + +@table @samp +@item OPT_NO_XLAT_CFG_NAMES; +@itemx OPT_XLAT_CFG_NAMES; +Disable (or enable) the translations of option names for configuration files. +If you enable translation for config files, then they will be translated for +command line options. + +@item OPT_NO_XLAT_OPT_NAMES; +@itemx OPT_XLAT_OPT_NAMES; +Disable (or enable) the translations of option names for command line +processing. If you disable the translation for command line processing, +you will also disable it for configuration file processing. Once translated, +the option names will remain translated. +@end table + +@node documentation attributes +@subsection Man and Info doc Attributes +@cindex documentation attributes + +AutoOpts includes AutoGen templates for producing abbreviated man pages +and for producing the invoking section of an info document. To take +advantage of these templates, you must add several attributes to your +option definitions. + +@menu +* per option attributes:: Per option documentation attributes +* global option attributes:: Global documentation attributes +@end menu + +@node per option attributes +@subsubsection Per option documentation attributes + +These attributes are sub-attributes (@i{sub-stanzas}) of the @code{flag} stanzas. + +@table @samp +@item arg-name +@vindex arg-name +If an option has an argument, the argument should have a name for +documentation purposes. It will default to @code{arg-type}, but +it will likely be clearer with something else like, @code{file-name} +instead of @code{string} (the type). + +@item doc +@vindex doc +First, every @code{flag} definition @emph{other than} @code{documentation} +definitions, must have a @code{doc} attribute defined. If the option takes +an argument, then it will need an @code{arg-name} attribute as well. The +@code{doc} text should be in plain sentences with minimal formatting. The +Texinfo commands @code{@@code}, and @code{@@var} will have its enclosed text +made into @strong{\fB} entries in the man page, and the @code{@@file} text +will be made into @strong{\fI} entries. The @code{arg-name} attribute is +used to display the option's argument in the man page. + +Options marked with the @code{documentation} attribute are for documenting +the usage text. All other options should have the @code{doc} attribute in +order to document the usage of the option in the generated man pages. + +Since these blocks of text are inserted into all output forms, +any markup text included in these blocks must be massaged for each +output format. By default, it is presumed to be @file{texi} format. +@end table + +@node global option attributes +@subsubsection Global documentation attributes +@table @samp +@item cmd-section +@vindex cmd-section +If your command is a game or a system management command, +specify this attribute with the value @code{5} or @code{8}, respectively. +The default is a user command (section 1). + +@item detail +@vindex detail +This attribute is used to add a very short explanation about what +a program is used for when the @code{title} attribute is insufficient. +If there is no @code{doc-section} stanza of type @code{DESCRIPTION}, then +this text is used for the man page DESCRIPTION section, too. + +@item addtogroup +@vindex addtogroup +This attribute tells the template that the generated code should be +surrounded with the following doxygen comments: +@example +/** @@file <header-or-code-file-name> + * @@addtogroup <value-of-addtogroup> + * @@@{ + */ +@end example +@noindent +and +@example +/** @@@} */ +@end example + +@item option-format +@vindex option-format +Specify the default markup style for the @code{doc} stanzas. +By default, it is @code{texi}, but @code{man} and @code{mdoc} may +also be selected. There are nine converter programs that do a partial +job of converting one form of markup into another. @command{texi2texi}, +@command{man2man} and @command{mdoc2mdoc} work pretty well. + +You may also post process the document by using @code{doc-sub} stanzas, +see below. + +@item option-info +@vindex option-info +This text will be inserted as a lead-in paragraph in the @code{OPTIONS} +section of the generated man page. + +@item doc-section +@vindex doc-section +This is a compound attribute that requires three @i{sub}attributes: + +@table @i +@item ds-format +This describes the format of the associated @code{ds-text} section. +@code{man}, @code{mdoc} and @code{texi} formats are supported. +Regardless of the chosen format, the formatting tags in the output +text will be converted to @code{man} macros for @code{man} pages, +@code{mdoc} macros for @code{mdoc} pages, and @code{texi} macros for +@code{texinfo} pages. + +@item ds-text +This is the descriptive text, written according to the rules for +@code{ds-format} documents. + +@item ds-type +This describes the section type. Basically, the title of the section +that will be added to all output documentation. There may be only one +@code{doc-section} for any given @code{ds-type}. If there are duplicates, +the results are undefined (it might work, it might not). + +There are five categories of @code{ds-type} sections. +They are those that the documentation templates would otherwise: +@enumerate +@item +always create itself, ignoring any @code{ds-type}s by this name. +These are marked, below, as @code{ao-only}. +@item +create, if none was provided. +These are marked, @code{alternate}. +@item +create, but augment if the @code{doc-section} was provided. +These are marked, @code{augments}. +@item +do nothing, but inserts them into the output in a prescribed order. +These are marked, @code{known} +@item +knows nothing about them. They will be alphabetized and inserted +after the list of leading sections and before the list of trailing +sections. These are not marked because I don't know their names. +@end enumerate + +Some of these are emitted by the documentation templates only if +certain conditions are met. If there are conditions, they are +explained below. If there are no conditions, then you will always +see the named section in the output. + +The output sections will appear in this order: +@table @samp +@item NAME +@code{ao-only}. +@item SYNOPSIS +@code{alternate}. +@item DESCRIPTION +@code{augments}. +@item OPTIONS +@code{ao-only}. +@item OPTION PRESETS +@code{ao-only}, if environment presets or configuration file processing +has been specified. +@item unknown +At this point, the unknown, alphabetized sections are inserted. +@item IMPLEMENTATION NOTES +@code{known} +@item ENVIRONMENT +@code{augments}, if environment presets have been specified. +@item FILES +@code{augments}, if configuration file processing has been specified. +@item EXAMPLES +@code{known} +@item EXIT STATUS +@code{augments}. +@item ERRORS +@code{known} +@item COMPATIBILITY +@code{known} +@item SEE ALSO +@code{known} +@item CONFORMING TO +@code{known} +@item HISTORY +@code{known} +@item AUTHORS +@code{alternate}, if the @code{copyright} stanza has either +an @code{author} or an @code{owner} attribute. +@item COPYRIGHT +@code{alternate}, if there is a @code{copyright} stanza. +@item BUGS +@code{augments}, if the @code{copyright} stanza has an +@code{eaddr} attribute. +@item NOTES +@code{augments}. +@end table +@end table + +@noindent +Here is an example of a @code{doc-section} for a @code{SEE ALSO} type. + +@example +doc-section = @{ + ds-type = 'SEE ALSO'; // or anything else + ds-format = 'man'; // or texi or mdoc format + ds-text = <<-_EOText_ + text relevant to this section type, + in the chosen format + _EOText_; +@}; +@end example + +@item doc-sub +@vindex doc-sub +This attribute will cause the resulting documentation to be post-processed. +This is normally with @command{sed}, see @code{doc-sub-cmd} below. +This attribute has several sub-attributes: + +@table @samp +@item sub-name +This is the name of an autogen text definition value, like @code{prog-name} +or @code{version}. In the @code{sub-text} field, occurrences of this +name preceded by two less than characters and followed by two greater +than characters will be replaced by the text value of the definition, +e.g. @samp{<<prog-name>>}. + +@item sub-text +The text that gets added to the command file for the post processing +program. + +@item sub-type +If this command only applies to certain types of output, specify +this with a regular expression that will match one of the valid +output format types, e.g. @samp{man|mdoc} will match those two kinds, +but not @code{texi} output. If omitted, it will always apply. +@end table + +For example, if you want to reference the program name in the @code{doc} +text for an option common to two programs, put @samp{#PROG#} into the +text. The following will replace all occrrences of @samp{#PROG#} +with the current value for @code{prog}: +@example +doc-sub = @{ + sub-name = prog-name; + sub-text = 's/#PROG#/<<prog-name>>/g'; +@}; +@end example + +@item doc-sub-cmd +@vindex doc-sub-cmd +A formatting string for constructing the post-processing command. +The first parameter is the name of the file with editing commands in it, +and the second is the file containing the unprocessed document. +The default value is: +@example +sed -f %s %s +@end example +@end table + +@node automatic options +@subsection Automatically Supported Options +@cindex automatic options + +AutoOpts provides automated support for several options. @code{help} and +@code{more-help} are always provided. The others are conditional upon +various global program attributes being defined @xref{program attributes}. + +Below are the option names and default flag values. The flags are activated +if and only if at least one user-defined option also uses a flag value. The +long names are supported as option names if @code{long-opts} has been +specified. These option flags may be deleted or changed to characters of your +choosing by specifying +@vindex more-help-value +@vindex usage-value +@vindex version-value +@vindex load-opts-value +@vindex reset-value +@code{xxx-value = "y";}, where @code{xxx} is one of the option names below and +@code{y} is either empty or the character of your choice. For example, to +change the help flag from @code{?} to @code{h}, specify +@vindex help-value +@code{help-value = "h";}; and to require that @code{save-opts} be specified +only with its long option name, specify +@vindex save-opts-value +@code{save-opts-value = "";}. + +Additionally, the procedure that prints out the program version may be +replaced by specifying @code{version-proc}. +@vindex version-proc +This procedure must be defined to be of external scope (non-static). +By default, the AutoOpts library provides @code{optionPrintVersion} +and it will be the specified callback function in the option +definition structure. + +With the exception of the @code{load-opts} option, none of these automatically +supported options will be recognized in configuration files or environment +variables. + +@table @samp +@item help -? +This option will immediately invoke the @code{USAGE()} procedure +and display the usage line, a description of each option with +its description and option usage information. This is followed +by the contents of the definition of the @code{detail} text macro. + +@item more-help -! +This option is identical to the @code{help} option, except that the +output is passed through a pager program. (@code{more} by default, or +the program identified by the @code{PAGER} environment variable.) + +@item usage -u +This option must be requested by specifying, @code{usage-opt} in the option +definition file. It will produce abbreviated help text to @file{stdout} and +exit with zero status (@code{EXIT_SUCCESS}). + +@item version -v + +This will print the program name, title and version. If it is not +followed by anything or is followed by the letter @code{v}, just the +program name and version will be printed. If followed by the letter +@code{c} and a value for @code{copyright} and @code{owner} have been +provided, then the copyright will be printed, too. If it is followed by +the letter @code{n}, then the full copyright notice (if available) will +be printed. The @code{version} attribute must be specified in the +option definition file. + +Because some target platforms discourage optional arguments to options, +the autoopts library can be compiled with @code{NO_OPTIONAL_OPT_ARGS} +defined. Alternatively, the @code{version-type} attribute can be added +to the option definitions and it can specify which flavor is preferred. +In either case, an argument to the @code{--version} option will then be +disallowed. + +@item load-opts -< +@cindex configuration file +This option will load options from the named file. They will be treated +exactly as if they were loaded from the normally found configuration files, +but will not be loaded until the option is actually processed. This can also +be used within another configuration file, causing them to nest. This is the +@strong{only} automatically supported option that can be activated inside of +config files or with environment variables. + +Specifying the negated form of the option (@option{--no-load-opts}) will +suppress the processing of configuration files and environment variables. + +This option is activated by specifying one or more @code{homerc} attributes. + +@item save-opts -> +@cindex configuration file +This option will cause the option state to be printed in the configuration +file format when option processing is done but not yet verified for +consistency. The program will terminate successfully without running when +this has completed. Note that for most shells you will have to quote or +escape the flag character to restrict special meanings to the shell. + +The output file will be the configuration file name (default or provided by +@code{rcfile}) in the last directory named in a @code{homerc} definition. + +This option may be set from within your program by invoking the +"@code{SET_OPT_SAVE_OPTS(@i{filename})}" macro (@pxref{SET_OPT_name}). +Invoking this macro will set the file name for saving the option processing +state, but the state will @strong{not} actually be saved. You must call +@code{optionSaveFile} to do that (@pxref{libopts-optionSaveFile}). +@strong{CAVEAT:} if, after invoking this macro, you call +@code{optionProcess}, the option processing state will be saved to this file +and @code{optionProcess} will not return. You may wish to invoke +@code{CLEAR_OPT( SAVE_OPTS )} (@pxref{CLEAR_OPT}) beforehand if you do need +to reinvoke @code{optionProcess}. + +This option is activated by specifying one or more @code{homerc} attributes. + +The method of saving the state may be altered by specifying flags before +the output file name. ``Flags'' are specified by placing a list of them +before the file name and separating them from the name with one or two +greater-than characters (``>''). There are three flags currently supported: + +@table @samp +@item default +If an option has a default value (has not been set), then the default value +is inserted as a comment. + +@item usage +Every option that can be processed from the configuration file will have a +comment that contains the usage string that gets printed with the @code{--help} text + +@item update +Instead of removing the old file and writing a new one, the output file is kept, +but any pre-existing segment labeled with @code{<?program prog-name>} is removed. +The new program segment is placed at the end of the file. This flag is implied if +the flags are separated from the file name with doubled greater-than characters. +In other words, @code{update,usage > @i{file-name}} and @code{usage >> @i{file-name}} +are identical. +@end table + +@item reset-option -R +This option takes the name of an option for the current program and resets its +state such that it is set back to its original, compile-time initialized +value. If the option state is subsequently stored (via @option{--save-opts}), +the named option will not appear in that file. + +This option is activated by specifying the @code{resettable} attribute. + +@strong{BEWARE}: If the @code{resettable} attribute is specified, all +option callbacks @strong{must} look for the @code{OPTST_RESET} bit in the +@code{fOptState} field of the option descriptor. If set, the @code{optCookie} +and @code{optArg} fields will be unchanged from their last setting. When the +callback returns, these fields will be set to their original values. If you +use this feature and you have allocated data hanging off of the cookie, you +need to deallocate it. +@end table + +@node standard options +@subsection Library of Standard Options +@cindex standard options + +AutoOpts has developed a set of standardized options. +You may incorporate these options in your program simply by @emph{first} +adding a @code{#define} for the options you want, and then the line, + +@example +#include stdoptions.def +@end example + +@noindent +in your option definitions. The supported options are specified thus: + +@example +#define DEBUG +#define DIRECTORY +#define DRY_RUN +#define INPUT +#define INTERACTIVE +#define OUTPUT +#define WARN + +#define SILENT +#define QUIET +#define BRIEF +#define VERBOSE +@end example + +By default, only the long form of the option will be available. +To specify the short (flag) form, suffix these names with @code{_FLAG}. +e.g., + +@example +#define DEBUG_FLAG +@end example + +@option{--silent}, @option{--quiet}, @option{--brief} and @option{--verbose} +are related in that they all indicate some level of diagnostic output. These +options are all designed to conflict with each other. Instead of four +different options, however, several levels can be incorporated by +@code{#define}-ing @code{VERBOSE_ENUM}. In conjunction with @code{VERBOSE}, +it incorporates the notion of @i{5} levels in an enumeration: @code{silent}, +@code{quiet}, @code{brief}, @code{informative} and @code{verbose}; with the +default being @code{brief}. + +@ignore +END == AUTOOPTS-MAIN == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore +Here is an example program that uses the following set of definitions: + +@example +AutoGen Definitions options; + +prog-name = default-test; +prog-title = 'Default Option Example'; +homerc = '$$/../share/default-test', '$HOME', '.'; +environrc; +long-opts; +gnu-usage; +usage-opt; +version = '1.0'; +main = @{ + main-type = shell-process; +@}; +#define DEBUG_FLAG +#define WARN_FLAG +#define WARN_LEVEL +#define VERBOSE_FLAG +#define VERBOSE_ENUM +#define DRY_RUN_FLAG +#define OUTPUT_FLAG +#define INPUT_FLAG +#define DIRECTORY_FLAG +#define INTERACTIVE_FLAG +#include stdoptions.def +@end example + +@noindent +Running a few simple commands on that definition file: + +@example +autogen default-test.def +copts="-DTEST_DEFAULT_TEST_OPTS `autoopts-config cflags`" +lopts="`autoopts-config ldflags`" +cc -o default-test $@{copts@} default-test.c $@{lopts@} +@end example + +@noindent +Yields a program which, when run with @file{--help}, prints out: + +@example + +exit 0 +@end example +@ignore +START == AUTOOPTS-API == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@c === SECTION MARKER + +@node AutoOpts API +@section Programmatic Interface +@cindex AutoOpts API + +The user interface for access to the argument information is completely +defined in the generated header file and in the portions of the +distributed file "options.h" that are marked "public". + +In the following macros, text marked @var{<NAME>} or @var{name} +is the name of the option @strong{in upper case} and +@strong{segmented with underscores @code{_}}. The macros and enumerations +defined in the options header (interface) file are used as follows: + +To see how these @code{#define} macros are used in a program, +the reader is referred to the several @file{opts.h} files +included with the AutoGen sources. + +@menu +* Option Processing Data:: Data for Option Processing +* CLEAR_OPT:: CLEAR_OPT( <NAME> ) - Clear Option Markings +* COUNT_OPT:: COUNT_OPT( <NAME> ) - Definition Count +* DESC:: DESC( <NAME> ) - Option Descriptor +* DISABLE_OPT_name:: DISABLE_OPT_name - Disable an option +* ENABLED_OPT:: ENABLED_OPT( <NAME> ) - Is Option Enabled? +* ERRSKIP_OPTERR:: ERRSKIP_OPTERR - Ignore Option Errors +* ERRSTOP_OPTERR:: ERRSTOP_OPTERR - Stop on Errors +* HAVE_OPT:: HAVE_OPT( <NAME> ) - Have this option? +* ISSEL_OPT:: ISSEL_OPT( <NAME> ) - Is Option Selected? +* ISUNUSED_OPT:: ISUNUSED_OPT( <NAME> ) - Never Specified? +* OPTION_CT:: OPTION_CT - Full Count of Options +* OPT_ARG:: OPT_ARG( <NAME> ) - Option Argument String +* OPT_NO_XLAT_CFG_NAMES:: OPT_NO_XLAT_CFG_NAMES - option name xlation +* OPT_NO_XLAT_OPT_NAMES:: OPT_NO_XLAT_OPT_NAMES - option name xlation +* OPT_VALUE_name:: OPT_VALUE_name - Option Argument Value +* OPT_XLAT_CFG_NAMES:: OPT_XLAT_CFG_NAMES - option name xlation +* OPT_XLAT_OPT_NAMES:: OPT_XLAT_OPT_NAMES - option name xlation +* RESTART_OPT:: RESTART_OPT( n ) - Resume Option Processing +* SET_OPT_name:: SET_OPT_name - Force an option to be set +* STACKCT_OPT:: STACKCT_OPT( <NAME> ) - Stacked Arg Count +* STACKLST_OPT:: STACKLST_OPT( <NAME> ) - Argument Stack +* START_OPT:: START_OPT - Restart Option Processing +* STATE_OPT:: STATE_OPT( <NAME> ) - Option State +* USAGE:: USAGE( exit-code ) - Usage invocation macro +* VALUE_OPT_name:: VALUE_OPT_name - Option Flag Value +* VERSION:: VERSION - Version and Full Version +* WHICH_IDX_name:: WHICH_IDX_name - Which Equivalenced Index +* WHICH_OPT_name:: WHICH_OPT_name - Which Equivalenced Option +* teOptIndex:: teOptIndex - Option Index and Enumeration +* OPTIONS_STRUCT_VERSION:: OPTIONS_STRUCT_VERSION - active version +* libopts procedures:: libopts External Procedures +@end menu + +@node Option Processing Data +@subsection Data for Option Processing +@cindex Option Processing Data + +This section describes the data that may be accessed from within the +option processing callback routines. The following fields may be used +in the following ways and may be used for read only. The first set is +addressed from the @code{tOptDesc*} pointer: + +@table @samp +@cindex optIndex +@item optIndex +@cindex optValue +@item optValue +These may be used by option procedures to determine which option they +are working on (in case they handle several options). + +@cindex optActualIndex +@item optActualIndex +@cindex optActualValue +@item optActualValue +These may be used by option procedures to determine which option was +used to set the current option. This may be different from the above if +the options are members of an equivalence class. + +@cindex optOccCt +@item optOccCt +If AutoOpts is processing command line arguments, then this value will contain +the current occurrence count. During the option preset phase (reading +configuration files and examining environment variables), the value is zero. + +@cindex fOptState +@item fOptState +The field may be tested for the following bit values +(prefix each name with @code{OPTST_}, e.g. @code{OPTST_INIT}): + +@table @samp +@item INIT +Initial compiled value. As a bit test, it will always yield FALSE. + +@item SET +The option was set via the @code{SET_OPT()} macro. + +@item PRESET +@cindex configuration file +The option was set via a configuration file. + +@item DEFINED +The option was set via a command line option. + +@item SET_MASK +This is a mask of flags that show the set state, one of the +above four values. + +@item EQUIVALENCE +This bit is set when the option was selected by an equivalenced option. + +@item DISABLED +This bit is set if the option is to be disabled. +(Meaning it was a long option prefixed by the disablement prefix, or +the option has not been specified yet and initializes as @code{disabled}.) +@end table + +As an example of how this might be used, in AutoGen I want to allow +template writers to specify that the template output can be left +in a writable or read-only state. To support this, there is a Guile +function named @code{set-writable} (@pxref{SCM set-writable}). +Also, I provide for command options @option{--writable} and +@option{--not-writable}. I give precedence to command line and RC +file options, thus: + +@example +switch (STATE_OPT( WRITABLE )) @{ +case OPTST_DEFINED: +case OPTST_PRESET: + fprintf(stderr, zOverrideWarn, pCurTemplate->pzFileName, + pCurMacro->lineNo); + break; + +default: + if (gh_boolean_p( set ) && (set == SCM_BOOL_F)) + CLEAR_OPT( WRITABLE ); + else + SET_OPT_WRITABLE; +@} +@end example + +@cindex pzLastArg +@item pzLastArg +Pointer to the latest argument string. BEWARE@: If the argument type +is numeric, an enumeration or a bit mask, then this will be the +argument @strong{value} and not a pointer to a string. +@end table + +The following two fields are addressed from the @code{tOptions*} pointer: + +@table @samp +@cindex pzProgName +@item pzProgName +Points to a NUL-terminated string containing the current program +name, as retrieved from the argument vector. + +@cindex pzProgPath +@item pzProgPath +Points to a NUL-terminated string containing the full path of +the current program, as retrieved from the argument vector. +(If available on your system.) + +@end table + +Note@: these fields get filled in during the first call to +@code{optionProcess()}. All other fields are private, for the exclusive +use of AutoOpts code and are subject to change. + +@node CLEAR_OPT +@subsection CLEAR_OPT( <NAME> ) - Clear Option Markings +@findex CLEAR_OPT + +Make as if the option had never been specified. +@code{HAVE_OPT(<NAME>)} will yield @code{FALSE} +after invoking this macro. + +@node COUNT_OPT +@subsection COUNT_OPT( <NAME> ) - Definition Count +@findex COUNT_OPT + +This macro will tell you how many times the option was +specified on the command line. It does not include counts +of preset options. + +@example +if (COUNT_OPT( NAME ) != desired-count) @{ + make-an-undesirable-message. +@} +@end example + +@node DESC +@subsection DESC( <NAME> ) - Option Descriptor +@findex DESC + +This macro is used internally by other AutoOpt macros. +It is not for general use. It is used to obtain the option description +corresponding to its @strong{UPPER CASED} option name argument. +This is primarily used in other macro definitions. + +@node DISABLE_OPT_name +@subsection DISABLE_OPT_name - Disable an option +@findex DISABLE_OPT_name + +This macro is emitted if it is both settable +and it can be disabled. If it cannot be disabled, it may +always be CLEAR-ed (see above). + +The form of the macro will actually depend on whether the +option is equivalenced to another, and/or has an assigned +handler procedure. Unlike the @code{SET_OPT} macro, +this macro does not allow an option argument. + +@example +DISABLE_OPT_NAME; +@end example + +@node ENABLED_OPT +@subsection ENABLED_OPT( <NAME> ) - Is Option Enabled? +@findex ENABLED_OPT + +Yields true if the option defaults to disabled and +@code{ISUNUSED_OPT()} would yield true. It also yields true if +the option has been specified with a disablement prefix, +disablement value or the @code{DISABLE_OPT_NAME} macro was invoked. + +@node ERRSKIP_OPTERR +@subsection ERRSKIP_OPTERR - Ignore Option Errors +@findex ERRSKIP_OPTERR + +When it is necessary to continue (return to caller) +on option errors, invoke this option. It is reversible. +@xref{ERRSTOP_OPTERR}. + +@node ERRSTOP_OPTERR +@subsection ERRSTOP_OPTERR - Stop on Errors +@findex ERRSTOP_OPTERR + +After invoking this macro, if @code{optionProcess()} +encounters an error, it will call @code{exit(1)} rather than return. +This is the default processing mode. It can be overridden by +specifying @code{allow-errors} in the definitions file, +or invoking the macro @xref{ERRSKIP_OPTERR}. + +@node HAVE_OPT +@subsection HAVE_OPT( <NAME> ) - Have this option? +@findex HAVE_OPT + +This macro yields true if the option has been specified +in any fashion at all. It is used thus: + +@example +if (HAVE_OPT( NAME )) @{ + <do-things-associated-with-opt-name>; +@} +@end example + +@node ISSEL_OPT +@subsection ISSEL_OPT( <NAME> ) - Is Option Selected? +@findex ISSEL_OPT + +This macro yields true if the option has been +specified either on the command line or via a SET/DISABLE macro. + +@node ISUNUSED_OPT +@subsection ISUNUSED_OPT( <NAME> ) - Never Specified? +@findex ISUNUSED_OPT + +This macro yields true if the option has +never been specified, or has been cleared via the +@code{CLEAR_OPT()} macro. + +@node OPTION_CT +@subsection OPTION_CT - Full Count of Options +@findex OPTION_CT + +The full count of all options, both those defined +and those generated automatically by AutoOpts. This is primarily +used to initialize the program option descriptor structure. + +@node OPT_ARG +@subsection OPT_ARG( <NAME> ) - Option Argument String +@findex OPT_ARG + +The option argument value as a pointer to string. Note that argument +values that have been specified as numbers are stored as numbers or +keywords. For such options, use instead the @code{OPT_VALUE_name} +define. It is used thus: + +@example +if (HAVE_OPT( NAME )) @{ + char* p = OPT_ARG( NAME ); + <do-things-with-opt-name-argument-string>; +@} +@end example + +@node OPT_NO_XLAT_CFG_NAMES +@subsection OPT_NO_XLAT_CFG_NAMES - option name xlation +@findex OPT_NO_XLAT_CFG_NAMES + +Invoking this macro will disable the translation of option names only while +processing configuration files and environment variables. This must be +invoked before the first call to @code{optionProcess}.. You need not invoke +this if your option definition file contains the attribute assignment, +@code{no-xlate = opt-cfg;}. + +@node OPT_NO_XLAT_OPT_NAMES +@subsection OPT_NO_XLAT_OPT_NAMES - option name xlation +@findex OPT_NO_XLAT_OPT_NAMES + +Invoking this macro will completely disable the translation of option names. +This must be invoked before the first call to @code{optionProcess}. You need +not invoke this if your option definition file contains the attribute +assignment, @code{no-xlate = opt;}. + +@node OPT_VALUE_name +@subsection OPT_VALUE_name - Option Argument Value +@findex OPT_VALUE_name + +This macro gets emitted only for options that take numeric, keyword or set +membership arguments. The macro yields a word-sized integer containing the +enumeration, bit set or numeric value for the option argument. + +@example +int opt_val = OPT_VALUE_name; +@end example + +@node OPT_XLAT_CFG_NAMES +@subsection OPT_XLAT_CFG_NAMES - option name xlation +@findex OPT_XLAT_CFG_NAMES + +If @code{ENABLE_NLS} is defined and @code{no-xlate} has been not set to the +value @emph{anything}, this macro will cause the translation of option names +to happen before starting the processing of configuration files and +environment variables. This will change the recognition of options within the +@code{$PROGRAMNAME} environment variable, but will not alter the names used +for setting options via @code{$PROGRAMNAME_name} environment variables. + +This must be invoked before the first call to @code{optionProcess}. You might +need to use this macro if your option definition file contains the attribute +assignment, @code{no-xlate = opt;} or @code{no-xlate = opt-cfg;}, and +you have determined in some way that you wish to override that. + +@node OPT_XLAT_OPT_NAMES +@subsection OPT_XLAT_OPT_NAMES - option name xlation +@findex OPT_XLAT_OPT_NAMES + +If @code{ENABLE_NLS} is defined and @code{no-xlate} has been not set to the +value @emph{anything}, translate the option names before processing the +command line options. Long option names may thus be localized. (If the names +were translated before configuration processing, they will not be +re-translated.) + +This must be invoked before the first call to @code{optionProcess}. You might +need to use this macro if your option definition file contains the attribute +assignment, @code{no-xlate = opt;} and you have determined in some way that +you wish to override that. + +@node RESTART_OPT +@subsection RESTART_OPT( n ) - Resume Option Processing +@findex RESTART_OPT + +If option processing has stopped (either because of an error +or something was encountered that looked like a program argument), +it can be resumed by providing this macro with the index @code{n} +of the next option to process and calling @code{optionProcess()} again. + +@example +int main(int argc, char ** argv) @{ + for (int ai = 0; ai < argc ;) @{ + restart: + ai = optionProcess(&progOptions, argc, argv); + for (; ai < argc; ai++) @{ + char * arg = arg[ai]; + if (*arg == '-') @{ + RESTART_OPT(ai); + goto restart; + @} + process(arg); + @} + @} +@} +@end example + +If you want a program to operate this way, you might consider specifying a +@code{for-each} main function +(@pxref{main for-each, for-each main procedure}) with the @code{interleaved} +attribute. It will allow you to process interleaved operands and options from +either the command line or when reading them from standard input. + +@node SET_OPT_name +@subsection SET_OPT_name - Force an option to be set +@findex SET_OPT_name + +This macro gets emitted only when the given +option has the @code{settable} attribute specified. + +The form of the macro will actually depend on whether the option is +equivalenced to another, has an option argument and/or has an assigned +handler procedure. If the option has an argument, then this macro will +too. Beware that the argument is not reallocated, so the value must not +be on the stack or deallocated in any other way for as long as the value +might get referenced. + +If you have supplied at least one @file{homerc} file +(@pxref{program attributes}), this macro will be emitted for the +@option{--save-opts} option. + +@example +SET_OPT_SAVE_OPTS( "filename" ); +@end example + +@noindent +@xref{automatic options}, for a discussion of the implications of using +this particular example. + +@node STACKCT_OPT +@subsection STACKCT_OPT( <NAME> ) - Stacked Arg Count +@findex STACKCT_OPT + +When the option handling attribute is specified +as @code{stack_arg}, this macro may be used to determine how +many of them actually got stacked. + +Do not use this on options that have not been stacked or has not been +specified (the @code{stack_arg} attribute must have been specified, +and @code{HAVE_OPT(<NAME>)} must yield TRUE). +Otherwise, you will likely seg fault. + +@example +if (HAVE_OPT( NAME )) @{ + int ct = STACKCT_OPT( NAME ); + char** pp = STACKLST_OPT( NAME ); + + do @{ + char* p = *pp++; + do-things-with-p; + @} while (--ct > 0); +@} +@end example + +@node STACKLST_OPT +@subsection STACKLST_OPT( <NAME> ) - Argument Stack +@findex STACKLST_OPT + +The address of the list of pointers to the +option arguments. The pointers are ordered by the order in +which they were encountered in the option presets and +command line processing. + +Do not use this on options that have not been stacked or has not been +specified (the @code{stack_arg} attribute must have been specified, +and @code{HAVE_OPT(<OPTION>)} must yield TRUE). +Otherwise, you will likely seg fault. + +@example +if (HAVE_OPT( NAME )) @{ + int ct = STACKCT_OPT( NAME ); + char** pp = STACKLST_OPT( NAME ); + + do @{ + char* p = *pp++; + do-things-with-p; + @} while (--ct > 0); +@} +@end example + +@node START_OPT +@subsection START_OPT - Restart Option Processing +@findex START_OPT + +This is just a shortcut for RESTART_OPT(1) (@xref{RESTART_OPT}.) + +@node STATE_OPT +@subsection STATE_OPT( <NAME> ) - Option State +@findex STATE_OPT + +If you need to know if an option was set because of presetting actions +(configuration file processing or environment variables), versus a command +line entry versus one of the SET/DISABLE macros, then use this macro. It +will yield one of four values: @code{OPTST_INIT}, @code{OPTST_SET}, +@code{OPTST_PRESET} or @code{OPTST_DEFINED}. It is used thus: + +@example +switch (STATE_OPT( NAME )) @{ + case OPTST_INIT: + not-preset, set or on the command line. (unless CLEAR-ed) + + case OPTST_SET: + option set via the SET_OPT_NAME() macro. + + case OPTST_PRESET: + option set via an configuration file or environment variable + + case OPTST_DEFINED: + option set via a command line option. + + default: + cannot happen :) +@} +@end example + +@node USAGE +@subsection USAGE( exit-code ) - Usage invocation macro +@findex USAGE + +This macro invokes the procedure registered to display +the usage text. Normally, this will be @code{optionUsage} from the +AutoOpts library, but you may select another procedure by specifying +@code{usage = "proc_name"} program attribute. This procedure must +take two arguments@: first, a pointer to the option descriptor, and +second the exit code. The macro supplies the option descriptor +automatically. This routine is expected to call @code{exit(3)} with +the provided exit code. + +The @code{optionUsage} routine also behaves differently depending +on the exit code: + +@table @code +@item EXIT_SUCCESS (the value zero) +It is assumed that full usage help has been requested. Consequently, more +information is provided than when displaying usage and exiting with a +non-zero exit code. Output will be sent to @file{stdout} and the program will +exit with a zero status code. + +@item EX_USAGE (64) +The abbreviated usage will be printed to @file{stdout} and the program will +exit with a zero status code. @code{EX_USAGE} may or may not be 64. If your +system provides @file{/usr/include/sysexits.h} that has a different value, +then that value will be used. + +@item any other value +The abbreviated usage will be printed to stderr and the program will +exit with the provided status code. +@end table + +@node VALUE_OPT_name +@subsection VALUE_OPT_name - Option Flag Value +@findex VALUE_OPT_name + +This is a #define for the flag character used to +specify an option on the command line. If @code{value} was not +specified for the option, then it is a unique number associated +with the option. @code{option value} refers to this value, +@code{option argument} refers to the (optional) argument to the +option. + +@example +switch (WHICH_OPT_OTHER_OPT) @{ +case VALUE_OPT_NAME: + this-option-was-really-opt-name; +case VALUE_OPT_OTHER_OPT: + this-option-was-really-other-opt; +@} +@end example + +@node VERSION +@subsection VERSION - Version and Full Version +@findex VERSION + +If the @code{version} attribute is defined for the program, +then a stringified version will be #defined as PROGRAM_VERSION and +PROGRAM_FULL_VERSION. PROGRAM_FULL_VERSION is used for printing +the program version in response to the version option. The version +option is automatically supplied in response to this attribute, too. + +You may access PROGRAM_VERSION via @code{programOptions.pzFullVersion}. + +@node WHICH_IDX_name +@subsection WHICH_IDX_name - Which Equivalenced Index +@findex WHICH_IDX_name + +This macro gets emitted only for equivalenced-to options. It is used to +obtain the index for the one of the several equivalence class members +set the equivalenced-to option. + +@example +switch (WHICH_IDX_OTHER_OPT) @{ +case INDEX_OPT_NAME: + this-option-was-really-opt-name; +case INDEX_OPT_OTHER_OPT: + this-option-was-really-other-opt; +@} +@end example + +@node WHICH_OPT_name +@subsection WHICH_OPT_name - Which Equivalenced Option +@findex WHICH_OPT_name + +This macro gets emitted only for equivalenced-to options. It is used to +obtain the value code for the one of the several equivalence class members +set the equivalenced-to option. + +@example +switch (WHICH_OPT_OTHER_OPT) @{ +case VALUE_OPT_NAME: + this-option-was-really-opt-name; +case VALUE_OPT_OTHER_OPT: + this-option-was-really-other-opt; +@} +@end example + +@node teOptIndex +@subsection teOptIndex - Option Index and Enumeration +@findex teOptIndex + +This enum defines the complete set of options, both +user specified and automatically provided. This can be used, +for example, to distinguish which of the equivalenced options +was actually used. + +@example +switch (pOptDesc->optActualIndex) @{ +case INDEX_OPT_FIRST: + stuff; +case INDEX_OPT_DIFFERENT: + different-stuff; +default: + unknown-things; +@} +@end example + +@node OPTIONS_STRUCT_VERSION +@subsection OPTIONS_STRUCT_VERSION - active version + +You will not actually need to reference this value, but you need to be +aware that it is there. It is the first value in the option descriptor +that you pass to @code{optionProcess}. It contains a magic number and +version information. Normally, you should be able to work with a more +recent option library than the one you compiled with. However, if the +library is changed incompatibly, then the library will detect the out of +date magic marker, explain the difficulty and exit. You will then need +to rebuild and recompile your option definitions. This has rarely been +necessary. + +@ignore +END == AUTOOPTS-API == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore +@node libopts procedures +@subsection libopts External Procedures + +These are the routines that libopts users may call directly from their +code. There are several other routines that can be called by code +generated by the libopts option templates, but they are not to be +called from any other user code. The @file{options.h} header is +fairly clear about this, too. + +@menu +* libopts-ao_string_tokenize:: ao_string_tokenize +* libopts-configFileLoad:: configFileLoad +* libopts-optionFileLoad:: optionFileLoad +* libopts-optionFindNextValue:: optionFindNextValue +* libopts-optionFindValue:: optionFindValue +* libopts-optionFree:: optionFree +* libopts-optionGetValue:: optionGetValue +* libopts-optionLoadLine:: optionLoadLine +* libopts-optionMemberList:: optionMemberList +* libopts-optionNextValue:: optionNextValue +* libopts-optionOnlyUsage:: optionOnlyUsage +* libopts-optionPrintVersion:: optionPrintVersion +* libopts-optionPrintVersionAndReturn:: optionPrintVersionAndReturn +* libopts-optionProcess:: optionProcess +* libopts-optionRestore:: optionRestore +* libopts-optionSaveFile:: optionSaveFile +* libopts-optionSaveState:: optionSaveState +* libopts-optionUnloadNested:: optionUnloadNested +* libopts-optionVersion:: optionVersion +* libopts-strequate:: strequate +* libopts-streqvcmp:: streqvcmp +* libopts-streqvmap:: streqvmap +* libopts-strneqvcmp:: strneqvcmp +* libopts-strtransform:: strtransform +@end menu + +This subsection was automatically generated by AutoGen +using extracted information and the aginfo3.tpl template. + +@node libopts-ao_string_tokenize +@subsubsection ao_string_tokenize +@findex ao_string_tokenize + +tokenize an input string + +@noindent +Usage: +@example +token_list_t * res = ao_string_tokenize( string ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab string @tab @code{char const *} +@tab string to be tokenized +@item @tab returns @tab token_list_t * +@tab pointer to a structure that lists each token +@end multitable + +This function will convert one input string into a list of strings. +The list of strings is derived by separating the input based on +white space separation. However, if the input contains either single +or double quote characters, then the text after that character up to +a matching quote will become the string in the list. + +The returned pointer should be deallocated with @code{free(3C)} when +are done using the data. The data are placed in a single block of +allocated memory. Do not deallocate individual token/strings. + +The structure pointed to will contain at least these two fields: +@table @samp +@item tkn_ct +The number of tokens found in the input string. +@item tok_list +An array of @code{tkn_ct + 1} pointers to substring tokens, with +the last pointer set to NULL. +@end table + +There are two types of quoted strings: single quoted (@code{'}) and +double quoted (@code{"}). Singly quoted strings are fairly raw in that +escape characters (@code{\\}) are simply another character, except when +preceding the following characters: +@example +@code{\\} double backslashes reduce to one +@code{'} incorporates the single quote into the string +@code{\n} suppresses both the backslash and newline character +@end example + +Double quote strings are formed according to the rules of string +constants in ANSI-C programs. + +NULL is returned and @code{errno} will be set to indicate the problem: +@itemize @bullet +@item +@code{EINVAL} - There was an unterminated quoted string. +@item +@code{ENOENT} - The input string was empty. +@item +@code{ENOMEM} - There is not enough memory. +@end itemize + + +@node libopts-configFileLoad +@subsubsection configFileLoad +@findex configFileLoad + +parse a configuration file + +@noindent +Usage: +@example +const tOptionValue * res = configFileLoad( fname ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab fname @tab @code{char const *} +@tab the file to load +@item @tab returns @tab const tOptionValue * +@tab An allocated, compound value structure +@end multitable + +This routine will load a named configuration file and parse the +text as a hierarchically valued option. The option descriptor +created from an option definition file is not used via this interface. +The returned value is "named" with the input file name and is of +type "@code{OPARG_TYPE_HIERARCHY}". It may be used in calls to +@code{optionGetValue()}, @code{optionNextValue()} and +@code{optionUnloadNested()}. + +If the file cannot be loaded or processed, @code{NULL} is returned and +@var{errno} is set. It may be set by a call to either @code{open(2)} +@code{mmap(2)} or other file system calls, or it may be: +@itemize @bullet +@item +@code{ENOENT} - the file was not found. +@item +@code{ENOMSG} - the file was empty. +@item +@code{EINVAL} - the file contents are invalid -- not properly formed. +@item +@code{ENOMEM} - not enough memory to allocate the needed structures. +@end itemize + + +@node libopts-optionFileLoad +@subsubsection optionFileLoad +@findex optionFileLoad + +Load the locatable config files, in order + +@noindent +Usage: +@example +int res = optionFileLoad( opts, prog ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab opts @tab @code{tOptions *} +@tab program options descriptor + +@item @tab prog @tab @code{char const *} +@tab program name +@item @tab returns @tab int +@tab 0 -> SUCCESS, -1 -> FAILURE +@end multitable + +This function looks in all the specified directories for a configuration +file ("rc" file or "ini" file) and processes any found twice. The first +time through, they are processed in reverse order (last file first). At +that time, only "immediate action" configurables are processed. For +example, if the last named file specifies not processing any more +configuration files, then no more configuration files will be processed. +Such an option in the @strong{first} named directory will have no effect. + +Once the immediate action configurables have been handled, then the +directories are handled in normal, forward order. In that way, later +config files can override the settings of earlier config files. + +See the AutoOpts documentation for a thorough discussion of the +config file format. + +Configuration files not found or not decipherable are simply ignored. + +Returns the value, "-1" if the program options descriptor +is out of date or indecipherable. Otherwise, the value "0" will +always be returned. + + +@node libopts-optionFindNextValue +@subsubsection optionFindNextValue +@findex optionFindNextValue + +find a hierarcicaly valued option instance + +@noindent +Usage: +@example +const tOptionValue * res = optionFindNextValue( odesc, pPrevVal, name, value ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab odesc @tab @code{const tOptDesc *} +@tab an option with a nested arg type + +@item @tab pPrevVal @tab @code{const tOptionValue *} +@tab the last entry + +@item @tab name @tab @code{char const *} +@tab name of value to find + +@item @tab value @tab @code{char const *} +@tab the matching value +@item @tab returns @tab const tOptionValue * +@tab a compound value structure +@end multitable + +This routine will find the next entry in a nested value option or +configurable. It will search through the list and return the next entry +that matches the criteria. + +The returned result is NULL and errno is set: +@itemize @bullet +@item +@code{EINVAL} - the @code{pOptValue} does not point to a valid +hierarchical option value. +@item +@code{ENOENT} - no entry matched the given name. +@end itemize + + +@node libopts-optionFindValue +@subsubsection optionFindValue +@findex optionFindValue + +find a hierarcicaly valued option instance + +@noindent +Usage: +@example +const tOptionValue * res = optionFindValue( odesc, name, val ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab odesc @tab @code{const tOptDesc *} +@tab an option with a nested arg type + +@item @tab name @tab @code{char const *} +@tab name of value to find + +@item @tab val @tab @code{char const *} +@tab the matching value +@item @tab returns @tab const tOptionValue * +@tab a compound value structure +@end multitable + +This routine will find an entry in a nested value option or configurable. +It will search through the list and return a matching entry. + +The returned result is NULL and errno is set: +@itemize @bullet +@item +@code{EINVAL} - the @code{pOptValue} does not point to a valid +hierarchical option value. +@item +@code{ENOENT} - no entry matched the given name. +@end itemize + + +@node libopts-optionFree +@subsubsection optionFree +@findex optionFree + +free allocated option processing memory + +@noindent +Usage: +@example +optionFree( pOpts ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab pOpts @tab @code{tOptions *} +@tab program options descriptor +@end multitable + +AutoOpts sometimes allocates memory and puts pointers to it in the +option state structures. This routine deallocates all such memory. + +As long as memory has not been corrupted, +this routine is always successful. + + +@node libopts-optionGetValue +@subsubsection optionGetValue +@findex optionGetValue + +get a specific value from a hierarcical list + +@noindent +Usage: +@example +const tOptionValue * res = optionGetValue( pOptValue, valueName ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab pOptValue @tab @code{const tOptionValue *} +@tab a hierarchcal value + +@item @tab valueName @tab @code{char const *} +@tab name of value to get +@item @tab returns @tab const tOptionValue * +@tab a compound value structure +@end multitable + +This routine will find an entry in a nested value option or configurable. +If "valueName" is NULL, then the first entry is returned. Otherwise, +the first entry with a name that exactly matches the argument will be +returned. If there is no matching value, NULL is returned and errno is +set to ENOENT. If the provided option value is not a hierarchical value, +NULL is also returned and errno is set to EINVAL. + +The returned result is NULL and errno is set: +@itemize @bullet +@item +@code{EINVAL} - the @code{pOptValue} does not point to a valid +hierarchical option value. +@item +@code{ENOENT} - no entry matched the given name. +@end itemize + + +@node libopts-optionLoadLine +@subsubsection optionLoadLine +@findex optionLoadLine + +process a string for an option name and value + +@noindent +Usage: +@example +optionLoadLine( opts, line ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab opts @tab @code{tOptions *} +@tab program options descriptor + +@item @tab line @tab @code{char const *} +@tab NUL-terminated text +@end multitable + +This is a client program callable routine for setting options from, for +example, the contents of a file that they read in. Only one option may +appear in the text. It will be treated as a normal (non-preset) option. + +When passed a pointer to the option struct and a string, it will find +the option named by the first token on the string and set the option +argument to the remainder of the string. The caller must NUL terminate +the string. The caller need not skip over any introductory hyphens. +Any embedded new lines will be included in the option +argument. If the input looks like one or more quoted strings, then the +input will be "cooked". The "cooking" is identical to the string +formation used in AutoGen definition files (@pxref{basic expression}), +except that you may not use backquotes. + +Invalid options are silently ignored. Invalid option arguments +will cause a warning to print, but the function should return. + + +@node libopts-optionMemberList +@subsubsection optionMemberList +@findex optionMemberList + +Get the list of members of a bit mask set + +@noindent +Usage: +@example +char * res = optionMemberList( od ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab od @tab @code{tOptDesc *} +@tab the set membership option description +@item @tab returns @tab char * +@tab the names of the set bits +@end multitable + +This converts the OPT_VALUE_name mask value to a allocated string. +It is the caller's responsibility to free the string. + + +@node libopts-optionNextValue +@subsubsection optionNextValue +@findex optionNextValue + +get the next value from a hierarchical list + +@noindent +Usage: +@example +const tOptionValue * res = optionNextValue( pOptValue, pOldValue ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab pOptValue @tab @code{const tOptionValue *} +@tab a hierarchcal list value + +@item @tab pOldValue @tab @code{const tOptionValue *} +@tab a value from this list +@item @tab returns @tab const tOptionValue * +@tab a compound value structure +@end multitable + +This routine will return the next entry after the entry passed in. At the +end of the list, NULL will be returned. If the entry is not found on the +list, NULL will be returned and "@var{errno}" will be set to EINVAL. +The "@var{pOldValue}" must have been gotten from a prior call to this +routine or to "@code{opitonGetValue()}". + +The returned result is NULL and errno is set: +@itemize @bullet +@item +@code{EINVAL} - the @code{pOptValue} does not point to a valid +hierarchical option value or @code{pOldValue} does not point to a +member of that option value. +@item +@code{ENOENT} - the supplied @code{pOldValue} pointed to the last entry. +@end itemize + + +@node libopts-optionOnlyUsage +@subsubsection optionOnlyUsage +@findex optionOnlyUsage + +Print usage text for just the options + +@noindent +Usage: +@example +optionOnlyUsage( pOpts, ex_code ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab pOpts @tab @code{tOptions *} +@tab program options descriptor + +@item @tab ex_code @tab @code{int} +@tab exit code for calling exit(3) +@end multitable + +This routine will print only the usage for each option. +This function may be used when the emitted usage must incorporate +information not available to AutoOpts. + + +@node libopts-optionPrintVersion +@subsubsection optionPrintVersion +@findex optionPrintVersion + +Print the program version + +@noindent +Usage: +@example +optionPrintVersion( opts, od ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab opts @tab @code{tOptions *} +@tab program options descriptor + +@item @tab od @tab @code{tOptDesc *} +@tab the descriptor for this arg +@end multitable + +This routine will print the version to stdout. + + +@node libopts-optionPrintVersionAndReturn +@subsubsection optionPrintVersionAndReturn +@findex optionPrintVersionAndReturn + +Print the program version + +@noindent +Usage: +@example +optionPrintVersionAndReturn( opts, od ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab opts @tab @code{tOptions *} +@tab program options descriptor + +@item @tab od @tab @code{tOptDesc *} +@tab the descriptor for this arg +@end multitable + +This routine will print the version to stdout and return +instead of exiting. Please see the source for the +@code{print_ver} funtion for details on selecting how +verbose to be after this function returns. + + +@node libopts-optionProcess +@subsubsection optionProcess +@findex optionProcess + +this is the main option processing routine + +@noindent +Usage: +@example +int res = optionProcess( opts, a_ct, a_v ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab opts @tab @code{tOptions *} +@tab program options descriptor + +@item @tab a_ct @tab @code{int} +@tab program arg count + +@item @tab a_v @tab @code{char **} +@tab program arg vector +@item @tab returns @tab int +@tab the count of the arguments processed +@end multitable + +This is the main entry point for processing options. It is intended +that this procedure be called once at the beginning of the execution of +a program. Depending on options selected earlier, it is sometimes +necessary to stop and restart option processing, or to select completely +different sets of options. This can be done easily, but you generally +do not want to do this. + +The number of arguments processed always includes the program name. +If one of the arguments is "--", then it is counted and the processing +stops. If an error was encountered and errors are to be tolerated, then +the returned value is the index of the argument causing the error. +A hyphen by itself ("-") will also cause processing to stop and will +@emph{not} be counted among the processed arguments. A hyphen by itself +is treated as an operand. Encountering an operand stops option +processing. + +Errors will cause diagnostics to be printed. @code{exit(3)} may +or may not be called. It depends upon whether or not the options +were generated with the "allow-errors" attribute, or if the +ERRSKIP_OPTERR or ERRSTOP_OPTERR macros were invoked. + + +@node libopts-optionRestore +@subsubsection optionRestore +@findex optionRestore + +restore option state from memory copy + +@noindent +Usage: +@example +optionRestore( pOpts ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab pOpts @tab @code{tOptions *} +@tab program options descriptor +@end multitable + +Copy back the option state from saved memory. +The allocated memory is left intact, so this routine can be +called repeatedly without having to call optionSaveState again. +If you are restoring a state that was saved before the first call +to optionProcess(3AO), then you may change the contents of the +argc/argv parameters to optionProcess. + +If you have not called @code{optionSaveState} before, a diagnostic is +printed to @code{stderr} and exit is called. + + +@node libopts-optionSaveFile +@subsubsection optionSaveFile +@findex optionSaveFile + +saves the option state to a file + +@noindent +Usage: +@example +optionSaveFile( opts ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab opts @tab @code{tOptions *} +@tab program options descriptor +@end multitable + +This routine will save the state of option processing to a file. The name +of that file can be specified with the argument to the @code{--save-opts} +option, or by appending the @code{rcfile} attribute to the last +@code{homerc} attribute. If no @code{rcfile} attribute was specified, it +will default to @code{.@i{programname}rc}. If you wish to specify another +file, you should invoke the @code{SET_OPT_SAVE_OPTS(@i{filename})} macro. + +The recommend usage is as follows: +@example +optionProcess(&progOptions, argc, argv); +if (i_want_a_non_standard_place_for_this) +SET_OPT_SAVE_OPTS("myfilename"); +optionSaveFile(&progOptions); +@end example + +If no @code{homerc} file was specified, this routine will silently return +and do nothing. If the output file cannot be created or updated, a message +will be printed to @code{stderr} and the routine will return. + + +@node libopts-optionSaveState +@subsubsection optionSaveState +@findex optionSaveState + +saves the option state to memory + +@noindent +Usage: +@example +optionSaveState( pOpts ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab pOpts @tab @code{tOptions *} +@tab program options descriptor +@end multitable + +This routine will allocate enough memory to save the current option +processing state. If this routine has been called before, that memory +will be reused. You may only save one copy of the option state. This +routine may be called before optionProcess(3AO). If you do call it +before the first call to optionProcess, then you may also change the +contents of argc/argv after you call optionRestore(3AO) + +In fact, more strongly put: it is safest to only use this function +before having processed any options. In particular, the saving and +restoring of stacked string arguments and hierarchical values is +disabled. The values are not saved. + +If it fails to allocate the memory, +it will print a message to stderr and exit. +Otherwise, it will always succeed. + + +@node libopts-optionUnloadNested +@subsubsection optionUnloadNested +@findex optionUnloadNested + +Deallocate the memory for a nested value + +@noindent +Usage: +@example +optionUnloadNested( pOptVal ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab pOptVal @tab @code{tOptionValue const *} +@tab the hierarchical value +@end multitable + +A nested value needs to be deallocated. The pointer passed in should +have been gotten from a call to @code{configFileLoad()} (See +@pxref{libopts-configFileLoad}). + + +@node libopts-optionVersion +@subsubsection optionVersion +@findex optionVersion + +return the compiled AutoOpts version number + +@noindent +Usage: +@example +char const * res = optionVersion(); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab returns @tab char const * +@tab the version string in constant memory +@end multitable + +Returns the full version string compiled into the library. +The returned string cannot be modified. + + +@node libopts-strequate +@subsubsection strequate +@findex strequate + +map a list of characters to the same value + +@noindent +Usage: +@example +strequate( ch_list ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab ch_list @tab @code{char const *} +@tab characters to equivalence +@end multitable + +Each character in the input string get mapped to the first character +in the string. +This function name is mapped to option_strequate so as to not conflict +with the POSIX name space. + +none. + + +@node libopts-streqvcmp +@subsubsection streqvcmp +@findex streqvcmp + +compare two strings with an equivalence mapping + +@noindent +Usage: +@example +int res = streqvcmp( str1, str2 ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab str1 @tab @code{char const *} +@tab first string + +@item @tab str2 @tab @code{char const *} +@tab second string +@item @tab returns @tab int +@tab the difference between two differing characters +@end multitable + +Using a character mapping, two strings are compared for "equivalence". +Each input character is mapped to a comparison character and the +mapped-to characters are compared for the two NUL terminated input strings. +This function name is mapped to option_streqvcmp so as to not conflict +with the POSIX name space. + +none checked. Caller responsible for seg faults. + + +@node libopts-streqvmap +@subsubsection streqvmap +@findex streqvmap + +Set the character mappings for the streqv functions + +@noindent +Usage: +@example +streqvmap( from, to, ct ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab from @tab @code{char} +@tab Input character + +@item @tab to @tab @code{char} +@tab Mapped-to character + +@item @tab ct @tab @code{int} +@tab compare length +@end multitable + +Set the character mapping. If the count (@code{ct}) is set to zero, then +the map is cleared by setting all entries in the map to their index +value. Otherwise, the "@code{From}" character is mapped to the "@code{To}" +character. If @code{ct} is greater than 1, then @code{From} and @code{To} +are incremented and the process repeated until @code{ct} entries have been +set. For example, +@example +streqvmap('a', 'A', 26); +@end example +@noindent +will alter the mapping so that all English lower case letters +will map to upper case. + +This function name is mapped to option_streqvmap so as to not conflict +with the POSIX name space. + +none. + + +@node libopts-strneqvcmp +@subsubsection strneqvcmp +@findex strneqvcmp + +compare two strings with an equivalence mapping + +@noindent +Usage: +@example +int res = strneqvcmp( str1, str2, ct ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab str1 @tab @code{char const *} +@tab first string + +@item @tab str2 @tab @code{char const *} +@tab second string + +@item @tab ct @tab @code{int} +@tab compare length +@item @tab returns @tab int +@tab the difference between two differing characters +@end multitable + +Using a character mapping, two strings are compared for "equivalence". +Each input character is mapped to a comparison character and the +mapped-to characters are compared for the two NUL terminated input strings. +The comparison is limited to @code{ct} bytes. +This function name is mapped to option_strneqvcmp so as to not conflict +with the POSIX name space. + +none checked. Caller responsible for seg faults. + + +@node libopts-strtransform +@subsubsection strtransform +@findex strtransform + +convert a string into its mapped-to value + +@noindent +Usage: +@example +strtransform( dest, src ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab dest @tab @code{char *} +@tab output string + +@item @tab src @tab @code{char const *} +@tab input string +@end multitable + +Each character in the input string is mapped and the mapped-to +character is put into the output. +This function name is mapped to option_strtransform so as to not conflict +with the POSIX name space. + +The source and destination may be the same. + +none. +@ignore +START == AUTOOPTS-DATA == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@c === SECTION MARKER + +@node Multi-Threading +@section Multi-Threading + +AutoOpts was designed to configure a program for running. This generally +happens before much real work has been started. Consequently, it is +expected to be run before multi-threaded applications have started multiple +threads. However, this is not always the case. Some applications may +need to reset and reload their running configuration, and some may use +@code{SET_OPT_xxx()} macros during processing. If you need to dynamically +change your option configuration in your multi-threaded application, it is +your responsibility to prevent all threads from accessing the option +configuration state, except the one altering the configuration. + +The various accessor macros (@code{HAVE_OPT()}, etc.) do not modify state +and are safe to use in a multi-threaded application. It is safe as long +as no other thread is concurrently modifying state, of course. + +@c === SECTION MARKER + +@node option descriptor +@section Option Descriptor File +@cindex option descriptor + +This is the module that is to be compiled and linked with your program. +It contains internal data and procedures subject to change. Basically, +it contains a single global data structure containing all the +information provided in the option definitions, plus a number of static +strings and any callout procedures that are specified or required. You +should never have need for looking at this, except, perhaps, to examine +the code generated for implementing the @code{flag-code} construct. + +@c === SECTION MARKER + +@node Using AutoOpts +@section Using AutoOpts +@cindex using AutoOpts + +There are actually several levels of @code{using} autoopts. +Which you choose depends upon how you plan to distribute +(or not) your application. + +@menu +* local use:: local-only use +* binary not installed:: binary distro, AutoOpts not installed +* binary pre-installed:: binary distro, AutoOpts pre-installed +* source pre-installed:: source distro, AutoOpts pre-installed +* source not installed:: source distro, AutoOpts not installed +@end menu + +@node local use +@subsection local-only use + +To use AutoOpts in your application where you do not have to +worry about distribution issues, your issues are simple and few. + +@itemize @bullet +@item +Create a file @samp{myopts.def}, according to the documentation above. +It is probably easiest to start with the example in @ref{Quick Start} +and edit it into the form you need. + +@item +Run AutoGen to create the option interface file (@code{myopts.h}) +and the option descriptor code (@code{myopts.c}): + +@example +autogen myopts.def +@end example + +@item +In all your source files where you need to refer to option state, +@code{#include "myopts.h"}. +@item +In your main routine, code something along the lines of: + +@example +#define ARGC_MIN some-lower-limit +#define ARGC_MAX some-upper-limit +main( int argc, char** argv ) +@{ + @{ + int arg_ct = optionProcess( &myprogOptions, argc, argv ); + argc -= arg_ct; + if ((argc < ARGC_MIN) || (argc > ARGC_MAX)) @{ + fprintf( stderr, "%s ERROR: remaining args (%d) " + "out of range\n", myprogOptions.pzProgName, + argc ); + + USAGE( EXIT_FAILURE ); + @} + argv += arg_ct; + @} + if (HAVE_OPT(OPTN_NAME)) + respond_to_optn_name(); + ... +@} +@end example + +@item +Compile @samp{myopts.c} and link your program +with the following additional arguments: + +@example +`autoopts-config cflags ldflags` myopts.c +@end example +@end itemize + +@node binary not installed +@subsection binary distro, AutoOpts not installed + +If you will be distributing (or copying) your project to a system that +does not have AutoOpts installed, you will need to statically link the +AutoOpts library, @code{libopts} into your program. Get the link information +with @code{static-libs} instead of @code{ldflags}: + +@example +`autoopts-config static-libs` +@end example + +@node binary pre-installed +@subsection binary distro, AutoOpts pre-installed + +If you will be distributing (or copying) your project to a system that does +have AutoOpts (or only @code{libopts}) installed, you will still need to +ensure that the library is findable at program load time, or you will still +have to statically link. The former can be accomplished by linking your +project with @option{--rpath} or by setting the @env{LD_LIBRARY_PATH} +appropriately. Otherwise, @xref{binary not installed}. + +@node source pre-installed +@subsection source distro, AutoOpts pre-installed + +If you will be distributing your project to a system that will build +your product but it may not be pre-installed with AutoOpts, you will +need to do some configuration checking before you start the build. +Assuming you are willing to fail the build if AutoOpts has not been +installed, you will still need to do a little work. + +AutoOpts is distributed with a configuration check M4 script, +@file{autoopts.m4}. It will add an @code{autoconf} macro named, +@code{AG_PATH_AUTOOPTS}. Add this to your @file{configure.ac} script +and use the following substitution values: + +@table @code +@item AUTOGEN +the name of the autogen executable +@item AUTOGEN_TPLIB +the directory where AutoGen template library is stored +@item AUTOOPTS_CFLAGS +the compile time options needed to find the AutoOpts headers +@item AUTOOPTS_LIBS +the link options required to access the @code{libopts} library +@end table + +@node source not installed +@subsection source distro, AutoOpts not installed + +If you will be distributing your project to a system that will build +your product but it may not be pre-installed with AutoOpts, you may +wish to incorporate the sources for @code{libopts} in your project. +To do this, I recommend reading the tear-off libopts library +@file{README} that you can find in the @file{pkg/libopts} directory. +You can also examine an example package (blocksort) that incorporates +this tear off library in the autogen distribution directory. There is +also a web page that describes what you need to do: +@example +@url{http://autogen.sourceforge.net/blocksort.html} +@end example + +Alternatively, you can pull the @code{libopts} library sources into +a build directory and build it for installation along with your package. +This can be done approximately as follows: +@example +tar -xzvf `autoopts-config libsrc` +cd libopts-* +./bootstrap +configure +make +make install +@end example +That will install the library, but not the headers or anything else. + +@c === SECTION MARKER + +@node Presetting Options +@section Configuring your program +@cindex shell options + +AutoOpts supports the notion of @code{presetting} the value or state of an +option. The values may be obtained either from environment variables or from +configuration files (@file{rc} or @file{ini} files). In order to take +advantage of this, the AutoOpts client program must specify these features in +the option descriptor file (@pxref{program attributes}) with the @code{rcfile} +or @code{environrc} attributes. + +@menu +* loading rcfile:: configuration file presets +* saving rcfile:: Saving the presets into a configuration file +* sample rcfile:: Creating a sample configuration file +* environrc:: environment variable presets +* config example:: Config file only example +@end menu + +It is also possible to configure your program @i{without} using +the command line option parsing code. This is done by using +only the following four functions from the @file{libopts} library: + +@table @samp +@item configFileLoad +(@pxref{libopts-configFileLoad}) will parse the contents of a config +file and return a pointer to a structure representing the hierarchical +value. The values are sorted alphabetically by the value name and all +entries with the same name will retain their original order. +Insertion sort is used. + +@item optionGetValue +(@pxref{libopts-optionGetValue}) will find the first value within the +hierarchy with a name that matches the name passed in. + +@item optionNextValue +(@pxref{libopts-optionNextValue}) will return the next value that +follows the value passed in as an argument. If you wish to get all +the values for a particular name, you must take note when the name +changes. + +@item optionUnloadNested +(@pxref{libopts-optionUnloadNested}). The pointer passed in must be +of type, @code{OPARG_TYPE_HIERARCHY} (see the autoopts/options.h +header file). @code{configFileLoad} will return a @code{tOptionValue} +pointer of that type. This function will release all the associated +memory. @code{AutoOpts} generated code uses this function for its own +needs. Client code should only call this function with pointers +gotten from @code{configFileLoad}. +@end table + +@node loading rcfile +@subsection configuration file presets +@cindex rcfile + +Configuration files are enabled by specifying the program attribute +@code{homerc} (@pxref{program attributes}). Any option not marked +with the @code{no-preset} attribute may appear in a configuration file. +The files loaded are selected both by the @code{homerc} entries and, +optionally, via a command line option. The first component of the +@code{homerc} entry may be an environment variable such as @env{$HOME}, or +it may also be @samp{$$} (@strong{two} dollar sign characters) to specify +the directory of the executable. For example: + +@example +homerc = "$$/../share/autogen"; +@end example + +@noindent +will cause the AutoOpts library to look in the normal autogen datadir +relative to the current installation directory for autogen. + +The configuration files are processed in the order they are specified by +the @code{homerc} attribute, so that each new file will normally override +the settings of the previous files. This may be overridden by marking some +options for @code{immediate action} (@pxref{Immediate Action}). Any such +options are acted upon in @strong{reverse} order. The disabled +@code{load-opts} (@option{--no-load-opts}) option, for example, is an +immediate action option. Its presence in the last @code{homerc} file will +prevent the processing of any prior @code{homerc} files because its effect +is immediate. + +Configuration file processing can be completely suppressed by specifying +@option{--no-load-opts} on the command line, or @code{PROGRAM_LOAD_OPTS=no} in +the environment (if @code{environrc} has been specified). + +See the @code{Configuration File Format} section (@pxref{Config File Format}) +for details on the format of the file. + +@node saving rcfile +@subsection Saving the presets into a configuration file + +When configuration files are enabled for an application, the user is +also provided with an automatically supplied @option{--save-opts} option. +All of the known option state will be written to either the specified +output file or, if it is not specified, then to the last specified +@code{homerc} file. + +@node sample rcfile +@subsection Creating a sample configuration file +@cindex sample rcfile + +AutoOpts is shipped with a template named, @file{rc-sample.tpl}. +If your option definition file specifies the @code{homerc} attribute, +then you may invoke @file{autogen} thus: + +@example +autogen -Trc-sample <your-option-def-file> +@end example + +This will, by default, produce a sample file named, +@file{sample-<prog-name>rc}. It will be named differently if you specify your +configuration (rc) file name with the @code{rcfile} attribute. In that case, +the output file will be named, @file{sample-<rcfile-name>}. It will contain +all of the program options not marked as @code{no-preset}. It will also +include the text from the @code{doc} attribute. + +@ignore +END == AUTOOPTS-DATA == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore +@noindent +Doing so with getdefs' option definitions yields this sample-getdefsrc file. +I tend to be wordy in my @code{doc} attributes: + +@example +# getdefs sample configuration file +## This source file is copyrighted and licensed under the following terms: +# +# Copyright (C) 1999-2018 Bruce Korb, all rights reserved. +# This is free software. It is licensed for use, modification and +# redistribution under the terms of the GNU General Public License, +# version 3 or later <http://gnu.org/licenses/gpl.html> +# +# getdefs is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# getdefs is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see <http://www.gnu.org/licenses/>. + +# defs_to_get -- Regexp to look for after the "/*=" +# +# +# +# +# If you want definitions only from a particular category, or even +# with names matching particular patterns, then specify this regular +# expression for the text that must follow the @@code@{/*=@}. +# Example: +# +#defs_to_get reg-ex + +# subblock -- subblock definition names +# +# +# +# +# This option is used to create shorthand entries for nested definitions. +# For example, with: +# @@table @@r +# @@item using subblock thus +# @@code@{--subblock=arg=argname,type,null@} +# @@item and defining an @@code@{arg@} thus +# @@code@{arg: this, char *@} +# @@item will then expand to: +# @@code@{arg = @@@{ argname = this; type = "char *"; @@@};@} +# @@end table +# The "this, char *" string is separated at the commas, with the +# white space removed. You may use characters other than commas by +# starting the value string with a punctuation character other than +# a single or double quote character. You may also omit intermediate +# values by placing the commas next to each other with no intervening +# white space. For example, "+mumble++yes+" will expand to: +# @@* +# @@code@{arg = @@@{ argname = mumble; null = "yes"; @@@};@}. +# Example: +# +#subblock sub-def + +# listattr -- attribute with list of values +# +# +# +# +# This option is used to create shorthand entries for definitions +# that generally appear several times. That is, they tend to be +# a list of values. For example, with: +# @@* +# @@code@{listattr=foo@} defined, the text: +# @@* +# @@code@{foo: this, is, a, multi-list@} will then expand to: +# @@* +# @@code@{foo = 'this', 'is', 'a', 'multi-list';@} +# @@* +# The texts are separated by the commas, with the +# white space removed. You may use characters other than commas by +# starting the value string with a punctuation character other than +# a single or double quote character. +# Example: +# +#listattr def + +# ordering -- Alphabetize or use named file +# +# +# +# +# By default, ordering is alphabetical by the entry name. Use, +# @@code@{no-ordering@} if order is unimportant. Use @@code@{ordering@} +# with no argument to order without case sensitivity. Use +# @@code@{ordering=<file-name>@} if chronological order is important. +# getdefs will maintain the text content of @@code@{file-name@}. +# @@code@{file-name@} need not exist. +# Example: +# +#ordering file-name + +# first_index -- The first index to apply to groups +# +# This configuration value takes an integer number as its argument. +# +# +# By default, the first occurrence of a named definition will have an +# index of zero. Sometimes, that needs to be a reserved value. Provide +# this option to specify a different starting point. +# Example: +# +#first_index 0 + +# filelist -- Insert source file names into defs +# +# +# +# +# Inserts the name of each input file into the output definitions. +# If no argument is supplied, the format will be: +# @@example +# infile = '%s'; +# @@end example +# If an argument is supplied, that string will be used for the entry +# name instead of @@var@{infile@}. +# Example: +# +#filelist file + +# assign -- Global assignments +# +# +# +# +# The argument to each copy of this option will be inserted into +# the output definitions, with only a semicolon attached. +# Example: +# +#assign ag-def + +# common_assign -- Assignments common to all blocks +# +# +# +# +# The argument to each copy of this option will be inserted into +# each output definition, with only a semicolon attached. +# Example: +# +#common_assign ag-def + +# copy -- File(s) to copy into definitions +# +# +# +# +# The content of each file named by these options will be inserted into +# the output definitions. +# Example: +# +#copy file + +# srcfile -- Insert source file name into each def +# +# +# +# +# Inserts the name of the input file where a definition was found +# into the output definition. +# If no argument is supplied, the format will be: +# @@example +# srcfile = '%s'; +# @@end example +# If an argument is supplied, that string will be used for the entry +# name instead of @@var@{srcfile@}. +# Example: +# +#srcfile file + +# linenum -- Insert source line number into each def +# +# +# +# +# Inserts the line number in the input file where a definition +# was found into the output definition. +# If no argument is supplied, the format will be: +# @@example +# linenum = '%s'; +# @@end example +# If an argument is supplied, that string will be used for the entry +# name instead of @@var@{linenum@}. +# Example: +# +#linenum def-name + +# input -- Input file to search for defs +# +# +# +# +# All files that are to be searched for definitions must be named on +# the command line or read from @@code@{stdin@}. If there is only one +# @@code@{input@} option and it is the string, "-", then the input file +# list is read from @@code@{stdin@}. If a command line argument is not +# an option name and does not contain an assignment operator +# (@@code@{=@}), then it defaults to being an input file name. +# At least one input file must be specified. +# Example: +# +#input src-file + +# output -- Output file to open +# +# +# +# +# If you are not sending the output to an AutoGen process, +# you may name an output file instead. +# Example: +# +#output file + +# autogen -- Invoke AutoGen with defs +# +# +# +# +# This is the default output mode. Specifying @@code@{no-autogen@} is +# equivalent to @@code@{output=-@}. If you supply an argument to this +# option, that program will be started as if it were AutoGen and +# its standard in will be set to the output definitions of this program. +# Example: +# +#autogen ag-cmd + +# template -- Template Name +# +# +# +# +# Specifies the template name to be used for generating the final output. +# Example: +# +#template file + +# agarg -- AutoGen Argument +# +# +# +# +# This is a pass-through argument. It allows you to specify any +# arbitrary argument to be passed to AutoGen. +# Example: +# +#agarg ag-opt + +# base_name -- Base name for output file(s) +# +# +# +# +# When output is going to AutoGen, a base name must either be supplied +# or derived. If this option is not supplied, then it is taken from +# the @@code@{template@} option. If that is not provided either, then +# it is set to the base name of the current directory. +# Example: +# +#base_name name +@end example +@ignore +START == AO-DATA1 == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@node environrc +@subsection environment variable presets +@cindex environrc + +If the AutoOpts client program specifies @code{environrc} in its +option descriptor file, then environment variables will be used for +presetting option state. Variables will be looked for that are named, +@env{PROGRAM_OPTNAME} and @env{PROGRAM}. @env{PROGRAM} is the +upper cased @code{C-name} of the program, and @var{OPTNAME} is the +upper cased @code{C-name} of a specific option. (The @code{C-name}s +are the regular names with all special characters converted to +underscores (@code{_}).) + +Option specific environment variables are processed after (and thus +take precedence over) the contents of the @env{PROGRAM} environment +variable. The option argument string for these options takes on the +string value gotten from the environment. Consequently, you can only +have one instance of the @var{OPTNAME}. + +If a particular option may be disabled, then its disabled state is +indicated by setting the @env{PROGRAM_OPTNAME} value to the +disablement prefix. So, for example, if the disablement prefix were +@code{dont}, then you can disable the @code{optname} option by setting +the @env{PROGRAM_OPTNAME}' environment variable to @code{@i{dont}}. +@xref{Common Attributes}. + +The @env{PROGRAM} environment string is tokenized and parsed much +like a command line. Doubly quoted strings have backslash escapes +processed the same way they are processed in C program constant +strings. Singly quoted strings are pretty raw in that backslashes are +honored before other backslashes, apostrophes, newlines and cr/newline +pairs. The options must be introduced with hyphens in the same way as +the command line. + +Note that not all options may be preset. Options that are specified with the +@code{no-preset} attribute and the @option{--help}, @option{--more-help}, +and @option{--save-opts} auto-supported options may not be preset. + +@node config example +@subsection Config file only example +@cindex rcfile +@cindex Configuration File +@cindex Configuration File example + +If for some reason it is difficult or unworkable to integrate configuration +file processing with command line option parsing, the @code{libopts} +(@pxref{libopts procedures}) library can still be used to process +configuration files. Below is a @t{Hello, World!} greeting program that tries +to load a configuration file @file{hello.conf} to see if it should use an +alternate greeting or to personalize the salutation. +@ignore +END == AO-DATA1 == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore +@example +#include <config.h> +#include <sys/types.h> +#include <stdio.h> +#include <pwd.h> +#include <string.h> +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#include <autoopts/options.h> +int main(int argc, char ** argv) @{ + char const * greeting = "Hello"; + char const * greeted = "World"; + tOptionValue const * pOV = configFileLoad("hello.conf"); + + if (pOV != NULL) @{ + const tOptionValue* pGetV = optionGetValue(pOV, "greeting"); + + if ( (pGetV != NULL) + && (pGetV->valType == OPARG_TYPE_STRING)) + greeting = strdup(pGetV->v.strVal); + + pGetV = optionGetValue(pOV, "personalize"); + if (pGetV != NULL) @{ + struct passwd * pwe = getpwuid(getuid()); + if (pwe != NULL) + greeted = strdup(pwe->pw_gecos); + @} + + optionUnloadNested(pOV); /* deallocate config data */ + @} + printf("%s, %s!\n", greeting, greeted); + return 0; +@} +@end example + +@noindent +With that text in a file named ``hello.c'', this short script: + +@example +cc -o hello hello.c `autoopts-config cflags ldflags` +./hello +echo 'greeting Buzz off' > hello.conf +./hello +echo personalize > hello.conf +./hello +@end example + +@noindent +will produce the following output: + +@example +Hello, World! +Buzz off, World! +Hello, Bruce Korb,,,! +@end example +@ignore +START == AO-DATA2 == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@c === SECTION MARKER + +@node Config File Format +@section Configuration File Format +@cindex Configuration File + +The configuration file is designed to associate names and values, much like +an AutoGen Definition File (@pxref{Definitions File}). Unfortunately, the +file formats are different. Specifically, AutoGen Definitions provide for +simpler methods for the precise control of a value string and provides for +dynamically computed content. Configuration files have some established +traditions in their layout. So, they are different, even though they do +both allow for a single name to be associated with multiple values and they +both allow for hierarchical values. + +@menu +* config name/string-value:: assigning a string value to a configurable +* config integer-values:: integer values +* config nested-values:: hierarchical values +* config directives:: configuration file directives +* config comments:: comments in the configuration file +@end menu + +@node config name/string-value +@subsection assigning a string value to a configurable + +The basic syntax is a name followed by a value on a single line. They are +separated from each other by either white space, a colon (@code{:}) or an +equal sign (@code{=}). The colon or equal sign may optionally be surrounded +by additional white space. If more than one value line is needed, a +backslash (@code{\}) may be used to continue the value. The backslash (but +not the newline) will be erased. Leading and trailing white space is always +stripped from the value. + +Fundamentally, it looks like this: + +@example +name value for that name +name = another \ + multi-line value \ + for that name. +name: a *third* value for @code{name} +@end example + +If you need more control over the content of the value, you may enclose the +value in XML style brackets: +@example +<name>value </name> +@end example +@noindent +Within these brackets you need not (must not) continue the value data with +backslashes. You may also select the string formation rules to use, just +add the attribute after the name, thus: @code{<name keep>}. + +@table @samp +@item keep +This mode will keep all text between the brackets and not strip any +white space. +@item uncooked +This mode strips leading and trailing white space, but not do any +quote processing. This is the default and need not be specified. +@item cooked +The text is trimmed of leading and trailing white space and XML encodings +are processed. These encodings are slightly expanded over the XML +specification. They are specified with an ampersand followed by a value +name or numeric value and then a semicolon: + +@table @samp +@item amp +@itemx lt +@itemx gt +@itemx quot +@itemx apos +@itemx #dd +@itemx #xHH + +These are all per fairly standad HTML and/or XML encodings. +Additionally: + +@item bs +The ASCII back space character. +@item ff +The ASCII form feed character. +@item ht +The ASCII horizontal (normal) tab character. +@item cr +The ASCII carriage return character. +@item vt +The ASCII vertical tab character. +@item bel +The ASCII alarm bell character. +@item nl +The ASCII new line character. +@item space +The ASCII space character. Normally not necessary, but if you want +to preserve leading or trailing space characters, then use this. +@end table +@end table + +And here is an example of an XML-styled value: + +@example +<name cooked> + This is&nl;&ht;another multi-line +&ht;string example. +</name> +@end example + +The string value associated with @code{name} will be exactly the text enclosed +in quotes with the encoded characters @code{cooked} as you would expect (three +text lines with the last line not ending with a newline, but ending with a +period). + +@node config integer-values +@subsection integer values + +A name can be specified as having an integer value. To do this, you +must use the XML-ish format and specify a @code{type} attribute for +the name: + +@example +<name type=integer> 1234 </name> +@end example + +Boolean, enumeration and set membership types will be added as time +allows. @code{type=string} is also supported, but also is the default. + +@node config nested-values +@subsection hierarchical values + +In order to specify a hierarchical value, you *must* use XML-styled +formatting, specifying a type that is shorter and easier to spell: + +@example +<structured-name type=nested> + [[....]] +</structured-name> +@end example + +@noindent +The ellipsis may be filled with any legal configuration file name/value +assignments. + +@node config directives +@subsection configuration file directives +@cindex autoopts directives + +The @code{<?} marker indicates an XML directive. +There is only one directive supported: program sectioning, +though two syntaxes are supported. + +If, for example, you have a collection of programs that work closely +together and, likely, have a common set of options, these programs may use a +single, sectioned, configuration file. The file may be sectioned in either +of two ways. The two ways may not be intermixed in a single configuration +file. All text before the first segmentation line is processed, then only +the segment that applies: + +@table @samp +@item <?auto-options ...> +The @code{...} ellipsis may contain AutoOpts option processing options. +Currently, that consists of one or both of: + +@table @code +@item gnu +@itemx autoopts +to indicate GNU-standard or AutoOpts-standard layout of usage and +version information, and/or + +@item misuse-usage +@itemx no-misuse-usage +to indicate whether the available options should be listed when +an invalid option appears on the command line. +@end table +@noindent +Anything else will be silently ignored. + +@item <?program prog-name> +The @code{<?} marker indicates an XML directive. +The file is partitioned by these lines and the options are processed +for the @code{prog-name} program only before the first @code{<?program} +directive and the program section with a matching program name. + +@item [PROG_NAME] +This is basically an alias for @code{<?program prog-name>}, except that +the program name must be upper cased and segmented only with underscores +and it is @strong{not} recognized as a program segment when updating +configuration files with the @code{--save-opts} option. In other words, +use this only for Windows compatibility. +@end table + +@noindent +Segmentation does not apply if the config file is being parsed with +the @code{configFileLoad(3AutoOpts)} function. + +@node config comments +@subsection comments in the configuration file + +Comments are lines beginning with a hash mark (@code{#}), +XML-style comments (@code{<!-- arbitrary text -->}), and +unrecognized XML directives. + +@example +# this is a comment +<!-- this is also + a comment --> +<?this is + a bad comment ;-> +@end example + +@c === SECTION MARKER + +@node shell options +@section AutoOpts for Shell Scripts +@cindex shell options +@cindex configuration file + +AutoOpts may be used with shell scripts either by automatically creating a +complete program that will process command line options and pass back +the results to the invoking shell by issuing shell variable assignment +commands, or it may be used to generate portable shell code that can +be inserted into your script. + +The functionality of these features, of course, is somewhat constrained +compared with the normal program facilities. Specifically, you cannot +invoke callout procedures with either of these methods. Additionally, +if you generate a shell script to do the parsing: + +@enumerate +@item +You cannot obtain options from configuration files. +@item +You cannot obtain options from environment variables. +@item +You cannot save the option state to an option file. +@item +Option conflict/requirement verification is disabled. +@end enumerate + +Both of these methods are enabled by running AutoGen on +the definitions file with the additional main procedure attribute: + +@example +main = @{ main-type = shell-process; @}; +@end example +@noindent +or: +@example +main = @{ main-type = shell-parser; @}; +@end example + +If you do not supply a @code{proc-to-call}, it will default to +@code{optionPutShell}. That will produce a program that will process the +options and generate shell text for the invoking shell to interpret +(@pxref{binary-parser}). If you supply the name, @code{optionParseShell}, +then you will have a program that will generate a shell script that can parse +the options (@pxref{script-parser}). If you supply a different procedure +name, you will have to provide that routine and it may do whatever you like. + +@menu +* binary-parser:: Parsing with an Executable +* script-parser:: Parsing with a Portable Script +@end menu + +@node binary-parser +@subsection Parsing with an Executable + +The following commands are approximately all that is needed +to build a shell script command line option parser from +an option definition file: + +@example +autogen -L <opt-template-dir> test-errors.def +cc -o test-errors -L <opt-lib-dir> -I <opt-include-dir> \ + -DTEST_PROGRAM_OPTS test-errors.c -lopts +@end example + +The resulting program can then be used within your shell script as follows: + +@example +eval `./test-errors "$@@"` +if [ -z "$@{OPTION_CT@}" ] ; then exit 1 ; fi +test $@{OPTION_CT@} -gt 0 && shift $@{OPTION_CT@} +@end example +@ignore +END == AO-DATA2 == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +Here is the usage output example from AutoOpts error handling +tests. The option definition has argument reordering enabled: + +@example +test_errors - Test AutoOpts for errors +Usage: errors [ -<flag> [<val>] | --<name>[@{=| @}<val>] ]... arg ... + Flg Arg Option-Name Description + -o no option The option option descrip + -s Str second The second option descrip + - may appear up to 10 times + -i --- ignored we have dumped this + -X no another Another option descrip + - may appear up to 5 times + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + -> opt save-opts save the option state to a config file + -< Str load-opts load options from a config file + - disabled as '--no-load-opts' + - may appear multiple times + +Options are specified by doubled hyphens and their name or by a single +hyphen and the flag character. +Operands and options may be intermixed. They will be reordered. + +The following option preset mechanisms are supported: + - reading file errorsRC +@end example + +Using the invocation, +@example + test-errors operand1 -s first operand2 -X -- -s operand3 +@end example +you get the following output for your shell script to evaluate: + +@example +OPTION_CT=4 +export OPTION_CT +TEST_ERRORS_SECOND='first' +export TEST_ERRORS_SECOND +TEST_ERRORS_ANOTHER=1 # 0x1 +export TEST_ERRORS_ANOTHER +set -- 'operand1' 'operand2' '-s' 'operand3' +OPTION_CT=0 +@end example +@node script-parser +@subsection Parsing with a Portable Script + +If you had used @code{test-main = optionParseShell} instead, then you can, +at this point, merely run the program and it will write the parsing +script to standard out. You may also provide this program with command +line options to specify the shell script file to create or edit, and you +may specify the shell program to use on the first shell script line. +That program's usage text would look something like the following +and the script parser itself would be very verbose: + +@example +genshellopt - Generate Shell Option Processing Script - Ver. 1 +Usage: genshellopt [ -<flag> [<val>] | --<name>[@{=| @}<val>] ]... + Flg Arg Option-Name Description + -o Str script Output Script File + -s Str shell Shell name (follows "#!" magic) + - disabled as '--no-shell' + - enabled by default + -v opt version output version information and exit + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + +Options are specified by doubled hyphens and their name or by a single +hyphen and the flag character. +Note that 'shell' is only useful if the output file does not already exist. +If it does, then the shell name and optional first argument will be +extracted from the script file. +If the script file already exists and contains Automated Option Processing +text, the second line of the file through the ending tag will be replaced +by the newly generated text. The first '#!' line will be regenerated. + +Please send bug reports to: <autogen-users@@lists.sourceforge.net> + += = = = = = = = + +This incarnation of genshell will produce +a shell script to parse the options for getdefs: + +getdefs (GNU AutoGen) - AutoGen Definition Extraction Tool - Ver. 1.5 +Usage: getdefs [ <option-name>[@{=| @}<val>] ]... + Arg Option-Name Description + Str defs-to-get Regexp to look for after the "/*=" + Str subblock subblock definition names + Str listattr attribute with list of values + opt ordering Alphabetize or use named file + Num first-index The first index to apply to groups + opt filelist Insert source file names into defs + Str assign Global assignments + Str common-assign Assignments common to all blocks + Str copy File(s) to copy into definitions + opt srcfile Insert source file name into each def + opt linenum Insert source line number into each def + Str input Input file to search for defs + Str output Output file to open + opt autogen Invoke AutoGen with defs + Str template Template Name + Str agarg AutoGen Argument + Str base-name Base name for output file(s) + @end example + +@noindent +Resulting in the following script: +@example +#! /bin/sh +# # # # # # # # # # -- do not modify this marker -- +# +# DO NOT EDIT THIS SECTION + OF /u/bkorb/tools/ag/autogen-bld/doc/ag-texi-32340.d/.ag-5GQlKL/genshellopt.sh +# +# From here to the next `-- do not modify this marker --', +# the text has been generated Sunday August 26, 2018 at 10:46:02 AM PDT +# From the GETDEFS option definitions +# +GETDEFS_LONGUSAGE_TEXT='getdefs error: invalid option descriptor for version +getdefs (GNU AutoGen) - AutoGen Definition Extraction Tool - Ver. 1.5 +Usage: getdefs [ <option-name>[@{=| @}<val>] ]... + +Specify which definitions are of interest and what to say about them: + + Arg Option-Name Description + Str defs-to-get Regexp to look for after the "/*=" + Str subblock subblock definition names + - may appear multiple times + Str listattr attribute with list of values + - may appear multiple times + +specify how to number the definitions: + + Arg Option-Name Description + opt ordering Alphabetize or use named file + - disabled as '\''--no-ordering'\'' + - enabled by default + Num first-index The first index to apply to groups + +Definition insertion options: + + Arg Option-Name Description + opt filelist Insert source file names into defs + Str assign Global assignments + - may appear multiple times + Str common-assign Assignments common to all blocks + - may appear multiple times + Str copy File(s) to copy into definitions + - may appear multiple times + opt srcfile Insert source file name into each def + opt linenum Insert source line number into each def + +specify which files to search for markers: + + Arg Option-Name Description + Str input Input file to search for defs + - may appear multiple times + - default option for unnamed options + +Definition output disposition options:: + + Arg Option-Name Description + Str output Output file to open + - an alternate for '\''autogen'\'' + opt autogen Invoke AutoGen with defs + - disabled as '\''--no-autogen'\'' + - enabled by default + Str template Template Name + Str agarg AutoGen Argument + - prohibits the option '\''output'\'' + - may appear multiple times + Str base-name Base name for output file(s) + - prohibits the option '\''output'\'' + +Version, usage and configuration options: + + Arg Option-Name Description + ' + +GETDEFS_USAGE_TEXT='getdefs (GNU AutoGen) - AutoGen Definition Extraction Tool - Ver. 1.5 +Usage: getdefs [ <option-name>[@{=| @}<val>] ]... + Arg Option-Name Description + Str defs-to-get Regexp to look for after the "/*=" + Str subblock subblock definition names + Str listattr attribute with list of values + opt ordering Alphabetize or use named file + Num first-index The first index to apply to groups + opt filelist Insert source file names into defs + Str assign Global assignments + Str common-assign Assignments common to all blocks + Str copy File(s) to copy into definitions + opt srcfile Insert source file name into each def + opt linenum Insert source line number into each def + Str input Input file to search for defs + Str output Output file to open + opt autogen Invoke AutoGen with defs + Str template Template Name + Str agarg AutoGen Argument + Str base-name Base name for output file(s) + getdefs error: invalid option descriptor for version' + + +GETDEFS_DEFS_TO_GET=$@{GETDEFS_DEFS_TO_GET@} +GETDEFS_DEFS_TO_GET_set=false +export GETDEFS_DEFS_TO_GET + +if test -z "$@{GETDEFS_SUBBLOCK@}" +then + GETDEFS_SUBBLOCK_CT=0 + export GETDEFS_SUBBLOCK_CT +else + GETDEFS_SUBBLOCK_CT=1 + GETDEFS_SUBBLOCK_1=$@{GETDEFS_SUBBLOCK@} + export GETDEFS_SUBBLOCK_CT GETDEFS_SUBBLOCK_1 +fi + +if test -z "$@{GETDEFS_LISTATTR@}" +then + GETDEFS_LISTATTR_CT=0 + export GETDEFS_LISTATTR_CT +else + GETDEFS_LISTATTR_CT=1 + GETDEFS_LISTATTR_1=$@{GETDEFS_LISTATTR@} + export GETDEFS_LISTATTR_CT GETDEFS_LISTATTR_1 +fi + +GETDEFS_ORDERING=$@{GETDEFS_ORDERING@} +GETDEFS_ORDERING_set=false +export GETDEFS_ORDERING + +GETDEFS_FIRST_INDEX=$@{GETDEFS_FIRST_INDEX-'0'@} +GETDEFS_FIRST_INDEX_set=false +export GETDEFS_FIRST_INDEX + +GETDEFS_FILELIST=$@{GETDEFS_FILELIST@} +GETDEFS_FILELIST_set=false +export GETDEFS_FILELIST + +if test -z "$@{GETDEFS_ASSIGN@}" +then + GETDEFS_ASSIGN_CT=0 + export GETDEFS_ASSIGN_CT +else + GETDEFS_ASSIGN_CT=1 + GETDEFS_ASSIGN_1=$@{GETDEFS_ASSIGN@} + export GETDEFS_ASSIGN_CT GETDEFS_ASSIGN_1 +fi + +if test -z "$@{GETDEFS_COMMON_ASSIGN@}" +then + GETDEFS_COMMON_ASSIGN_CT=0 + export GETDEFS_COMMON_ASSIGN_CT +else + GETDEFS_COMMON_ASSIGN_CT=1 + GETDEFS_COMMON_ASSIGN_1=$@{GETDEFS_COMMON_ASSIGN@} + export GETDEFS_COMMON_ASSIGN_CT GETDEFS_COMMON_ASSIGN_1 +fi + +if test -z "$@{GETDEFS_COPY@}" +then + GETDEFS_COPY_CT=0 + export GETDEFS_COPY_CT +else + GETDEFS_COPY_CT=1 + GETDEFS_COPY_1=$@{GETDEFS_COPY@} + export GETDEFS_COPY_CT GETDEFS_COPY_1 +fi + +GETDEFS_SRCFILE=$@{GETDEFS_SRCFILE@} +GETDEFS_SRCFILE_set=false +export GETDEFS_SRCFILE + +GETDEFS_LINENUM=$@{GETDEFS_LINENUM@} +GETDEFS_LINENUM_set=false +export GETDEFS_LINENUM + +if test -z "$@{GETDEFS_INPUT@}" +then + GETDEFS_INPUT_CT=0 + export GETDEFS_INPUT_CT +else + GETDEFS_INPUT_CT=1 + GETDEFS_INPUT_1=$@{GETDEFS_INPUT@} + export GETDEFS_INPUT_CT GETDEFS_INPUT_1 +fi + +GETDEFS_OUTPUT=$@{GETDEFS_OUTPUT@} +GETDEFS_OUTPUT_set=false +export GETDEFS_OUTPUT + +GETDEFS_AUTOGEN=$@{GETDEFS_AUTOGEN@} +GETDEFS_AUTOGEN_set=false +export GETDEFS_AUTOGEN + +GETDEFS_TEMPLATE=$@{GETDEFS_TEMPLATE@} +GETDEFS_TEMPLATE_set=false +export GETDEFS_TEMPLATE + +if test -z "$@{GETDEFS_AGARG@}" +then + GETDEFS_AGARG_CT=0 + export GETDEFS_AGARG_CT +else + GETDEFS_AGARG_CT=1 + GETDEFS_AGARG_1=$@{GETDEFS_AGARG@} + export GETDEFS_AGARG_CT GETDEFS_AGARG_1 +fi + +GETDEFS_BASE_NAME=$@{GETDEFS_BASE_NAME@} +GETDEFS_BASE_NAME_set=false +export GETDEFS_BASE_NAME + +ARG_COUNT=$# +OPT_ARG=$1 +while [ $# -gt 0 ] +do + OPT_ELEMENT='' + OPT_ARG_VAL='' + OPT_ARG=$@{1@} + OPT_CODE=`echo "X$@{OPT_ARG@}"|sed 's/^X-*//'` + shift + OPT_ARG=$1 + case "$@{OPT_CODE@}" in *=* ) + OPT_ARG_VAL=`echo "$@{OPT_CODE@}"|sed 's/^[^=]*=//'` + OPT_CODE=`echo "$@{OPT_CODE@}"|sed 's/=.*$//'` ;; esac + case "$@{OPT_CODE@}" in + 'de' | \ + 'def' | \ + 'defs' | \ + 'defs-' | \ + 'defs-t' | \ + 'defs-to' | \ + 'defs-to-' | \ + 'defs-to-g' | \ + 'defs-to-ge' | \ + 'defs-to-get' ) + if [ -n "$@{GETDEFS_DEFS_TO_GET@}" ] && $@{GETDEFS_DEFS_TO_GET_set@} ; then + echo 'Error: duplicate DEFS_TO_GET option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_DEFS_TO_GET_set=true + OPT_NAME='DEFS_TO_GET' + OPT_ARG_NEEDED=YES + ;; + + 'su' | \ + 'sub' | \ + 'subb' | \ + 'subbl' | \ + 'subblo' | \ + 'subbloc' | \ + 'subblock' ) + GETDEFS_SUBBLOCK_CT=`expr $@{GETDEFS_SUBBLOCK_CT@} + 1` + OPT_ELEMENT="_$@{GETDEFS_SUBBLOCK_CT@}" + OPT_NAME='SUBBLOCK' + OPT_ARG_NEEDED=YES + ;; + + 'li' | \ + 'lis' | \ + 'list' | \ + 'lista' | \ + 'listat' | \ + 'listatt' | \ + 'listattr' ) + GETDEFS_LISTATTR_CT=`expr $@{GETDEFS_LISTATTR_CT@} + 1` + OPT_ELEMENT="_$@{GETDEFS_LISTATTR_CT@}" + OPT_NAME='LISTATTR' + OPT_ARG_NEEDED=YES + ;; + + 'or' | \ + 'ord' | \ + 'orde' | \ + 'order' | \ + 'orderi' | \ + 'orderin' | \ + 'ordering' ) + if [ -n "$@{GETDEFS_ORDERING@}" ] && $@{GETDEFS_ORDERING_set@} ; then + echo 'Error: duplicate ORDERING option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_ORDERING_set=true + OPT_NAME='ORDERING' + eval GETDEFS_ORDERING$@{OPT_ELEMENT@}=true + export GETDEFS_ORDERING$@{OPT_ELEMENT@} + OPT_ARG_NEEDED=OK + ;; + + 'no-' | \ + 'no-o' | \ + 'no-or' | \ + 'no-ord' | \ + 'no-orde' | \ + 'no-order' | \ + 'no-orderi' | \ + 'no-orderin' | \ + 'no-ordering' ) + if [ -n "$@{GETDEFS_ORDERING@}" ] && $@{GETDEFS_ORDERING_set@} ; then + echo 'Error: duplicate ORDERING option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_ORDERING_set=true + GETDEFS_ORDERING='no' + export GETDEFS_ORDERING + OPT_NAME='ORDERING' + OPT_ARG_NEEDED=NO + ;; + + 'fi' | \ + 'fir' | \ + 'firs' | \ + 'first' | \ + 'first-' | \ + 'first-i' | \ + 'first-in' | \ + 'first-ind' | \ + 'first-inde' | \ + 'first-index' ) + if [ -n "$@{GETDEFS_FIRST_INDEX@}" ] && $@{GETDEFS_FIRST_INDEX_set@} ; then + echo 'Error: duplicate FIRST_INDEX option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_FIRST_INDEX_set=true + OPT_NAME='FIRST_INDEX' + OPT_ARG_NEEDED=YES + ;; + + 'fi' | \ + 'fil' | \ + 'file' | \ + 'filel' | \ + 'fileli' | \ + 'filelis' | \ + 'filelist' ) + if [ -n "$@{GETDEFS_FILELIST@}" ] && $@{GETDEFS_FILELIST_set@} ; then + echo 'Error: duplicate FILELIST option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_FILELIST_set=true + OPT_NAME='FILELIST' + eval GETDEFS_FILELIST$@{OPT_ELEMENT@}=true + export GETDEFS_FILELIST$@{OPT_ELEMENT@} + OPT_ARG_NEEDED=OK + ;; + + 'as' | \ + 'ass' | \ + 'assi' | \ + 'assig' | \ + 'assign' ) + GETDEFS_ASSIGN_CT=`expr $@{GETDEFS_ASSIGN_CT@} + 1` + OPT_ELEMENT="_$@{GETDEFS_ASSIGN_CT@}" + OPT_NAME='ASSIGN' + OPT_ARG_NEEDED=YES + ;; + + 'co' | \ + 'com' | \ + 'comm' | \ + 'commo' | \ + 'common' | \ + 'common-' | \ + 'common-a' | \ + 'common-as' | \ + 'common-ass' | \ + 'common-assi' | \ + 'common-assig' | \ + 'common-assign' ) + GETDEFS_COMMON_ASSIGN_CT=`expr $@{GETDEFS_COMMON_ASSIGN_CT@} + 1` + OPT_ELEMENT="_$@{GETDEFS_COMMON_ASSIGN_CT@}" + OPT_NAME='COMMON_ASSIGN' + OPT_ARG_NEEDED=YES + ;; + + 'co' | \ + 'cop' | \ + 'copy' ) + GETDEFS_COPY_CT=`expr $@{GETDEFS_COPY_CT@} + 1` + OPT_ELEMENT="_$@{GETDEFS_COPY_CT@}" + OPT_NAME='COPY' + OPT_ARG_NEEDED=YES + ;; + + 'sr' | \ + 'src' | \ + 'srcf' | \ + 'srcfi' | \ + 'srcfil' | \ + 'srcfile' ) + if [ -n "$@{GETDEFS_SRCFILE@}" ] && $@{GETDEFS_SRCFILE_set@} ; then + echo 'Error: duplicate SRCFILE option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_SRCFILE_set=true + OPT_NAME='SRCFILE' + eval GETDEFS_SRCFILE$@{OPT_ELEMENT@}=true + export GETDEFS_SRCFILE$@{OPT_ELEMENT@} + OPT_ARG_NEEDED=OK + ;; + + 'li' | \ + 'lin' | \ + 'line' | \ + 'linen' | \ + 'linenu' | \ + 'linenum' ) + if [ -n "$@{GETDEFS_LINENUM@}" ] && $@{GETDEFS_LINENUM_set@} ; then + echo 'Error: duplicate LINENUM option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_LINENUM_set=true + OPT_NAME='LINENUM' + eval GETDEFS_LINENUM$@{OPT_ELEMENT@}=true + export GETDEFS_LINENUM$@{OPT_ELEMENT@} + OPT_ARG_NEEDED=OK + ;; + + 'in' | \ + 'inp' | \ + 'inpu' | \ + 'input' ) + GETDEFS_INPUT_CT=`expr $@{GETDEFS_INPUT_CT@} + 1` + OPT_ELEMENT="_$@{GETDEFS_INPUT_CT@}" + OPT_NAME='INPUT' + OPT_ARG_NEEDED=YES + ;; + + 'ou' | \ + 'out' | \ + 'outp' | \ + 'outpu' | \ + 'output' ) + if [ -n "$@{GETDEFS_OUTPUT@}" ] && $@{GETDEFS_OUTPUT_set@} ; then + echo 'Error: duplicate OUTPUT option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_OUTPUT_set=true + OPT_NAME='OUTPUT' + OPT_ARG_NEEDED=YES + ;; + + 'au' | \ + 'aut' | \ + 'auto' | \ + 'autog' | \ + 'autoge' | \ + 'autogen' ) + if [ -n "$@{GETDEFS_AUTOGEN@}" ] && $@{GETDEFS_AUTOGEN_set@} ; then + echo 'Error: duplicate AUTOGEN option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_AUTOGEN_set=true + OPT_NAME='AUTOGEN' + eval GETDEFS_AUTOGEN$@{OPT_ELEMENT@}=true + export GETDEFS_AUTOGEN$@{OPT_ELEMENT@} + OPT_ARG_NEEDED=OK + ;; + + 'no-' | \ + 'no-a' | \ + 'no-au' | \ + 'no-aut' | \ + 'no-auto' | \ + 'no-autog' | \ + 'no-autoge' | \ + 'no-autogen' ) + if [ -n "$@{GETDEFS_AUTOGEN@}" ] && $@{GETDEFS_AUTOGEN_set@} ; then + echo 'Error: duplicate AUTOGEN option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_AUTOGEN_set=true + GETDEFS_AUTOGEN='no' + export GETDEFS_AUTOGEN + OPT_NAME='AUTOGEN' + OPT_ARG_NEEDED=NO + ;; + + 'te' | \ + 'tem' | \ + 'temp' | \ + 'templ' | \ + 'templa' | \ + 'templat' | \ + 'template' ) + if [ -n "$@{GETDEFS_TEMPLATE@}" ] && $@{GETDEFS_TEMPLATE_set@} ; then + echo 'Error: duplicate TEMPLATE option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_TEMPLATE_set=true + OPT_NAME='TEMPLATE' + OPT_ARG_NEEDED=YES + ;; + + 'ag' | \ + 'aga' | \ + 'agar' | \ + 'agarg' ) + GETDEFS_AGARG_CT=`expr $@{GETDEFS_AGARG_CT@} + 1` + OPT_ELEMENT="_$@{GETDEFS_AGARG_CT@}" + OPT_NAME='AGARG' + OPT_ARG_NEEDED=YES + ;; + + 'ba' | \ + 'bas' | \ + 'base' | \ + 'base-' | \ + 'base-n' | \ + 'base-na' | \ + 'base-nam' | \ + 'base-name' ) + if [ -n "$@{GETDEFS_BASE_NAME@}" ] && $@{GETDEFS_BASE_NAME_set@} ; then + echo 'Error: duplicate BASE_NAME option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_BASE_NAME_set=true + OPT_NAME='BASE_NAME' + OPT_ARG_NEEDED=YES + ;; + + 've' | \ + 'ver' | \ + 'vers' | \ + 'versi' | \ + 'versio' | \ + 'version' ) + echo "$GETDEFS_LONGUSAGE_TEXT" + exit 0 + ;; + + 'he' | \ + 'hel' | \ + 'help' ) + echo "$GETDEFS_LONGUSAGE_TEXT" + exit 0 + ;; + + 'mo' | \ + 'mor' | \ + 'more' | \ + 'more-' | \ + 'more-h' | \ + 'more-he' | \ + 'more-hel' | \ + 'more-help' ) + echo "$GETDEFS_LONGUSAGE_TEXT" | $@{PAGER-more@} + exit 0 + ;; + + 'sa' | \ + 'sav' | \ + 'save' | \ + 'save-' | \ + 'save-o' | \ + 'save-op' | \ + 'save-opt' | \ + 'save-opts' ) + echo 'Warning: Cannot save options files' >&2 + OPT_ARG_NEEDED=OK + ;; + + 'lo' | \ + 'loa' | \ + 'load' | \ + 'load-' | \ + 'load-o' | \ + 'load-op' | \ + 'load-opt' | \ + 'load-opts' ) + echo 'Warning: Cannot load options files' >&2 + OPT_ARG_NEEDED=YES + ;; + + 'no-' | \ + 'no-l' | \ + 'no-lo' | \ + 'no-loa' | \ + 'no-load' | \ + 'no-load-' | \ + 'no-load-o' | \ + 'no-load-op' | \ + 'no-load-opt' | \ + 'no-load-opts' ) + echo 'Warning: Cannot suppress the loading of options files' >&2 + OPT_ARG_NEEDED=NO + ;; + + * ) + echo Unknown option: "$@{OPT_CODE@}" >&2 + echo "$GETDEFS_USAGE_TEXT" >&2 + exit 1 + ;; + esac + case "$@{OPT_ARG_NEEDED@}" in + NO ) + OPT_ARG_VAL='' + ;; + YES ) + if [ -z "$@{OPT_ARG_VAL@}" ] + then + if [ $# -eq 0 ] + then + echo No argument provided for $@{OPT_NAME@} option + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + OPT_ARG_VAL=$@{OPT_ARG@} + shift + OPT_ARG=$1 + fi + ;; + OK ) + if [ -z "$@{OPT_ARG_VAL@}" ] && [ $# -gt 0 ] + then + case "$@{OPT_ARG@}" in -* ) ;; * ) + OPT_ARG_VAL=$@{OPT_ARG@} + shift + OPT_ARG=$1 ;; esac + fi + ;; + esac + if [ -n "$@{OPT_ARG_VAL@}" ] + then + eval GETDEFS_$@{OPT_NAME@}$@{OPT_ELEMENT@}="'$@{OPT_ARG_VAL@}'" + export GETDEFS_$@{OPT_NAME@}$@{OPT_ELEMENT@} + fi +done +OPTION_COUNT=`expr $ARG_COUNT - $#` +OPERAND_COUNT=$# +unset OPT_PROCESS || : +unset OPT_ELEMENT || : +unset OPT_ARG || : +unset OPT_ARG_NEEDED || : +unset OPT_NAME || : +unset OPT_CODE || : +unset OPT_ARG_VAL || : + +# # # # # # # # # # +# +# END OF AUTOMATED OPTION PROCESSING +# +# # # # # # # # # # -- do not modify this marker -- + +env | grep '^GETDEFS_' +@end example +@ignore +START == AUTOINFO == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@c === SECTION MARKER + +@node AutoInfo +@section Automated Info Docs +@cindex AutoInfo + +AutoOpts provides two templates for producing @file{.texi} documentation. +@file{agtexi-cmd.tpl} for the invoking section, and @file{aginfo3.tpl} for +describing exported library functions and macros. + +For both types of documents, the documentation level is selected by +passing a @samp{-DLEVEL=<level-name>} argument to AutoGen when you build +the document. (See the example invocation below.) + +Two files will be produced, a @file{.texi} file and a @file{.menu} file. +You should include the text in the @file{.menu} file in a @file{@@menu} +list, either with @file{@@include}-ing it or just copying text. +The @file{.texi} file should be @file{@@include}-ed where the invoking +section belongs in your document. + +The @file{.texi} file will contain an introductory paragraph, a menu +and a subordinate section for the invocation usage and for each +documented option. The introductory paragraph is normally the boiler +plate text, along the lines of: + +@example +This chapter documents the @@file@{AutoOpts@} generated usage text +and option meanings for the @@file@{your-program@} program. +@end example + +@noindent +or: + +@example +These are the publicly exported procedures from the lib@i{name} library. +Any other functions mentioned in the @i{header} file are for the private use +of the library. +@end example + +@menu +* command-info:: @code{invoking} info docs +* library-info:: library info docs +@end menu + +@node command-info +@subsection @code{invoking} info docs + +Using the option definitions for an AutoOpt client program, the +@file{agtexi-cmd.tpl} template will produce texinfo text that documents the +invocation of your program. The text emitted is designed to be included +in the full texinfo document for your product. It is not a stand-alone +document. The usage text for the @ref{autogen usage}, +@ref{getdefs usage} and @ref{columns usage} programs, are included in +this document and are all generated using this template. + +If your program's option definitions include a +@samp{prog-info-descrip} section, then that text will replace the +boilerplate introductory paragraph. + +@noindent +These files are produced by invoking the following command: + +@example +autogen -L $@{prefix@}/share/autogen -Tagtexi-cmd.tpl \ + -DLEVEL=section your-opts.def +@end example + +@noindent +Where @file{$@{prefix@}} is the AutoGen installation prefix +and @file{your-opts.def} is the name of your product's option +definition file. + +@node library-info +@subsection library info docs + +The @command{texinfo} doc for libraries is derived from mostly the same +information as is used for producing man pages @xref{man3}. The main +difference is that there is only one output file and the individual +functions are referenced from a @code{texi} menu. There is also +a small difference in the global attributes used: + +@multitable @columnfractions .02 .23 .65 +@item @tab lib_description +@tab A description of the library. This text appears before the menu. +If not provided, the standard boilerplate version will be inserted. +@item +@item @tab see_also +@tab The @code{SEE ALSO} functionality is not supported for the +@file{texinfo} documentation, so any @code{see_also} attribute will be +ignored. +@end multitable + +@noindent +These files are produced by invoking the following commands: + +@example +getdefs linenum srcfile template=aginfo3.tpl output=libexport.def \ + <source-file-list> + +autogen -L $@{prefix@}/share/autogen -DLEVEL=section libexport.def +@end example + +@noindent +Where @file{$@{prefix@}} is the AutoGen installation prefix +and @file{libexport.def} is some name that suits you. + +An example of this can be seen in this document, @xref{libopts procedures}. + +@c === SECTION MARKER + +@node AutoMan pages +@section Automated Man Pages +@cindex AutoMan pages + +AutoOpts provides two templates for producing man pages. +The command (@file{man1}) pages are derived from the options definition +file, and the library (@file{man3}) pages are derived from +stylized comments (@pxref{getdefs Invocation}). + +Man pages include a date in the footer. By default, this is derived from +the current date. However, this may be overridden with the @code{MAN_PAGE_DATE} +environment variable. If set and not empty, its contents will be copied +into where the output of @code{date '+%d %b %Y'} would otherwise go. + +Man pages may be formatted as either traditional man pages or using @code{mdoc} formatting. +The format is selected by selecting the appropriate template. + +@menu +* man1:: command line man pages +* man3:: library man pages +@end menu + +@node man1 +@subsection command line man pages + +Man pages for commands are documented using the @file{agman-cmd.tpl} +and @file{agmdoc-cmd.tpl} templates. If the options specify pulling +information from @file{RC}/@file{ini}/@file{cfg} files, then you may use +the @file{rc-sample.tpl} template to produce an example config file for +your program. + +Using the option definitions for an AutoOpts client program, +the @samp{agman-cmd.tpl} template will produce an nroff document +suitable for use as a @samp{man(1)} page document for a command +line command. The description section of the document is either +the @samp{prog-man-descrip} text, if present, or the @samp{detail} +text. + +Each option in the option definitions file is fully documented +in its usage. This includes all the information documented +above for each option (@pxref{option attributes}), plus +the @samp{doc} attribute is appended. Since the @samp{doc} +text is presumed to be designed for @code{texinfo} documentation, +@code{sed} is used to convert some constructs from @code{texi} +to @code{nroff}-for-@code{man}-pages. Specifically, + +@example +convert @@code, @@var and @@samp into \fB...\fP phrases +convert @@file into \fI...\fP phrases +Remove the '@@' prefix from curly braces +Indent example regions +Delete the example commands +Replace @samp{end example} command with ".br" +Replace the @samp{@@*} command with ".br" +@end example + +@noindent +This document is produced by invoking the following command: + +@example +autogen -L $@{prefix@}/share/autogen -Tagman-cmd.tpl options.def +@end example + +@noindent +Where @file{$@{prefix@}} is the AutoGen installation prefix and +@file{options.def} is the name of your product's option definition file. +I do not use this very much, so any feedback or improvements would be +greatly appreciated. + +@node man3 +@subsection library man pages + +Man pages for libraries are documented using the @file{agman3.tpl} template. + +Two global definitions are required, and then +one library man page is produced for each @code{export_func} definition +that is found. It is generally convenient to place these definitions +as @file{getdefs} comments (@pxref{getdefs Invocation}) near the procedure +definition, but they may also be a separate AutoGen definitions file +(@pxref{Definitions File}). Each function will be cross referenced +with their sister functions in a @file{SEE ALSO} section. A global +@code{see_also} definition will be appended to this cross referencing text. + +@noindent +The two global definitions required are: + +@multitable @columnfractions .02 .15 .77 +@item @tab library +@tab This is the name of your library, without the @file{lib} prefix. +The AutoOpts library is named @file{libopts.so...}, so the @code{library} +attribute would have the value @code{opts}. +@item +@item @tab header +@tab Generally, using a library with a compiled program entails +@code{#include}-ing a header file. Name that header with this attribute. +In the case of AutoOpts, it is generated and will vary based on the +name of the option definition file. Consequently, @file{your-opts.h} is +specified. +@end multitable + +@noindent +The @code{export_func} definition should contain the following attributes: + +@multitable @columnfractions .02 .15 .77 +@item @tab name +@tab The name of the procedure the library user may call. +@item @tab what +@tab A brief sentence describing what the procedure does. +@item @tab doc +@tab A detailed description of what the procedure does. +It may ramble on for as long as necessary to properly describe it. +@item @tab err +@tab A short description of how errors are handled. +@item @tab ret_type +@tab The data type returned by the procedure. +Omit this for @code{void} procedures. +@item @tab ret_desc +@tab Describe what the returned value is, if needed. +@item @tab private +@tab If specified, the function will @strong{not} be documented. +This is used, for example, to produce external declarations for functions +that are not available for public use, but are used in the generated text. +@item +@item @tab arg +@tab This is a compound attribute that contains: +@end multitable +@multitable @columnfractions .02 .15 .15 .62 +@item @tab @tab arg_type +@tab The data type of the argument. +@item @tab @tab arg_name +@tab A short name for it. +@item @tab @tab arg_desc +@tab A brief description. +@end multitable + +@noindent +As a @file{getdefs} comment, this would appear something like this: + +@example +/*=--subblock=arg=arg_type,arg_name,arg_desc =*/ +/*=* + * library: opts + * header: your-opts.h +=*/ +/*=export_func optionProcess + * + * what: this is the main option processing routine + * arg: + tOptions* + pOpts + program options descriptor + + * arg: + int + argc + program arg count + + * arg: + char** + argv + program arg vector + + * ret_type: int + * ret_desc: the count of the arguments processed + * + * doc: This is what it does. + * err: When it can't, it does this. +=*/ +@end example + +@noindent +Note the @code{subblock} and @code{library} comments. +@code{subblock} is an embedded @file{getdefs} +option (@pxref{getdefs subblock}) that tells it how to parse the +@code{arg} attribute. The @code{library} and @code{header} entries +are global definitions that apply to all the documented functions. + +@c === SECTION MARKER + +@node getopt_long +@section Using getopt(3C) +@cindex getopt_long + +There is a template named, @file{getopt.tpl} that is distributed with +AutoOpts. Using that template instead of @file{options.tpl} will produce +completely independent source code that will parse command line options. It +will utilize either the standard @code{getopt(3C)} or the GNU +@code{getopt_long(3GNU)} function to drive the parsing. Which is used is +selected by the presence or absence of the @code{long-opts} program attribute. +It will save you from being dependent upon the @code{libopts} library @i{and} +it produces code ready for internationalization. However, it also carries +with it some limitations on the use of AutoOpts features and some requirements +on the build environment. + +@strong{PLEASE NOTE}: in processing the option definitions to produce +the usage text, it is necessary to compile some generated code in a +temporary directory. That means that all the include directories +needed to compile the code must be full path names and not relative +directory names. ``.'' is a relative directory name. To specify +``-I.'' in the @code{CFLAGS} environment variable, you must expand it. +For example, use: +@example +CFLAGS=-I`pwd` +@end example + +@menu +* getopt limitations:: getopt feature limitations +* getopt building:: getopt build requirements +@end menu + +@node getopt limitations +@subsection getopt feature limitations + +This list of limitations is relative to the full list of AutoOpts +supported features, @xref{Features}. + +@enumerate +@item +You cannot automatically take advantage of environment variable options or +automated parsing of configuration files (@code{rc} or @code{ini} files). +Consequently, the resulting code does not support @file{--load-opts} or +@file{--save-opts} options automatically. + +@item +You cannot use set membership, enumerated, range checked or stacked +argument type options. In fact, you cannot use anything that depends +upon the @code{libopts} library. You are constrained to options that +take @code{@code{string}} arguments, though you may handle the option +argument with a callback procedure. + +@item +Special disablement and/or enablement prefixes are not recognized. + +@item +Option coordination with external libraries will not work. + +@item +Every option must be @code{settable} because the emitted code +depends upon the @code{SET_OPT_XXX} macros having been defined. +Specify this as a global (program) attribute. + +@item +You must specify a main procedure attribute (@pxref{Generated main}). +The @file{getopt.tpl} template depends upon being able to compile the +traditional .c file into a program and get it to emit the usage text. + +@item +For the same reason, the traditional option parsing table code must be +emitted @b{before} the @file{getopt.tpl} template gets expanded. + +@item +The usage text is, therefore, statically defined. +@end enumerate + +@node getopt building +@subsection getopt build requirements + +You must supply some compile and link options via environment variables. + +@table @samp +@item srcdir +In case the option definition file lives in a different directory. +@item CFLAGS +Any special flags required to compile. The flags from +@code{autoopts-config cflags} will be included automatically. Since +the creation of the option parsing code includes creating a program +that prints out help text, if it is necessary to include files from +various directories to compile that program, you will need to specify +those directories with @option{-Idirpath} text in the @code{CFLAGS}. +Some experimentation may be necessary in that case. + +@strong{NOTE}: the @option{-Idirpath} text is only needed if your option +callback functions include code that require additional @code{#include} +directives. +@item LDFLAGS +Any special flags required to link. The flags from +@code{autoopts-config ldflags} will be included automatically. This +is required only if additional link flags for the help text emission +program might be needed. +@item CC +This is needed only if @code{@code{cc}} cannot be found in @env{$PATH} +(or it is not the one you want). +@end table + +To use this, set the exported environment variables and specify @code{getopt} +as the default template in your option definitions file +(@pxref{Identification}). You will have @i{four} new files. Assuming your +definitions were in a file named @file{myprog-opts.def} and your program name +was specified as @file{progname}, the resulting files would be created: +@file{myprog-opts.h}, @file{myprog-opts.c}, @file{getopt-progname.h} and +@file{getopt-progname.c}. You must compile and link both @file{.c} files into +your program. If there are link failures, then you are using AutoOpts +features that require the @file{libopts} library. You must remove these +features, @xref{getopt limitations}. + +These generated files depend upon configure defines to work correctly. +Therefore, you must specify a @code{config-header} attribute +(@pxref{programming attributes}) and ensure it has @code{#defines} for +either @code{HAVE_STDINT_H} or @code{HAVE_INTTYPES_H}; either +@code{HAVE_SYS_LIMITS_H} or @code{HAVE_LIMITS_H}; and +@code{HAVE_SYSEXITS_H}, if the @file{sysexits.h} header is available. +The required header files for these defines are, respectively, +the @file{/usr/include} files named: +@itemize @bullet +@item stdint.h +@item inttypes.h +@item sys/limits.h +@item limits.h +@item sysexits.h +@end itemize + +@noindent +The following header files must also exist on the build platform: +@itemize @bullet +@item sys/types.h +@item stdio.h +@item string.h +@item unistd.h -- or, for getopt_long: +@item getopt.h +@end itemize +@c === SECTION MARKER + +@node i18n +@section Internationalizing AutoOpts +@cindex Internationalizing AutoOpts + +The generated code for AutoOpts will enable and disable the translation of +AutoOpts run time messages. If @code{ENABLE_NLS} is defined at compile time +and @code{no-xlate} has been not set to the value @emph{anything}, then the +@code{_()} macro may be used to specify a translation function. If undefined, +it will default to @code{gettext(3GNU)}. This define will also enable a +callback function that @code{optionProcess} invokes at the beginning of option +processing. The AutoOpts @code{libopts} library will always check for this +@emph{compiled with NLS} flag, so @code{libopts} does not need to be specially +compiled. The strings returned by the translation function will be +@code{strdup(3)-ed} and kept. They will not be re-translated, even if the +locale changes, but they will also not be dependent upon reused or unmappable +memory. + +You should also ensure that the @code{ATTRIBUTE_FORMAT_ARG()} gets +@code{#define}-ed to something useful. There is an autoconf macro +named @code{AG_COMPILE_FORMAT_ARG} in @file{ag_macros.m4} that will +set it appropriately for you. If you do not do this, then translated +formatting strings may trigger GCC compiler warnings. + +To internationalize option processing, you should first internationalize your +program. Then, the option processing strings can be added to your translation +text by processing the AutoOpts-generated @file{my-opts.c} file and adding the +distributed @file{po/usage-txt.pot} file. (Also by extracting the strings +yourself from the @file{usage-txt.h} file.) When you call +@code{optionProcess}, all of the user visible AutoOpts strings will be passed +through the localization procedure established with the @code{_()} +preprocessing macro. + +All of this is @emph{dis}-abled if you specify the global attribute +@code{no-xlate} to @emph{anything}. + +@c === SECTION MARKER + +@node Naming Conflicts +@section Naming Conflicts +@cindex Naming Conflicts + +AutoOpts generates a header file that contains many C preprocessing macros and +several external names. For the most part, they begin with either @code{opt_} +or @code{option}, or else they end with @code{_opt}. If this happens to +conflict with other macros you are using, or if you are compiling multiple +option sets in the same compilation unit, the conflicts can be avoided. You +may specify an external name @code{prefix} (@pxref{program attributes}) for +all of the names generated for each set of option definitions. + +Among these macros, several take an option name as a macro argument. +Sometimes, this will inconveniently conflict. For example, if you specify an +option named, @code{debug}, the emitted code will presume that @code{DEBUG} is +not a preprocessing name. Or also, if you are building on a Windows platform, +you may find that MicroSoft has usurped a number of user space names in its +header files. Consequently, you will get a preprocessing error if you use, +for example, @code{HAVE_OPT(DEBUG)} or @code{HAVE_OPT(INTERNAL)} +(@pxref{HAVE_OPT}) in your code. You may trigger an obvious warning for such +conflicts by specifying the @code{guard-option-names} attribute +(@pxref{program attributes}). That emitted code will also @code{#undef}-ine +the conflicting name. + +@node All Attribute Names +@section All Attribute Names + +This is the list of all the option attributes used in the various +option processing templates. There are several flavors of attributes, +and these are not distinguished here. + +@itemize @bullet +@item +Valid, current attributes that you are encouraged to use. +@item +Internally generated attributes that you cannot use at all. +I need to prefix these with a distinguished prefix. e.g. @code{ao-} +@item +Valid attributes, but are deprecated. Alternates should be documented. +@end itemize + +This list is derived by running many example option definitions through the +option generation and man page templates and noting which attributes are +actually used. There may be a few that are used but not exercised in my +testing. If so, I need to ferret those out and test them, too. + +@example +addtogroup aliases allow_errors arg_default +arg_name arg_optional arg_range arg_type +argument author call_proc cmd_section +comment_char concept config_header copyright +date default deprecated descrip +detail die_code disable disable_load +disable_save doc doc_section doc_sub +doc_sub_cmd documentation ds_format ds_text +ds_type eaddr enable enabled +environrc equivalence exit_desc exit_name +explain export extract_code field +file_fail_code flag flag_code flag_proc +flags_cant flags_must full_usage gnu_usage +guard_option_names handler_proc handler_type help_type +help_value home_rc homerc ifdef +ifndef immed_disable immediate include +interleaved keyword lib_name library +load_opts_value long_opts main_fini main_init +main_type max min more_help_value +must_set name no_command no_libopts +no_misuse_usage no_preset no_xlate omit_texi +omitted_usage open_file opt_state option_format +option_info owner package prefix +prefix_enum preserve_case prog_descrip prog_info_descrip +prog_man_descrip prog_name prog_title rcfile +reorder_args reset_value resettable save_opts_value +scaled set_desc set_index settable +short_usage stack_arg stdin_input sub_name +sub_text sub_type test_main translators +type unshar_file_code unstack_arg usage +usage_message usage_opt usage_value value +vendor_opt version version_proc version_value +@end example + +@node Option Define Names +@section Option Definition Name Index +@printindex vr + +@ignore +END == AUTOINFO == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore +@page +@node Add-Ons +@chapter Add-on packages for AutoGen + +This chapter includes several programs that either work closely +with AutoGen (extracting definitions or providing special formatting +functions), or leverage off of AutoGen technology. There is also +a formatting library that helps make AutoGen possible. + +AutoOpts ought to appear in this list as well, but since it is +the primary reason why many people would even look into AutoGen +at all, I decided to leave it in the list of chapters. + +@menu +* AutoFSM:: Automated Finite State Machine. +* AutoXDR:: Combined RPC Marshalling. +* AutoEvents:: Automated Event Management. +* Bit Maps:: Bit Maps and Enumerations. +* columns Invocation:: Invoking columns. +* getdefs Invocation:: Invoking getdefs. +* xml2ag Invocation:: Invoking xml2ag. +* snprintfv:: The extensible format printing library. +@end menu +@ignore +START == AUTOFSM == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@c === SECTION MARKER + +@node AutoFSM +@section Automated Finite State Machine +@cindex AutoFSM +@cindex finite state machine + +The templates to generate a finite state machine in C or C++ is included +with AutoGen. The documentation is not. The documentation is in HTML +format for @uref{http://www.gnu.org/software/autogen/autofsm.html,viewing}, +or you can @uref{http://download.sourceforge.net/autogen/,download FSM}. + +@node AutoXDR +@section Combined RPC Marshalling +@cindex RPC +@cindex rpcgen +@cindex remote procedure call +@cindex AutoXDR +@cindex XDR + +The templates and NFSv4 definitions are not included with AutoGen in any way. +The folks that designed NFSv4 noticed that much time and bandwidth was +wasted sending queries and responses when many of them could be bundled. +The protocol bundles the data, but there is no support for it in rpcgen. +That means you have to write your own code to do that. Until now. +Download this and you will have a large, complex example of how to use +@code{AutoXDR} for generating the marshaling and unmarshaling of combined +RPC calls. There is a brief example +@uref{http://www.gnu.org/software/autogen/xdr/index.html,on the web}, but +you should @uref{http://download.sourceforge.net/autogen/,download AutoXDR}. + +@c === SECTION MARKER + +@node AutoEvents +@section Automated Event Management +@cindex AutoEvents + +Large software development projects invariably have a need to manage +the distribution and display of state information and state changes. +In other words, they need to manage their software events. Generally, +each such project invents its own way of accomplishing this and then +struggles to get all of its components to play the same way. It is a +difficult process and not always completely successful. This project +helps with that. + +AutoEvents completely separates the tasks of supplying the data +needed for a particular event from the methods used to manage the +distribution and display of that event. Consequently, the programmer +writing the code no longer has to worry about that part of the +problem. Likewise the persons responsible for designing the event +management and distribution no longer have to worry about getting +programmers to write conforming code. + +This is a work in progress. See my +@uref{http://www.gnu.org/software/autogen/autoevents.html,web page} +on the subject, if you are interested. +I have some useful things put together, but it is not ready +to call a product. + +@ignore +END == AUTOFSM == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore +@page +@ignore +* * * * * * * * * * * * * * * * * +@end ignore +@include invoke-bitmaps.texi + +@page +@ignore +* * * * * * * * * * * * * * * * * +@end ignore +@include invoke-columns.texi + +@page +@ignore +* * * * * * * * * * * * * * * * * +@end ignore +@include invoke-getdefs.texi + +@page +@ignore +* * * * * * * * * * * * * * * * * +@end ignore +@include invoke-xml2ag.texi + +@page +@ignore +* * * * * * * * * * * * * * * * * +@end ignore +@include invoke-snprintfv.texi +@ignore +START == FUTURE == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore +@ignore +END == FUTURE == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore +@page +@node Future +@chapter Some ideas for the future. +@cindex futures + +Here are some things that might happen in the distant future. + +@itemize @bullet +@item +Fix up current tools that contain +miserably complex perl, shell, sed, awk and m4 scripts +to instead use this tool. +@end itemize +@node Copying This Manual +@appendix Copying This Manual + +You may copy this manual under the terms of the FDL +(@url{http://gnu.org/licenses/fdl.texi,the GNU Free Documentation License}). + + + +@page +@node Concept Index +@unnumbered Concept Index + +@printindex cp +@page +@node Function Index +@unnumbered Function Index + +@printindex fn +@page +@contents +@bye + diff --git a/doc/auto-opts.tlib b/doc/auto-opts.tlib new file mode 100644 index 0000000..58c4d80 --- /dev/null +++ b/doc/auto-opts.tlib @@ -0,0 +1,469 @@ +[= -*- Mode: texinfo -*- + + AutoGen5 Template + +# This file is part of AutoGen. +# AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +# +# AutoGen is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# AutoGen is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see <http://www.gnu.org/licenses/>. +=] + +@page +@node AutoOpts +@chapter Automated Option Processing +@cindex autoopts + +AutoOpts [= +(make-tmp-dir) +(out-push-new) +=] +test ${#AGexe} -eq 0 -o ${#top_srcdir} -eq 0 -o ${top_builddir} -eq 0 && \ + die "AGexe, top_srcdir and top_builddir must be set" +ag_cmd="${AGexe} -L${top_srcdir}/autoopts/tpl" +test "X${top_srcdir}" = "X${top_builddir}" || \ + ag_cmd="${ag_cmd} -L${top_builddir}/autoopts/tpl" +readonly ag_cmd + +run_ag() { + echo ${ag_cmd} "$@" >&2 + ${ag_cmd} "$@" +} + +eval "`egrep '^AO_[A-Z]*=' ${top_srcdir}/VERSION`" 2> /dev/null +echo ${AO_CURRENT}.${AO_REVISION} +[= + +(shell (out-pop #t)) + +=] is bundled with AutoGen. It is a tool that virtually eliminates the +hassle of processing options and keeping man pages, info docs and usage text +up to date. This package allows you to specify several program attributes, +thousands of option types and many option attributes. From this, it then +produces all the code necessary to parse and handle the command line and +configuration file options, and the documentation that should go with your +program as well. +[= + +INVOKE get-text tag = autoopts =][= +(out-push-new (string-append tmp-dir "/check.def" )) + +=] +AutoGen Definitions options; +prog-name = check; +prog-title = "Checkout Automated Options"; +long-opts; +gnu-usage; /* GNU style preferred to default */ + +main = { main-type = shell-process; }; + +flag = { + name = check-dirs; + value = L; /* flag style option character */ + arg-type = string; /* option argument indication */ + max = NOLIMIT; /* occurrence limit (none) */ + stack-arg; /* save opt args in a stack */ + descrip = "Checkout directory list"; + doc = 'name of each directory that is to be "checked out".'; +}; + +flag = { + name = show_defs; + descrip = "Show the definition tree"; + disable = dont; /* mark as enable/disable type */ + /* option. Disable as `dont-' */ + doc = 'disable, if you do not want to see the tree.'; +}; +[= (texi-escape-encode (out-pop #t)) \=] +@end example + +@node quick ao build +@subsection Build the example options + +This program will produce a program that digests its options and +writes the values as shell script code to stdout. +Run the following short script to produce this program:[= # + +Developer note: the following only works when AutoGen has been installed. +Since this may be being built on a system where it has not been installed, +the code below ensures we are running out tools out of the build directory +=] +@example +[= + +(out-push-new (string-append tmp-dir "/mk-check.sh" )) + +\=] +base=check +BASE=`echo $base | tr '[a-z-]' '[A-Z_]'` +cflags="-DTEST_${BASE} `autoopts-config cflags`" +ldflags="`autoopts-config ldflags`" +autogen ${base}.def +cc -o ${base} -g ${cflags} ${base}.c ${ldflags} +./${base} --help +[= (texi-escape-encode (out-pop #t)) \=] +@end example + +@node quick ao help +@subsection Example option help text + +Running the build commands yields: + +@example +[= (out-push-new) \=] +base=check +cd ${tmp_dir} +( + PS4='>ck> ' + BASH_XTRACEFD=2 + exec 2> ${base}-msg.log 1>&2 + set -x + + test -f ${base}.def || die "cannot locate ${base}.def" + test ! -f ${base} || rm -f ${base} + echo "include = '#include \"compat/compat.h\"';" >> ${base}.def + f='@="@="'`echo ${INCLUDES} ${CFLAGS}`' @' + sed -e "s@^cc @${CC:-cc} -include ${top_builddir}/config.h @" \ + -e '/^cflags="/s'"${f}" \ + -e 's@^autogen @run_ag @' \ + mk-${base}.sh > mk-${base} + + . ./mk-${base} +) +test -x ./${base} || { + cat mk-${base} + printf '\n\nFAILURE LOG:\n\n' + cat ${base}-msg.log + tar czf /tmp/ck-fail.tgz . + die cannot create ${base} program +} >&2 + +./${base} --help | sed 's/\t/ /g' +[= + +(texi-escape-encode (shell (out-pop #t))) + +=] +@end example +[= + +INVOKE get-text tag = autoopts-main + +=] +Here is an example program that uses the following set of definitions: + +@example +[= + + (out-push-new (string-append tmp-dir "/default-test.def" )) + +=]AutoGen Definitions options; + +prog-name = default-test; +prog-title = 'Default Option Example'; +homerc = '$$/../share/default-test', '$HOME', '.'; +environrc; +long-opts; +gnu-usage; +usage-opt; +version = '1.0'; +main = { + main-type = shell-process; +}; +#define DEBUG_FLAG +#define WARN_FLAG +#define WARN_LEVEL +#define VERBOSE_FLAG +#define VERBOSE_ENUM +#define DRY_RUN_FLAG +#define OUTPUT_FLAG +#define INPUT_FLAG +#define DIRECTORY_FLAG +#define INTERACTIVE_FLAG +#include stdoptions.def +[= + + (texi-escape-encode (out-pop #t)) + +=]@end example + +@noindent +Running a few simple commands on that definition file: + +@example +autogen default-test.def +copts="-DTEST_DEFAULT_TEST_OPTS `autoopts-config cflags`" +lopts="`autoopts-config ldflags`" +cc -o default-test $@{copts@} default-test.c $@{lopts@} +@end example + +@noindent +Yields a program which, when run with @file{--help}, prints out: + +@example +[= (out-push-new) \=] +set -x +log_file=${tmp_dir}/ao-doc-log +exec 7>&2 ; exec 2>> ${log_file} +TOPDIR=`cd ${top_builddir} >/dev/null ; pwd` +OPTDIR=${TOPDIR}/autoopts + +{ + cd ${tmp_dir} + chmod 666 *.def + echo 'config-header = "config.h";' >> default-test.def + HOME=${tmp_dir} run_ag default-test.def + test -f default-test.c || die 'NO default-test.c PROGRAM' + + opts="-o default-test -DTEST_DEFAULT_TEST_OPTS ${INCLUDES}" + ${CC:-cc} ${CFLAGS} ${opts} default-test.c ${LIBS} || \ + rm -f ./default-test + + test -x ./default-test || { + exec 2>&7 + fail_text=`cat $log_file`$'\n\nprogram:\n'`cat default-test.c` + die 'NO default-test EXECUTABLE + '"$fail_text"' + === END FAIL TEXT' + } +} >&2 + +HOME=${tmp_dir} ${tmp_dir}/default-test --help | \ + sed 's, , ,g;s,\([@{}]\),@\1,g' + +exec 2>&7 7>&- +[= + (shell (out-pop #t)) +=] +@end example +[= + +INVOKE get-text tag = autoopts-api + +=] +[=` + +f=../autoopts/libopts.texi +test -f $f || { + f=${top_srcdir}/autoopts/libopts.texi + test -f $f || die "Cannot locate libopts.texi in $f" +} +cat $f + +`=] +[= + +INVOKE get-text tag = "autoopts-data" + +=] +@noindent +Doing so with getdefs' option definitions yields this sample-getdefsrc file. +I tend to be wordy in my @code{doc} attributes: + +@example +[= (texi-escape-encode (shell " + cd ${tmp_dir} + run_ag -Trc-sample.tpl ${top_srcdir}/getdefs/opts.def >/dev/null + test -f sample-getdefsrc || die did not create sample-getdefsrc + cat sample-getdefsrc +" )) =] +@end example +[= + +INVOKE get-text tag = "ao-data1" + +=] +@example[= +(out-push-new (string-append tmp-dir "/hello.c")) + +\=] + +#include <config.h> +#include <sys/types.h> +#include <stdio.h> +#include <pwd.h> +#include <string.h> +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#include <autoopts/options.h> +int main(int argc, char ** argv) { + char const * greeting = "Hello"; + char const * greeted = "World"; + tOptionValue const * pOV = configFileLoad("hello.conf"); + + if (pOV != NULL) { + const tOptionValue* pGetV = optionGetValue(pOV, "greeting"); + + if ( (pGetV != NULL) + && (pGetV->valType == OPARG_TYPE_STRING)) + greeting = strdup(pGetV->v.strVal); + + pGetV = optionGetValue(pOV, "personalize"); + if (pGetV != NULL) { + struct passwd * pwe = getpwuid(getuid()); + if (pwe != NULL) + greeted = strdup(pwe->pw_gecos); + } + + optionUnloadNested(pOV); /* deallocate config data */ + } + printf("%s, %s!\n", greeting, greeted); + return 0; +} +[= (texi-escape-encode (out-pop #t)) \=] +@end example + +@noindent +With that text in a file named ``hello.c'', this short script: + +@example +cc -o hello hello.c `autoopts-config cflags ldflags` +./hello +echo 'greeting Buzz off' > hello.conf +./hello +echo personalize > hello.conf +./hello +@end example + +@noindent +will produce the following output: + +@example +[= (texi-escape-encode (shell " +cd ${tmp_dir} +${CC:-cc} -o hello hello.c ${CFLAGS} ${LIBS} ${LDFLAGS} || \ + die cannot compile hello +./hello +echo 'greeting Buzz off' > hello.conf +./hello +echo personalize > hello.conf +./hello" +)) =] +@end example +[= + +INVOKE get-text tag = "ao-data2" + +=] +[= + + (out-push-new) + +=]( + exec 4>&2 2> ${tmp_dir}/err-test-log.txt + BASH_XTRACEFD=2 + PS4='>etl> ' + set -x + cd ${top_builddir}/autoopts/test || \ + die "cannot cd into ${top_builddir}/autoopts/test" + VERBOSE=true AUTOGEN_TRACE=every AUTOGEN_TRACE_OUT=">>$PWD/ag-log.txt" + export VERBOSE AUTOGEN_TRACE AUTOGEN_TRACE_OUT + ${MAKE:-make} check TESTS=errors.test 1>&2 || : + if test ! -x errors-testd/errors + then + exec 2>&4 + cat ${tmp_dir}/err-test-log.txt >&2 + die "no error usage in $PWD/errors-testd" + fi + cat <<-EOF + + Here is the usage output example from AutoOpts error handling + tests. The option definition has argument reordering enabled: + + @example +EOF + + ./errors-testd/errors -? | sed 's, , ,g;s,\([@{}]\),@\1,g' + cmd='errors operand1 -s first operand2 -X -- -s operand3' + cat <<-EOF + @end example + + Using the invocation, + @example + test-${cmd} + @end example + you get the following output for your shell script to evaluate: + + @example + `./errors-testd/${cmd}` + @end example +EOF +)[= + +(shell (out-pop #t)) + +=] +@node script-parser +@subsection Parsing with a Portable Script + +If you had used @code{test-main = optionParseShell} instead, then you can, +at this point, merely run the program and it will write the parsing +script to standard out. You may also provide this program with command +line options to specify the shell script file to create or edit, and you +may specify the shell program to use on the first shell script line. +That program's usage text would look something like the following +and the script parser itself would be very verbose: + +@example +[= ` + +log=${tmp_dir}/../genshellopt.log + +( + set -x + opts="-o genshellopt -DTEST_GETDEFS_OPTS ${INCLUDES}" + exec 3> ${tmp_dir}/genshellopt.def + cat ${top_srcdir}/getdefs/opts.def >&3 + echo "test_main = 'optionParseShell';" >&3 + echo 'config-header = "config.h";' >&3 + exec 3>&- + + cd ${tmp_dir} + HOME='' run_ag -t40 genshellopt.def + test $? -eq 0 || die "autogen failed to create genshellopt.c - See ${log}" + + ${CC} ${CFLAGS} ${opts} genshellopt.c ${LIBS} + test $? -eq 0 || { + head -n 50000 genshellopt.[ch] + die "could not compile genshellopt.c - See ${log}" + } +) > ${log} 2>&1 + +test -x ${tmp_dir}/genshellopt || \ + die "NO GENSHELLOPT PROGRAM - See ${log}" + +${tmp_dir}/genshellopt --help > ${tmp_dir}/genshellopt.hlp + +${tmp_dir}/genshellopt -o ${tmp_dir}/genshellopt.sh || \ + die cannot create ${tmp_dir}/genshellopt.sh + +sedcmd='s,\t, ,g;s,\\([@{}]\\),@\\1,g' +sed "${sedcmd}" ${tmp_dir}/genshellopt.hlp +cat <<- \_EOF_ + @end example + + @noindent + Resulting in the following script: + @example + _EOF_ + +sed "${sedcmd}" ${tmp_dir}/genshellopt.sh + +` =] +@end example +[= + +INVOKE get-text tag = autoinfo + +=] diff --git a/doc/auto_gen-tpl.in b/doc/auto_gen-tpl.in new file mode 100644 index 0000000..839b7e5 --- /dev/null +++ b/doc/auto_gen-tpl.in @@ -0,0 +1,679 @@ +[= AutoGen5 template + +texi + +## Documentation template +## +## Author: Bruce Korb <bkorb@gnu.org> +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see <http://www.gnu.org/licenses/>. +## --------------------------------------------------------------------- + +# Set up some global Scheme variables +# +(setenv "SHELL" "@CONFIG_SHELL@") + +(define texi-file-source (getenv "DOC_TEXT")) + +(define texi-escape-encode (lambda (in-str) + (string-substitute in-str + '("@" "{" "}") + '("@@" "@{" "@}") +) )) + +(define temp-txt "") +(define text-tag "") +(define func-name "") +(define func-str "") +(define func-name "") +(define func-str "") +(make-tmp-dir) + +=][= # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +\=] +@settitle [= package =] - [= prog-title =] +@setchapternewpage off +@syncodeindex pg cp +@c %**end of header +@copying +This manual is for GNU AutoGen version [= ` + UPDATED=\`date '+%B %Y'\` + echo ${AG_REVISION}, updated ${UPDATED}` =]. + +Copyright @copyright{} [= copyright.date =] by Bruce Korb. + +@quotation +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.2 or +any later version published by the Free Software Foundation; with no +Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. +@end quotation +@end copying + +@ignore +[=(set-writable) (dne "")=] + +Plus bits and pieces gathered from all over the source/build +directories: +[= ` for f in ${DOC_DEPENDS} ; do echo " $f" ; done ` =] + +@end ignore + +@dircategory GNU programming tools +@direntry +* AutoGen: (autogen). [= prog-title =] +@end direntry + +@ifinfo +@ifnothtml +This file documents [= package =] Version [=`echo ${AG_REVISION}`=]. + +AutoGen copyright @copyright{} [= copyright.date =] Bruce Korb +AutoOpts copyright @copyright{} [= copyright.date =] Bruce Korb +snprintfv copyright @copyright{} 1999-2000 Gary V. Vaughan + +[=(gpl "AutoGen" "")=] + +@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. +@end ignore +@end ifnothtml +@end ifinfo + +@finalout +@titlepage +@title AutoGen - [= prog-title =] +@subtitle For version [=` + echo ${AG_REVISION}, ${UPDATED} `=] +@author Bruce Korb +@author @email{[= (texi-escape-encode "bkorb@gnu.org") =]} + +@page +@vskip 0pt plus 1filll +AutoGen copyright @copyright{} [= copyright.date =] Bruce Korb +@sp 2 +This is the second edition of the GNU AutoGen documentation, +@sp 2 +Published by Bruce Korb, 910 Redwood Dr., Santa Cruz, CA 95060 + +[=(gpl "AutoGen" "")=] + +@insertcopying +@end titlepage + +@node Top, Introduction, , (dir) +@top The Automated Program Generator +@comment node-name, next, previous, up + +This file documents AutoGen version [=` + echo ${AG_REVISION}`=]. It is a tool designed +for generating program files that contain repetitive text with varied +substitutions. This document is very long because it is intended as a +reference document. For a quick start example, @xref{Example Usage}. + +The AutoGen distribution includes the basic generator engine and +several add-on libraries and programs. Of the most general interest +would be Automated Option processing, @xref{AutoOpts}, which also +includes stand-alone support for configuration file parsing, @xref{Features}. +@xref{Add-Ons, Add-on packages for AutoGen}, section for additional +programs and libraries associated with AutoGen. + +This edition documents version [=`echo ${AG_REVISION}, ${UPDATED}.`=] + +[=`cat autogen-intro.texi`=] + +@node Directives +@section Controlling What Gets Processed +@cindex directives + +Definition processing directives can @strong{only} be processed +if the '#' character is the first character on a line. Also, if you +want a '#' as the first character of a line in one of your string +assignments, you should either escape it by preceding it with a +backslash @samp{\}, or by embedding it in the string as in @code{"\n#"}. + +All of the normal C preprocessing directives are recognized, though +several are ignored. There is also an additional @code{#shell} - +@code{#endshell} pair. Another minor difference is that AutoGen +directives must have the hash character (@code{#}) in column 1. +Unrecognized directives produce an error. + +The final tweak is that @code{#!} is treated as a comment line. +Using this feature, you can use: @samp{#! /usr/local/bin/autogen} +as the first line of a definitions file, set the mode to executable +and "run" the definitions file as if it were a direct invocation of +AutoGen. This was done for its hack value. + +The AutoGen recognized directives are: +@table @code[=` +if test -z "$top_srcdir" || test ! -d "$top_srcdir" +then top_srcdir=.. ; fi +f=${top_srcdir}/agen5/defDirect.c +test -f ${f} || die missing $f + +load_comment() { + comment_text= + nl='' + while IFS= read -r line + do + case "X$line" in + X*' */' ) return ;; esac + + comment_text=${comment_text}${nl}$( + echo "$line" | sed 's/ *\\* *//') + nl=' +' + done + die 'end of comment not found' +} + +while IFS= read -r line +do + test "X$line" = "X/**" || continue + load_comment + IFS= read -r line || break + test "X$line" = "Xchar *" || continue + IFS= read -r line || die bad read + case "X$line" in + XdoDir_* ) + line=${line%%(*} + line=${line#doDir_} + ;; + * ) + continue + ;; + esac + { + printf '\n@item #%s\n@cindex %s\n@cindex %s directive\n' \ + $line $line $line + echo "$comment_text" + } > ${tmp_dir}/directive-$line +done < $f +cat ${tmp_dir}/directive-* +`=] +@end table +[= + +INVOKE get-text tag = COMMENTS + +=] +@node Full Syntax +@section Finite State Machine Grammar + +The preprocessing directives and comments are not part of the grammar. They +are handled by the scanner/lexer. The following was extracted directly from +the generated defParse-fsm.c source file. The "EVT:" is the token seen, +the "STATE:" is the current state and the entries in this table describe +the next state and the action to take. Invalid transitions were removed +from the table. + +@ignore +Extracted from $top_srcdir/agen5/defParse.y +@end ignore +@example +[= ` + +if test -z "$top_srcdir" || test ! -d "$top_srcdir" +then top_srcdir=.. ; fi +f=${top_srcdir}/agen5/defParse-fsm.c +test -f ${f} || die missing generated file: $f +sed -n -e '/^dp_trans_table/,/^};$/p' ${f} | \ + sed '/ \&dp_do_invalid /d;/^ *}/d;s/@/@@/g;s/{/@{/g;s/}/@}/g' + +` =] +@end example +[= + +INVOKE get-text tag = TEMPLATE + +=] +@ignore + +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +@end ignore +@page +@node AutoGen Functions +@section AutoGen Scheme Functions + +AutoGen uses Guile to interpret Scheme expressions within AutoGen +macros. All of the normal Guile functions are available, plus several +extensions (@pxref{Common Functions}) have been added to +augment the repertoire of string manipulation functions and +manage the state of AutoGen processing. + +This section describes those functions that are specific to AutoGen. +Please take note that these AutoGen specific functions are not loaded +and thus not made available until after the command line options have +been processed and the AutoGen definitions have been loaded. They may, +of course, be used in Scheme functions that get defined at those times, +but they cannot be invoked. + +@menu[= + +FOR gfunc =][= + (if (not (exist? "name")) + (error "NO NAME")) =][= + + IF (not (exist? "general_use")) =][= + INVOKE emit-menu-entry =][= + ENDIF =][= + +ENDFOR gfunc =] +* SCM autogen-version:: @file{autogen-version} - ``[= version =]'' +* SCM c-file-line-fmt:: format file info as, ``@code{#line nn "file"}'' +@end menu + +[= +FOR gfunc =][= + IF (not (exist? "general_use")) =][= + INVOKE emit-scm-func =][= + ENDIF general_use =][= +ENDFOR gfunc +=] +@ignore +Generated [= (tpl-file-line) =]. +@end ignore + +@node SCM autogen-version +@subsection @file{autogen-version} - autogen version number +@findex autogen-version + +This is a symbol defining the current AutoGen version number string. +It was first defined in AutoGen-5.2.14. +It is currently ``[= version =]''. + +@node SCM c-file-line-fmt +@subsection format file info as, ``@code{#line nn "file"}'' +@findex c-file-line-fmt + +This is a symbol that can easily be used with the functions +@xref{SCM tpl-file-line}, and @xref{SCM def-file-line}. +These will emit C program @code{#line} directives pointing to template +and definitions text, respectively. +@ignore + +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +@end ignore +@page +@node Common Functions +@section Common Scheme Functions + +This section describes a number of general purpose functions that make +the kind of string processing that AutoGen does a little easier. +Unlike the AutoGen specific functions (@pxref{AutoGen Functions}), +these functions are available for direct use during definition load time. +The equality test (@pxref{SCM =}) is ``overloaded'' to do string equivalence +comparisons. If you are looking for inequality, the Scheme/Lisp way +of spelling that is, ``(not (= ...))''. + +@menu[= + +FOR gfunc =][= + + IF (exist? "general_use") =][= + INVOKE emit-menu-entry =][= + ENDIF =][= + +ENDFOR gfunc + +=] +@end menu + +[= + +FOR gfunc =][= + IF (exist? "general_use") =][= + INVOKE emit-scm-func =][= + ENDIF general_use =][= +ENDFOR gfunc + +=][= + +INVOKE get-text tag = MACROS + +=] +@menu +* AGMacro syntax:: AutoGen Macro Syntax[= +FOR macfunc =][= + IF (exist? "desc") =][= + (sprintf "\n* %-18s %s - %s" + (string-append (get "name") "::" ) + (string-upcase! (get "name")) + (get "what") ) =][= + ENDIF =][= +ENDFOR macfunc=] +* shell command:: Inserting text from a shell script +* guile command:: Inserting text from a scheme script +@end menu +@node AGMacro syntax +@subsection AutoGen Macro Syntax +@cindex macro syntax + +The general syntax is: + +@example +[ @{ <native-macro-name> | <user-defined-name> @} ] [ <arg> ... ] +@end example + +@noindent +The syntax for @code{<arg>} depends on the particular macro, +but is generally a full expression (@pxref{expression syntax}). +Here are the exceptions to that general rule: + +@enumerate +@item +@code{INVOKE} macros, implicit or explicit, must be followed by +a list of name/string value pairs. The string values are +@i{simple expressions}, as described above. + +That is, the @code{INVOKE} syntax is one of these two: +@example +<user-macro-name> [ <name> [ = <expression> ] ... ] + +INVOKE <name-expression> [ <name> [ = <expression> ] ... ] +@end example + +@item +AutoGen FOR macros must be in one of three forms: + +@example +FOR <name> [ <separator-string> ] + +FOR <name> (...Scheme expression list) + +FOR <name> IN <string-entry> [ ... ] +@end example +@noindent +where: +@table @samp +@item <name> +must be a simple name. +@item <separator-string> +is inserted between copies of the enclosed block. Do not try to use ``IN'' +as your separator string. It won't work. +@item <string-entry> +is an entry in a list of strings. ``@code{<name>}'' is assigned +each value from the ``@code{IN}'' list before expanding the @code{FOR} block. +@item (...Scheme expression list) +is expected to contain one or more of the @code{for-from}, +@code{for-to}, @code{for-by}, and @code{for-sep} functions. +(@xref{FOR}, and @ref{AutoGen Functions}) +@end table + +The first two forms iterate over the @code{FOR} block if @code{<name>} +is found in the AutoGen values. The last form will create the AutoGen +value named @code{<name>}. + +@item +AutoGen @code{DEFINE} macros must be followed by a simple name. +Anything after that is ignored. Consequently, that ``comment space'' +may be used to document any named values the macro expects to have +set up as arguments. @xref{DEFINE}. + +@item +The AutoGen @code{COMMENT}, @code{ELSE}, @code{ESAC} and the @code{END*} +macros take no arguments and ignore everything after the macro name +(e.g. see @ref{COMMENT}) +@end enumerate[= # + + +@c FOR each defined function, +@c this code will insert the extracted documentation =][= + +FOR macfunc =][= + IF (exist? "desc") =] + +@node [=name=] +@subsection [=% name (string-upcase! "%s") =] - [=what=] +[= id-file =] +@findex [=% name (string-upcase! "%s") =][= + (if (exist? "cindex") + (string-append "\n@cindex " + (join "\n@cindex " (stack "cindex")) )) =] + +[=desc=][= + ENDIF desc exists =][= +ENDFOR macfunc=] +@node shell command +@subsection Inserting text from a shell script + +If the text between the start and end macro markers starts with an opening +curly brace ('@code{@{}') or is surrounded by back quotes ('@code{`}'), then +the text is handed off to the server shell for evaluation. The output to +standard out is inserted into the document. If the text starts with the +curly brace, all the text is passed off as is to the shell. If surrounded by +back quotes, then the string is ``cooked'' before being handed off to the +shell. + +@node guile command +@subsection Inserting text from a scheme script + +If the text between the start and end macro markers starts with a semi-colon +or an opening parenthesis, all the text is handed off to the Guile/scheme +processor. If the last result is text or a number, it is added (as text) +to the output document. + +[= + +INVOKE get-text tag = augmenting + +=] +@ignore + +Invocation section from [= ag-texi =] + +@end ignore +@page + +@include [= ag-texi =] + +[= + +INVOKE get-text tag = installation =][= +INCLUDE "auto-opts.tlib" + +=] +@page +@node Add-Ons +@chapter Add-on packages for AutoGen + +This chapter includes several programs that either work closely +with AutoGen (extracting definitions or providing special formatting +functions), or leverage off of AutoGen technology. There is also +a formatting library that helps make AutoGen possible. + +AutoOpts ought to appear in this list as well, but since it is +the primary reason why many people would even look into AutoGen +at all, I decided to leave it in the list of chapters. + +@menu +* AutoFSM:: Automated Finite State Machine. +* AutoXDR:: Combined RPC Marshalling. +* AutoEvents:: Automated Event Management. +* Bit Maps:: Bit Maps and Enumerations. +* columns Invocation:: Invoking columns. +* getdefs Invocation:: Invoking getdefs. +* xml2ag Invocation:: Invoking xml2ag. +* snprintfv:: The extensible format printing library. +@end menu +[= + +INVOKE get-text tag = autofsm + +=][= + +FOR addon-texi + +=] +@page +@ignore +* * * * * * * * * * * * * * * * * +@end ignore +@include [= addon-texi =] +[= + +ENDFOR =][= + +INVOKE get-text tag = Future + +=] +@page +@node Future +@chapter Some ideas for the future. +@cindex futures + +Here are some things that might happen in the distant future. + +@itemize @bullet +@item +Fix up current tools that contain +miserably complex perl, shell, sed, awk and m4 scripts +to instead use this tool. +@end itemize +@node Copying This Manual +@appendix Copying This Manual + +You may copy this manual under the terms of the FDL +(@url{http://gnu.org/licenses/fdl.texi,the GNU Free Documentation License}). + +[=`sed '1,/^@appendixsec/d' fdl.texi`=] + +@page +@node Concept Index +@unnumbered Concept Index + +@printindex cp +@page +@node Function Index +@unnumbered Function Index + +@printindex fn +@page +@contents +@bye +[= + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +=][= + +DEFINE id-file =] +@ignore +Generated [= (tpl-file-line) =]. +Extracted from [=srcfile=] line [=linenum=]. +@end ignore +[= + +ENDDEF id-file + +# # # # # # # # # # # # # # # # # # # # =][= + +DEFINE get-text =][= + +(set! text-tag + (string-append "@ignore\n%s == " + (string-upcase! (get "tag")) " == %s or the surrounding 'ignore's\n" + "Extraction from autogen.texi\n" + "@end ignore" )) + +(extract texi-file-source text-tag) =][= + +ENDDEF get-text + +# # # # # # # # # # # # # # # # # # # # =][= + +DEFINE set-func-name =][= + + (set! func-name (shell (sprintf "echo '%s' | + sed -e 's/-p$/?/' -e 's/-x$/!/' -e 's/-to-/->/'" + (string-tr! (get "name") "A-Z_^" "a-z--") )) ) + + (set! func-str + (if (exist? "string") (get "string") func-name)) =][= + +ENDDEF + +# # # # # # # # # # # # # # # # # # # # =][= + +DEFINE emit-scm-func =][= + + INVOKE set-func-name =] +@node SCM [= (. func-str)=] +@subsection [= (string-append "@file{" func-name "} - " (get "what")) =] +@findex [= (. func-name) =][= +% string "\n@findex %s" =] +[= id-file =] +Usage: ([= (. func-str) =][= + + FOR exparg =] [= + + arg_optional "[ " =][=arg_name=][= arg_list " ..." =][= + arg_optional " ]" =][= + + ENDFOR exparg =]) +@* +[= string (string-append func-name ": ") =][= + (shell (string-append + "(sed \"s/^\\`'//\" <<\\_EODoc_\n" + (if (exist? "doc") (get "doc") "This function is not documented.") + "\n_EODoc_\n)" ))=] +[= + IF (exist? "exparg") =] +Arguments:[= + FOR exparg =] +@* +[=arg_name=] - [= + + arg_optional "Optional - " =][= + IF (exist? "arg_desc") =][=arg_desc=][= + ELSE =]Undocumented[= + ENDIF =][= + + ENDFOR exparg =][= + + ELSE + =] +This Scheme function takes no arguments.[= + ENDIF =] +[= + +ENDDEF + +# # # # # # # # # # # # # # # # # # # # =][= + +DEFINE emit-menu-entry =][= + + INVOKE set-func-name =][= + (sprintf "\n* SCM %-20s @file{%s} - %s" (string-append func-str "::") + func-name (get "what")) + =][= +ENDDEF emit-menu-entry + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +=][= # + +;; Local Variables: +;; indent-tabs-mode: nil +;; mode: texinfo +;; End: + +auto_gen-tpl.in ends here =] diff --git a/doc/autogen-intro.texi b/doc/autogen-intro.texi new file mode 100644 index 0000000..f379f3c --- /dev/null +++ b/doc/autogen-intro.texi @@ -0,0 +1,819 @@ +@ignore + +This file is part of AutoGen. +AutoGen is free software. +AutoGen is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + +AutoGen is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +AutoGen is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program. If not, see <http://www.gnu.org/licenses/>. + +This file has the following md5sum: + +43b91e8ca915626ed3818ffb1b71248b COPYING.gplv3 + +@end ignore +@menu +* Introduction:: AutoGen's Purpose +* Definitions File:: AutoGen Definitions File +* Template File:: AutoGen Template +* Augmenting AutoGen:: Augmenting AutoGen Features +* autogen Invocation:: Invoking AutoGen +* Installation:: Configuring and Installing +* AutoOpts:: Automated Option Processing +* Add-Ons:: Add-on packages for AutoGen +* Future:: Some ideas for the future. +* Copying This Manual:: Copying This Manual +* Concept Index:: General index +* Function Index:: Function index +@end menu + +@ignore +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +@end ignore +@page +@node Introduction +@chapter Introduction +@cindex Introduction + +AutoGen is a tool designed for generating program files that contain +repetitive text with varied substitutions. Its goal is to simplify the +maintenance of programs that contain large amounts of repetitious text. +This is especially valuable if there are several blocks of such text +that must be kept synchronized in parallel tables. + +An obvious example is the problem of maintaining the code required for +processing program options and configuration settings. Processing options +requires a minimum of four different constructs be kept in proper order in +different places in your program. You need at least: + +@enumerate +@item +The flag character in the flag string, +@item +code to process the flag when it is encountered, +@item +a global state variable or two, and +@item +a line in the usage text. +@end enumerate + +@noindent +You will need more things besides this if you choose to implement long option +names, configuration (rc/ini) file processing, environment variable settings +and keep all the documentation for these up to date. This can be done +mechanically; with the proper templates and this program. In fact, it has +already been done and AutoGen itself uses it@: @xref{AutoOpts}. For a simple +example of Automated Option processing, @xref{Quick Start}. For a full list +of the Automated Option features, @xref{Features}. Be forewarned, though, the +feature list is ridiculously extensive. + +@menu +* Generalities:: The Purpose of AutoGen +* Example Usage:: A Simple Example +* csh/zsh caveat:: csh/zsh caveat +* Testimonial:: A User's Perspective +@end menu + +@c === SECTION MARKER + +@node Generalities +@section The Purpose of AutoGen + +The idea of this program is to have a text file, a template if +you will, that contains the general text of the desired output file. +That file includes substitution expressions and sections of text that are +replicated under the control of separate definition files. + +@cindex design goals + +AutoGen was designed with the following features: + +@enumerate +@item +The definitions are completely separate from the template. By completely +isolating the definitions from the template it greatly increases the +flexibility of the template implementation. A secondary goal is that a +template user only needs to specify those data that are necessary to describe +his application of a template. + +@item +Each datum in the definitions is named. Thus, the definitions can be +rearranged, augmented and become obsolete without it being necessary to +go back and clean up older definition files. Reduce incompatibilities! + +@item +Every definition name defines an array of values, even when there is +only one entry. These arrays of values are used to control the +replication of sections of the template. + +@item +There are named collections of definitions. They form a nested hierarchy. +Associated values are collected and associated with a group name. +These associated data are used collectively in sets of substitutions. + +@item +The template has special markers to indicate where substitutions are +required, much like the @code{$@{VAR@}} construct in a shell @code{here doc}. +These markers are not fixed strings. They are specified at the start of +each template. Template designers know best what fits into their +syntax and can avoid marker conflicts. + +We did this because it is burdensome and difficult to avoid conflicts +using either M4 tokenization or C preprocessor substitution rules. It +also makes it easier to specify expressions that transform the value. +Of course, our expressions are less cryptic than the shell methods. + +@item +These same markers are used, in conjunction with enclosed keywords, to +indicate sections of text that are to be skipped and for sections of +text that are to be repeated. This is a major improvement over using C +preprocessing macros. With the C preprocessor, you have no way of +selecting output text because it is an @i{un}varying, mechanical +substitution process. + +@item +Finally, we supply methods for carefully controlling the output. +Sometimes, it is just simply easier and clearer to compute some text or +a value in one context when its application needs to be later. So, +functions are available for saving text or values for later use. +@end enumerate + +@c === SECTION MARKER + +@node Example Usage +@section A Simple Example +@cindex example, simple AutoGen + +This is just one simple example that shows a few basic features. +If you are interested, you also may run "make check" with the +@code{VERBOSE} environment variable set and see a number of other +examples in the @file{agen5/test} directory. + +Assume you have an enumeration of names and you wish to associate some +string with each name. Assume also, for the sake of this example, +that it is either too complex or too large to maintain easily by hand. +We will start by writing an abbreviated version of what the result +is supposed to be. We will use that to construct our output templates. + +@noindent +In a header file, @file{list.h}, you define the enumeration +and the global array containing the associated strings: + +@example +typedef enum @{ + IDX_ALPHA, + IDX_BETA, + IDX_OMEGA @} list_enum; + +extern char const* az_name_list[ 3 ]; +@end example + +@noindent +Then you also have @file{list.c} that defines the actual strings: + +@example +#include "list.h" +char const* az_name_list[] = @{ + "some alpha stuff", + "more beta stuff", + "final omega stuff" @}; +@end example + +@noindent +First, we will define the information that is unique for each enumeration +name/string pair. This would be placed in a file named, @file{list.def}, +for example. + +@example +autogen definitions list; +list = @{ list_element = alpha; + list_info = "some alpha stuff"; @}; +list = @{ list_info = "more beta stuff"; + list_element = beta; @}; +list = @{ list_element = omega; + list_info = "final omega stuff"; @}; +@end example + +The @code{autogen definitions list;} entry defines the file as an AutoGen +definition file that uses a template named @code{list}. That is followed by +three @code{list} entries that define the associations between the +enumeration names and the strings. The order of the differently named +elements inside of list is unimportant. They are reversed inside of the +@code{beta} entry and the output is unaffected. + +Now, to actually create the output, we need a template or two that can be +expanded into the files you want. In this program, we use a single template +that is capable of multiple output files. The definitions above refer to a +@file{list} template, so it would normally be named, @file{list.tpl}. + +It looks something like this. +(For a full description, @xref{Template File}.) + +@example +[+ AutoGen5 template h c +] +[+ CASE (suffix) +][+ + == h +] +typedef enum @{[+ + FOR list "," +] + IDX_[+ (string-upcase! (get "list_element")) +][+ + ENDFOR list +] @} list_enum; + +extern char const* az_name_list[ [+ (count "list") +] ]; +[+ + + == c +] +#include "list.h" +char const* az_name_list[] = @{[+ + FOR list "," +] + "[+list_info+]"[+ + ENDFOR list +] @};[+ + +ESAC +] +@end example + +The @code{[+ AutoGen5 template h c +]} text tells AutoGen that this is +an AutoGen version 5 template file; that it is to be processed twice; +that the start macro marker is @code{[+}; and the end marker is +@code{+]}. The template will be processed first with a suffix value of +@code{h} and then with @code{c}. Normally, the suffix values are +appended to the @file{base-name} to create the output file name. + +The @code{[+ == h +]} and @code{[+ == c +]} @code{CASE} selection clauses +select different text for the two different passes. In this example, +the output is nearly disjoint and could have been put in two separate +templates. However, sometimes there are common sections and this is +just an example. + +The @code{[+FOR list "," +]} and @code{[+ ENDFOR list +]} clauses delimit +a block of text that will be repeated for every definition of @code{list}. +Inside of that block, the definition name-value pairs that +are members of each @code{list} are available for substitutions. + +The remainder of the macros are expressions. Some of these contain +special expression functions that are dependent on AutoGen named values; +others are simply Scheme expressions, the result of which will be +inserted into the output text. Other expressions are names of AutoGen +values. These values will be inserted into the output text. For example, +@code{[+list_info+]} will result in the value associated with +the name @code{list_info} being inserted between the double quotes and +@code{(string-upcase! (get "list_element"))} will first "get" the value +associated with the name @code{list_element}, then change the case of +all the letters to upper case. The result will be inserted into the +output document. + +If you have compiled AutoGen, you can copy out the template and definitions +as described above and run @code{autogen list.def}. This will produce +exactly the hypothesized desired output. + +One more point, too. Lets say you decided it was too much trouble to figure +out how to use AutoGen, so you created this enumeration and string list with +thousands of entries. Now, requirements have changed and it has become +necessary to map a string containing the enumeration name into the enumeration +number. With AutoGen, you just alter the template to emit the table of names. +It will be guaranteed to be in the correct order, missing none of the entries. +If you want to do that by hand, well, good luck. + +@c === SECTION MARKER + +@node csh/zsh caveat +@section csh/zsh caveat + +AutoGen tries to use your normal shell so that you can supply shell code +in a manner you are accustomed to using. If, however, you use csh or +zsh, you cannot do this. Csh is sufficiently difficult to program that +it is unsupported. Zsh, though largely programmable, also has some +anomalies that make it incompatible with AutoGen usage. Therefore, when +invoking AutoGen from these environments, you must be certain to set the +SHELL environment variable to a Bourne-derived shell, e.g., sh, ksh or +bash. + +Any shell you choose for your own scripts need to follow these basic +requirements: + +@enumerate +@item +It handles @code{trap ":" $sig} without output to standard out. This is done +when the server shell is first started. If your shell does not handle this, +then it may be able to by loading functions from its start up files. +@item +At the beginning of each scriptlet, the command @code{\\cd $PWD} +is inserted. This ensures that @code{cd} is not aliased to something +peculiar and each scriptlet starts life in the execution directory. +@item +At the end of each scriptlet, the command @code{echo mumble} is +appended. The program you use as a shell must emit the single +argument @code{mumble} on a line by itself. +@end enumerate + +@c === SECTION MARKER + +@node Testimonial +@section A User's Perspective + +@format +Alexandre wrote: +> +> I'd appreciate opinions from others about advantages/disadvantages of +> each of these macro packages. +@end format + +I am using AutoGen in my pet project, and find one of its best points to +be that it separates the operational data from the implementation. + +Indulge me for a few paragraphs, and all will be revealed: +In the manual, Bruce cites the example of maintaining command line flags +inside the source code; traditionally spreading usage information, flag +names, letters and processing across several functions (if not files). +Investing the time in writing a sort of boiler plate (a template in +AutoGen terminology) pays by moving all of the option details (usage, +flags names etc.) into a well structured table (a definition file if you +will), so that adding a new command line option becomes a simple matter +of adding a set of details to the table. + +So far so good! Of course, now that there is a template, writing all of +that tedious optargs processing and usage functions is no longer an +issue. Creating a table of the options needed for the new project and +running AutoGen generates all of the option processing code in C +automatically from just the tabular data. AutoGen in fact already ships +with such a template... AutoOpts. + +One final consequence of the good separation in the design of AutoGen is +that it is retargetable to a greater extent. The +egcs/gcc/fixinc/inclhack.def can equally be used (with different +templates) to create a shell script (inclhack.sh) or a c program +(fixincl.c). + +This is just the tip of the iceberg. AutoGen is far more powerful than +these examples might indicate, and has many other varied uses. I am +certain Bruce or I could supply you with many and varied examples, and I +would heartily recommend that you try it for your project and see for +yourself how it compares to m4. +@cindex m4 + +As an aside, I would be interested to see whether someone might be +persuaded to rationalise autoconf with AutoGen in place of m4... Ben, +are you listening? autoconf-3.0! `kay? =)O| + +@format +Sincerely, + Gary V. Vaughan +@end format + +@ignore +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +@end ignore +@page +@node Definitions File +@chapter Definitions File +@cindex definitions file +@cindex .def file + +This chapter describes the syntax and semantics of the AutoGen +definition file. In order to instantiate a template, you normally must +provide a definitions file that identifies itself and contains some +value definitions. Consequently, we keep it very simple. For +"advanced" users, there are preprocessing directives, sparse +arrays, named indexes and comments that may be used as well. + +The definitions file is used to associate values with names. Every +value is implicitly an array of values, even if there is only one value. +Values may be either simple strings or compound collections of +name-value pairs. An array may not contain both simple and compound +members. Fundamentally, it is as simple as: + +@example +prog-name = "autogen"; +flag = @{ + name = templ_dirs; + value = L; + descrip = "Template search directory list"; +@}; +@end example + +For purposes of commenting and controlling the processing of the +definitions, C-style comments and most C preprocessing directives are +honored. The major exception is that the @code{#if} directive is +ignored, along with all following text through the matching +@code{#endif} directive. The C preprocessor is not actually invoked, so +C macro substitution is @strong{not} performed. + +@menu +* Identification:: The Identification Definition +* Definitions:: Named Definitions +* Index Assignments:: Assigning an Index to a Definition +* Dynamic Text:: Dynamic Text +* Directives:: Controlling What Gets Processed +* Predefines:: Pre-defined Names +* Comments:: Commenting Your Definitions +* Example:: What it all looks like. +* Full Syntax:: Finite State Machine Grammar +* Alternate Definition:: Alternate Definition Forms +@end menu + +@c === SECTION MARKER + +@node Identification +@section The Identification Definition +@cindex identification + +The first definition in this file is used to identify it as a +AutoGen file. It consists of the two keywords, +@samp{autogen} and @samp{definitions} followed by the default +template name and a terminating semi-colon (@code{;}). That is: + +@example + AutoGen Definitions @var{template-name}; +@end example + +@noindent +Note that, other than the name @var{template-name}, the words +@samp{AutoGen} and @samp{Definitions} are searched for without case +sensitivity. Most lookups in this program are case insensitive. + +@noindent +Also, if the input contains more identification definitions, +they will be ignored. This is done so that you may include +(@pxref{Directives}) other definition files without an identification +conflict. + +@cindex template file + +@noindent +AutoGen uses the name of the template to find the corresponding template +file. It searches for the file in the following way, stopping when +it finds the file: + +@enumerate +@item +It tries to open @file{./@var{template-name}}. If it fails, +@item +it tries @file{./@var{template-name}.tpl}. +@item +It searches for either of these files in the directories listed in the +templ-dirs command line option. +@end enumerate + +If AutoGen fails to find the template file in one of these places, +it prints an error message and exits. + +@c === SECTION MARKER + +@node Definitions +@section Named Definitions +@cindex definitions + +A name is a sequence of characters beginning with an alphabetic character +(@code{a} through @code{z}) followed by zero or more alpha-numeric +characters and/or separator characters: hyphen (@code{-}), underscore +(@code{_}) or carat (@code{^}). Names are case insensitive. + +Any name may have multiple values associated with it. Every name may be +considered a sparse array of one or more elements. If there is more than +one value, the values my be accessed by indexing the value with +@code{[index]} or by iterating over them using the FOR (@pxref{FOR}) AutoGen +macro on it, as described in the next chapter. Sparse arrays are specified +by specifying an index when defining an entry +(@pxref{Index Assignments,, Assigning an Index to a Definition}). + +There are two kinds of definitions, @samp{simple} and @samp{compound}. +They are defined thus (@pxref{Full Syntax}): + +@example +compound_name '=' '@{' definition-list '@}' ';' + +simple-name[2] '=' string ';' + +no^text^name ';' +@end example + +@noindent +@code{simple-name} has the third index (index number 2) defined here. +@code{No^text^name} is a simple definition with a shorthand empty string +value. The string values for definitions may be specified in any of +several formation rules. + +@menu +* def-list:: Definition List +* double-quote-string:: Double Quote String +* single-quote-string:: Single Quote String +* simple-string:: An Unquoted String +* shell-generated:: Shell Output String +* scheme-generated:: Scheme Result String +* here-string:: A Here String +* concat-string:: Concatenated Strings +@end menu + +@cindex simple definitions +@cindex compound definitions + +@node def-list +@subsection Definition List + +@code{definition-list} is a list of definitions that may or may not +contain nested compound definitions. Any such definitions may +@strong{only} be expanded within a @code{FOR} block iterating over the +containing compound definition. @xref{FOR}. + +Here is, again, the example definitions from the previous chapter, +with three additional name value pairs. Two with an empty value +assigned (@var{first} and @var{last}), and a "global" @var{group_name}. + +@example +autogen definitions list; +group_name = example; +list = @{ list_element = alpha; first; + list_info = "some alpha stuff"; @}; +list = @{ list_info = "more beta stuff"; + list_element = beta; @}; +list = @{ list_element = omega; last; + list_info = "final omega stuff"; @}; +@end example + +@node double-quote-string +@subsection Double Quote String + +@cindex string, double quote +The string follows the C-style escaping, using the backslash to quote +(escape) the following character(s). Certain letters are translated to +various control codes (e.g. @code{\n}, @code{\f}, @code{\t}, etc.). +@code{x} introduces a two character hex code. @code{0} (the digit zero) +introduces a one to three character octal code (note: an octal byte followed +by a digit must be represented with three octal digits, thus: @code{"\0001"} +yielding a NUL byte followed by the ASCII digit 1). Any other character +following the backslash escape is simply inserted, without error, into the +string being formed. + +Like ANSI "C", a series of these strings, possibly intermixed with +single quote strings, will be concatenated together. + +@node single-quote-string +@subsection Single Quote String + +@cindex string, single quote +This is similar to the shell single-quote string. However, escapes +@code{\} are honored before another escape, single quotes @code{'} +and hash characters @code{#}. This latter is done specifically +to disambiguate lines starting with a hash character inside +of a quoted string. In other words, + +@example +fumble = ' +#endif +'; +@end example + +could be misinterpreted by the definitions scanner, whereas +this would not: + +@example +fumble = ' +\#endif +'; +@end example + +@* +As with the double quote string, a series of these, even intermixed +with double quote strings, will be concatenated together. + +@node simple-string +@subsection An Unquoted String + +A simple string that does not contain white space @i{may} be left +unquoted. The string must not contain any of the characters special to +the definition text (i.e., @code{"}, @code{#}, @code{'}, @code{(}, +@code{)}, @code{,}, @code{;}, @code{<}, @code{=}, @code{>}, @code{[}, +@code{]}, @code{`}, @code{@{}, or @code{@}}). This list is subject to +change, but it will never contain underscore (@code{_}), period +(@code{.}), slash (@code{/}), colon (@code{:}), hyphen (@code{-}) or +backslash (@code{\\}). Basically, if the string looks like it is a +normal DOS or UNIX file or variable name, and it is not one of two +keywords (@samp{autogen} or @samp{definitions}) then it is OK to not +quote it, otherwise you should. + +@node shell-generated +@subsection Shell Output String +@cindex shell-generated string + +@cindex string, shell output +This is assembled according to the same rules as the double quote string, +except that there is no concatenation of strings and the resulting string is +written to a shell server process. The definition takes on the value of +the output string. + +NB@: The text is interpreted by a server shell. There may be left over +state from previous server shell processing. This scriptlet may also leave +state for subsequent processing. However, a @code{cd} to the original +directory is always issued before the new command is issued. + +@node scheme-generated +@subsection Scheme Result String + +A scheme result string must begin with an open parenthesis @code{(}. +The scheme expression will be evaluated by Guile and the +value will be the result. The AutoGen expression functions +are @strong{dis}abled at this stage, so do not use them. + +@node here-string +@subsection A Here String +@cindex here-string + +A @samp{here string} is formed in much the same way as a shell here doc. It +is denoted with two less than characters(@code{<<}) and, optionally, a hyphen. +This is followed by optional horizontal white space and an ending +marker-identifier. This marker must follow the syntax rules for identifiers. +Unlike the shell version, however, you must not quote this marker. + +The resulting string will start with the first character on the next line and +continue up to but not including the newline that precedes the line that +begins with the marker token. The characters are copied directly into the +result string. Mostly. + +If a hyphen follows the less than characters, then leading tabs will be +stripped and the terminating marker will be recognized even if preceded by +tabs. Also, if the first character on the line (after removing tabs) is a +backslash and the next character is a tab or space, then the backslash will +be removed as well. No other kind of processing is done on this string. + +Here are three examples: +@example +str1 = <<- STR_END + $quotes = " ' ` + STR_END; + +str2 = << STR_END + $quotes = " ' ` + STR_END; +STR_END; + +str3 = <<- STR_END + \ $quotes = " ' ` + STR_END; +@end example +The first string contains no new line characters. +The first character is the dollar sign, the last the back quote. + +The second string contains one new line character. The first character +is the tab character preceding the dollar sign. The last character is +the semicolon after the @code{STR_END}. That @code{STR_END} does not +end the string because it is not at the beginning of the line. In the +preceding case, the leading tab was stripped. + +The third string is almost identical to the first, except that the +first character is a tab. That is, it exactly matches the first line +of the second string. + +@node concat-string +@subsection Concatenated Strings +@cindex concat-string + +If single or double quote characters are used, +then you also have the option, a la ANSI-C syntax, +of implicitly concatenating a series of them together, +with intervening white space ignored. + +NB@: You @strong{cannot} use directives to alter the string +content. That is, + +@example +str = "fumble" +#ifdef LATER + "stumble" +#endif + ; +@end example + +@noindent +will result in a syntax error. The preprocessing directives are not +carried out by the C preprocessor. However, + +@example +str = '"fumble\n" +#ifdef LATER +" stumble\n" +#endif +'; +@end example + +@noindent +@strong{Will} work. It will enclose the @samp{#ifdef LATER} +and @samp{#endif} in the string. But it may also wreak +havoc with the definition processing directives. The hash +characters in the first column should be disambiguated with +an escape @code{\} or join them with previous lines: +@code{"fumble\n#ifdef LATER...}. + +@c === SECTION MARKER + +@node Index Assignments +@section Assigning an Index to a Definition +@cindex Definition Index + +In AutoGen, every name is implicitly an array of values. +When assigning values, they are usually implicitly +assigned to the next highest slot. They can also be +specified explicitly: + +@example +mumble[9] = stumble; +mumble[0] = grumble; +@end example + +@noindent +If, subsequently, you assign a value to @code{mumble} without an +index, its index will be @code{10}, not @code{1}. +If indexes are specified, they must not cause conflicts. + +@code{#define}-d names may also be used for index values. +This is equivalent to the above: + +@example +#define FIRST 0 +#define LAST 9 +mumble[LAST] = stumble; +mumble[FIRST] = grumble; +@end example + +All values in a range do @strong{not} have to be filled in. +If you leave gaps, then you will have a sparse array. This +is fine (@pxref{FOR}). You have your choice of iterating +over all the defined values, or iterating over a range +of slots. This: + +@example +[+ FOR mumble +][+ ENDFOR +] +@end example + +@noindent +iterates over all and only the defined entries, whereas this: + +@example +[+ FOR mumble (for-by 1) +][+ ENDFOR +] +@end example + +@noindent +will iterate over all 10 "slots". Your template will +likely have to contain something like this: + +@example +[+ IF (exist? (sprintf "mumble[%d]" (for-index))) +] +@end example + +@noindent +or else "mumble" will have to be a compound value that, +say, always contains a "grumble" value: + +@example +[+ IF (exist? "grumble") +] +@end example + +@c === SECTION MARKER + +@node Dynamic Text +@section Dynamic Text +@cindex Dynamic Definition Text + +There are several methods for including dynamic content inside a definitions +file. Three of them are mentioned above (@ref{shell-generated} and +@pxref{scheme-generated}) in the discussion of string formation rules. +Another method uses the @code{#shell} processing directive. +It will be discussed in the next section (@pxref{Directives}). +Guile/Scheme may also be used to yield to create definitions. + +When the Scheme expression is preceded by a backslash and single +quote, then the expression is expected to be an alist of +names and values that will be used to create AutoGen definitions. + +@noindent +This method can be be used as follows: + +@example +\'( (name (value-expression)) + (name2 (another-expr)) ) +@end example + +@noindent +This is entirely equivalent to: + +@example +name = (value-expression); +name2 = (another-expr); +@end example + +@noindent +Under the covers, the expression gets handed off to a Guile function +named @code{alist->autogen-def} in an expression that looks like this: + +@example +(alist->autogen-def + ( (name (value-expression)) (name2 (another-expr)) ) ) +@end example diff --git a/doc/autogen-texi.txt b/doc/autogen-texi.txt new file mode 100644 index 0000000..951b532 --- /dev/null +++ b/doc/autogen-texi.txt @@ -0,0 +1,6114 @@ +@c -*- Mode: texinfo -*- +@setfilename autogen.info +@ignore +This file serves two purposes: + +1) it provides that stupid (at)setfilename so that automake will + deign to produce the documentation + +2) a text repository for documentation that would make the doc + template more confusing. + + + This file is part of AutoGen. + AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + + AutoGen is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + AutoGen is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program. If not, see <http://www.gnu.org/licenses/>. +@end ignore + +@ignore +START == COMMENTS == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@ignore +Resume input from autogen.texi +@end ignore + +@c === SECTION MARKER + +@node Predefines +@section Pre-defined Names +@cindex predefines + +When AutoGen starts, it tries to determine several names from the +operating environment and put them into environment variables for use in +both @code{#ifdef} tests in the definitions files and in shell scripts +with environment variable tests. @env{__autogen__} is always defined. +For other names, AutoGen will first try to use the POSIX version of the +@code{sysinfo(2)} system call. Failing that, it will try for the POSIX +@code{uname(2)} call. If neither is available, then only +"@env{__autogen__}" will be inserted into the environment. +In all cases, the associated names are converted to lower case, surrounded +by doubled underscores and non-symbol characters are replaced with +underscores. + +With Solaris on a sparc platform, @code{sysinfo(2)} is available. +The following strings are used: + +@itemize @bullet +@item +@code{SI_SYSNAME} (e.g., "__sunos__") +@item +@code{SI_HOSTNAME} (e.g., "__ellen__") +@item +@code{SI_ARCHITECTURE} (e.g., "__sparc__") +@item +@code{SI_HW_PROVIDER} (e.g., "__sun_microsystems__") +@item +@code{SI_PLATFORM} (e.g., "__sun_ultra_5_10__") +@item +@code{SI_MACHINE} (e.g., "__sun4u__") +@end itemize + +For Linux and other operating systems that only support the +@code{uname(2)} call, AutoGen will use these values: + +@itemize @bullet +@item +@code{sysname} (e.g., "__linux__") +@item +@code{machine} (e.g., "__i586__") +@item +@code{nodename} (e.g., "__bach__") +@end itemize + +By testing these pre-defines in my definitions, you can select +pieces of the definitions without resorting to writing shell +scripts that parse the output of @code{uname(1)}. You can also +segregate real C code from autogen definitions by testing for +"@code{__autogen__}". + +@example +#ifdef __bach__ + location = home; +#else + location = work; +#endif +@end example + +@c === SECTION MARKER + +@node Comments +@section Commenting Your Definitions +@cindex comments + +The definitions file may contain C and C++ style comments. + +@example +/* + * This is a comment. It continues for several lines and closes + * when the characters '*' and '/' appear together. + */ +// this comment is a single line comment +@end example + +@c === SECTION MARKER + +@node Example +@section What it all looks like. + +@noindent +This is an extended example: + +@example +autogen definitions @samp{template-name}; +/* + * This is a comment that describes what these + * definitions are all about. + */ +global = "value for a global text definition."; + +/* + * Include a standard set of definitions + */ +#include standards.def + +a_block = @{ + a_field; + a_subblock = @{ + sub_name = first; + sub_field = "sub value."; + @}; + +#ifdef FEATURE + a_subblock = @{ + sub_name = second; + @}; +#endif + +@}; +@end example + +@ignore +END == COMMENTS == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@ignore +START == TEMPLATE == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@c === SECTION MARKER + +@node Alternate Definition +@section Alternate Definition Forms +@cindex Alternate Definition + +There are several methods for supplying data values for templates. + +@table @samp +@item no definitions +It is entirely possible to write a template that does not depend upon +external definitions. Such a template would likely have an unvarying +output, but be convenient nonetheless because of an external library +of either AutoGen or Scheme functions, or both. This can be accommodated +by providing the @option{--override-tpl} and @option{--no-definitions} +options on the command line. @xref{autogen Invocation}. + +@item CGI +AutoGen behaves as a CGI server if the definitions input is from stdin +and the environment variable @env{REQUEST_METHOD} is defined +and set to either "GET" or "POST", @xref{AutoGen CGI}. Obviously, +all the values are constrained to strings because there is no way +to represent nested values. + +@item XML +AutoGen comes with a program named, @command{xml2ag}. Its output can +either be redirected to a file for later use, or the program can +be used as an AutoGen wrapper. @xref{xml2ag Invocation}. + +The introductory template example (@pxref{Example Usage}) can be rewritten +in XML as follows: + +@example +<EXAMPLE template="list.tpl"> +<LIST list_element="alpha" + list_info="some alpha stuff"/> +<LIST list_info="more beta stuff" + list_element="beta"/> +<LIST list_element="omega" + list_info="final omega stuff"/> +</EXAMPLE> +@end example + +A more XML-normal form might look like this: +@example +<EXAMPLE template="list.tpl"> +<LIST list_element="alpha">some alpha stuff</LIST> +<LIST list_element="beta" >more beta stuff</LIST> +<LIST list_element="omega">final omega stuff</LIST> +</EXAMPLE> +@end example +@noindent +but you would have to change the template @code{list-info} references +into @code{text} references. + +@item standard AutoGen definitions +Of course. :-) + +@end table + +@ignore +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +@end ignore +@page +@node Template File +@chapter Template File +@cindex template file +@cindex .tpl file + +The AutoGen template file defines the content of the output text. +It is composed of two parts. The first part consists of a pseudo +macro invocation and commentary. It is followed by the template proper. + +@cindex pseudo macro +@cindex macro, pseudo +This pseudo macro is special. It is used to identify the file as a +AutoGen template file, fixing the starting and ending marks for +the macro invocations in the rest of the file, specifying the list +of suffixes to be generated by the template and, optionally, the +shell to use for processing shell commands embedded in the template. + +AutoGen-ing a file consists of copying text from the template to the +output file until a start macro marker is found. The text from the +start marker to the end marker constitutes the macro text. AutoGen +macros may cause sections of the template to be skipped or processed +several times. The process continues until the end of the template is +reached. The process is repeated once for each suffix specified in the +pseudo macro. + +This chapter describes the format of the AutoGen template macros +and the usage of the AutoGen native macros. Users may augment +these by defining their own macros, @xref{DEFINE}. + +@menu +* pseudo macro:: Format of the Pseudo Macro +* naming values:: Naming a value +* expression syntax:: Macro Expression Syntax +* AutoGen Functions:: AutoGen Scheme Functions +* Common Functions:: Common Scheme Functions +* native macros:: AutoGen Native Macros +* output controls:: Redirecting Output +@end menu + +@c === SECTION MARKER + +@node pseudo macro +@section Format of the Pseudo Macro +@cindex pseudo macro + +The pseudo macro is used to tell AutoGen how to process a template. +It tells autogen: + +@enumerate +@item +The start macro marker. It consists of punctuation characters used to +demarcate the start of a macro. It may be up to seven characters long and +must be the first non-whitespace characters in the file. + +@noindent +It is generally a good idea to use some sort of opening +bracket in the starting macro and closing bracket in the ending +macro (e.g. @code{@{}, @code{(}, @code{[}, or even @code{<} +in the starting macro). It helps both visually and with editors +capable of finding a balancing parenthesis. + +@item +That start marker must be immediately followed by the identifier strings +"AutoGen5" and then "template", though capitalization is not important. +@end enumerate + +@noindent +The next several components may be intermingled: + +@enumerate 3 +@item +Zero, one or more suffix specifications tell AutoGen how many times to +process the template file. No suffix specifications mean that it is to +be processed once and that the generated text is to be written to +@file{stdout}. The current suffix for each pass can be determined with the +@code{(suffix)} scheme function (@pxref{SCM suffix}). + +The suffix specification consists of a sequence of POSIX compliant file name +characters and, optionally, an equal sign and a file name formatting +specification. That specification may be either an ordinary sequence of +file name characters with zero, one or two "%s" formatting sequences in it, +or else it may be a Scheme expression that, when evaluated, produces such a +string. The Scheme result may not be empty. The two string arguments +allowed for that string are the base name of the definition file, and the +current suffix (that being the text to the left of the equal sign). (Note: +"POSIX compliant file name characters" consist of alphanumerics plus the +period (@code{.}), hyphen (@code{-}) and underscore (@code{_}) characters.) + +If the suffix begins with one of these three latter characters and +a formatting string is not specified, then that character is presumed to +be the suffix separator. Otherwise, without a specified format string, +a single period will separate the suffix from the base name in constructing +the output file name. + +@item +Shell specification: to specify that the template was written expecting a +particular shell to run the shell commands. By default, the shell used is the +autoconf-ed @env{CONFIG_SHELL}. This will usually be @file{/bin/sh}. The +shell is specified by a hash mark (@code{#}) followed by an exclamation mark +(@code{!}) followed by a full-path file name (e.g. @file{/usr/xpg4/bin/sh} on +Solaris): +@example +[= Autogen5 Template c +#!/usr/xpg4/bin/sh +=] +@end example + +@item +Comments: blank lines, lines starting with a hash mark (@code{#}) and not +specifying a shell, and edit mode markers (text between pairs of @code{-*-} +strings) are all treated as comments. + +@item +Some scheme expressions may be inserted in order to make configuration +changes before template processing begins. +@i{before template processing begins} means that there is no current +output file, no current suffix and, basically, none of the AutoGen +specific functions +(@pxref{AutoGen Functions}) may be invoked. + +The scheme expression can also be used, for example, to save a pre-existing +output file for later text extraction (@pxref{SCM extract}). + +@example +(shellf "mv -f %1$s.c %1$s.sav" (base-name)) +@end example +@end enumerate + +@noindent +After these must come the end macro marker: + +@enumerate 6 +@item +The punctuation characters used to demarcate the end of a macro. +Like the start marker, it must consist of seven or fewer punctuation +characters. +@end enumerate + +The ending macro marker has a few constraints on its content. Some of +them are just advisory, though. There is no special check for advisory +restrictions. + +@itemize @bullet +@item +It must not begin with a POSIX file name character (hyphen @code{-}, +underscore @code{_} or period @code{.}), the backslash (@code{\}) or +open parenthesis (@code{(}). These are used to identify a suffix +specification, indicate Scheme code and trim white space. + +@item +If it begins with an equal sign, then it +must be separated from any suffix specification by white space. + +@item +The closing marker may not begin with an open parenthesis, as that is used +to enclose a scheme expression. + +@item +It cannot begin with a backslash, as that is used to indicate white +space trimming after the end macro mark. If, in the body of the template, +you put the backslash character (@code{\}) before the end macro mark, then +any white space characters after the mark and through the newline character +are trimmed. + +@item +It is also helpful to avoid using the comment marker (@code{#}). +It might be seen as a comment within the pseudo macro. + +@item +You should avoid using any of the quote characters@: double, +single or back-quote. It won't confuse AutoGen, but it might well +confuse you and/or your editor. +@end itemize + +As an example, assume we want to use @code{[+} and @code{+]} as the start +and end macro markers, and we wish to produce a @file{.c} and a @file{.h} +file, then the pseudo macro might look something like this: + +@example +[+ AutoGen5 template -*- Mode: emacs-mode-of-choice -*- +h=chk-%s.h +c +# make sure we don't use csh: +(setenv "SHELL" "/bin/sh") +] +@end example + +The template proper starts after the pseudo-macro. The starting +character is either the first non-whitespace character or the first +character after the newline that follows the end macro marker. + +@c === SECTION MARKER + +@node naming values +@section Naming a value +@cindex naming values + +When an AutoGen value is specified in a template, it is specified by name. +The name may be a simple name, or a compound name of several components. +Since each named value in AutoGen is implicitly an array of one or more +values, each component may have an index associated with it. + +@noindent +It looks like this: + +@example +comp-name-1 . comp-name-2 [ 2 ] +@end example + +Note that if there are multiple components to a name, each component +name is separated by a dot (@code{.}). Indexes follow a component name, +enclosed in square brackets (@code{[} and @code{]}). The index may be +either an integer or an integer-valued define name. The first component +of the name is searched for in the current definition level. If not +found, higher levels will be searched until either a value is found, +or there are no more definition levels. Subsequent components of the +name must be found within the context of the newly-current definition +level. Also, if the named value is prefixed by a dot (@code{.}), +@cindex . +then the value search is started in the current context only. +Backtracking +@cindex backtrack +into other definition levels is prevented. + +If someone rewrites this, I'll incorporate it. :-) + +@c === SECTION MARKER + +@node expression syntax +@section Macro Expression Syntax +@cindex expression syntax + +AutoGen has two types of expressions: full expressions and basic ones. +A full AutoGen expression can appear by itself, or as the argument +to certain AutoGen built-in macros: CASE, IF, ELIF, INCLUDE, +INVOKE (explicit invocation, @pxref{INVOKE}), and WHILE. +If it appears by itself, the result is inserted into the output. +If it is an argument to one of these macros, the macro code +will act on it sensibly. + +You are constrained to basic expressions only when passing +arguments to user defined macros, @xref{DEFINE}. + +The syntax of a full AutoGen expression is: + +@example +[[ <apply-code> ] <value-name> ] [ <basic-expr-1> [ <basic-expr-2> ]] +@end example + +How the expression is evaluated depends upon the presence or absence +of the apply code and value name. The "value name" is the name of +an AutoGen defined value, or not. If it does not name such a value, +the expression result is generally the empty string. All expressions +must contain either a @var{value-name} or a @var{basic-expr}. + +@menu +* apply code:: Apply Code +* basic expression:: Basic Expression +@end menu + +@node apply code +@subsection Apply Code + +The "apply code" selected determines the method of evaluating the +expression. There are five apply codes, including the non-use +of an apply code. + +@table @samp +@item no apply code +This is the most common expression type. +Expressions of this sort come in three flavors: + +@table @samp +@item <value-name> +The result is the value of @var{value-name}, if defined. +Otherwise it is the empty string. + +@item <basic-expr> +The result of the basic expression is the result of the full expression, +@xref{basic expression}. + +@item <value-name> <basic-expr> +If there is a defined value for @var{value-name}, then the @var{basic-expr} +is evaluated. Otherwise, the result is the empty string. +@end table + +@item % <value-name> <basic-expr> +If @var{value-name} is defined, use @var{basic-expr} as a format +string for sprintf. Then, if the @var{basic-expr} is either a back-quoted +string or a parenthesized expression, then hand the result to the +appropriate interpreter for further evaluation. Otherwise, for single +and double quote strings, the result is the result of the sprintf operation. +Naturally, if @var{value-name} is not defined, the result is the empty +string. + +For example, assume that @samp{fumble} had the string value, @samp{stumble}: +@example +[+ % fumble `printf '%%x\\n' $%s` +] +@end example +This would cause the shell to evaluate "@samp{printf '%x\n' $stumble}". +Assuming that the shell variable @samp{stumble} had a numeric value, +the expression result would be that number, in hex. Note the need +for doubled percent characters and backslashes. + +@item ? <value-name> <basic-expr-1> <basic-expr-2> +Two @var{basic-expr}-s are required. If the @var{value-name} is +defined, then the first @var{basic-expr-1} is evaluated, otherwise +@var{basic-expr-2} is. + +@item - <value-name> <basic-expr> +Evaluate @var{basic-expr} only if @var{value-name} is @i{not} defined. + +@item ?% <value-name> <basic-expr-1> <basic-expr-2> +This combines the functions of @samp{?} and @samp{%}. If @var{value-name} is +defined, it behaves exactly like @samp{%}, above, using @var{basic-expr-1}. +If not defined, then @var{basic-expr-2} is evaluated. + +For example, assume again that @samp{fumble} had the string value, +@samp{stumble}: +@example +[+ ?% fumble `cat $%s` `pwd` +] +@end example +This would cause the shell to evaluate "@samp{cat $stumble}". +If @samp{fumble} were not defined, then the result would be the name +of our current directory. +@end table + +@node basic expression +@subsection Basic Expression + +A basic expression can have one of the following forms: + +@table @samp +@item 'STRING' +A single quoted string. Backslashes can be used to protect single +quotes (@code{'}), hash characters (@code{#}), or backslashes (@code{\}) +in the string. All other characters of STRING are output as-is when the +single quoted string is evaluated. Backslashes are processed before the hash +character for consistency with the definition syntax. It is needed there +to avoid preprocessing conflicts. + +@item "STRING" +A double quoted string. This is a cooked text string as in C, +except that they are not concatenated with adjacent strings. +Evaluating "@samp{STRING}" will output STRING with all +backslash sequences interpreted. + +@item `STRING` +A back quoted string. When this expression is evaluated, STRING +is first interpreted as a cooked string (as in `"STRING"') and +evaluated as a shell expression by the AutoGen server shell. This +expression is replaced by the @file{stdout} output of +the shell. + +@item (STRING) +A parenthesized expression. It will be passed to the Guile +interpreter for evaluation and replaced by the resulting value. +If there is a Scheme error in this expression, Guile 1.4 and Guile 1.6 +will report the template line number where the error occurs. Guile 1.7 +has lost this capability. + +Guile has the capability of creating and manipulating variables that +can be referenced later on in the template processing. If you define +such a variable, it is invisible to AutoGen. To reference its value, +you must use a Guile expression. For example, +@example +[+ (define my-var "some-string-value") +] +@end example +can have that string inserted later, but only as in: +@example +[+ (. my-var) +] +@end example + +Additionally, other than in the @code{%} and @code{?%} expressions, the +Guile expressions may be introduced with the Guile comment character +(@code{;}) and you may put a series of Guile expressions within a single +macro. They will be implicitly evaluated as if they were arguments +to the @code{(begin ...)} expression. The result will be the +result of the last Guile expression evaluated. +@end table + +@ignore +END == TEMPLATE == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@ignore +START == MACROS == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@c === SECTION MARKER + +@node native macros +@section AutoGen Native Macros +@cindex native macros + +This section describes the various AutoGen natively defined macros. +Unlike the Scheme functions, some of these macros are "block macros" +with a scope that extends through a terminating macro. Block macros +must not overlap. That is to say, a block macro started within the +scope of an encompassing block macro must have its matching end macro +appear before the encompassing block macro is either ended or subdivided. + +The block macros are these: + +@table @code +@item CASE +This macro has scope through the @code{ESAC} macro. +The scope is subdivided by @code{SELECT} macros. +You must have at least one @code{SELECT} macro. + +@item DEFINE +This macro has scope through the @code{ENDDEF} macro. The defined +user macro can never be a block macro. This macro is extracted from +the template @i{before} the template is processed. Consequently, you +cannot select a definition based on context. You can, however, place +them all at the end of the file. + +@item FOR +This macro has scope through the @code{ENDFOR} macro. + +@item IF +This macro has scope through the @code{ENDIF} macro. +The scope may be subdivided by @code{ELIF} and @code{ELSE} +macros. Obviously, there may be only one @code{ELSE} macro +and it must be the last of these subdivisions. + +@item INCLUDE +This macro has the scope of the included file. +It is a block macro in the sense that the included +file must not contain any incomplete block macros. + +@item WHILE +This macro has scope through the @code{ENDWHILE} macro. +@end table +@ignore +END == MACROS == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@ignore +START == AUGMENTING == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@c === SECTION MARKER + +@node output controls +@section Redirecting Output +@cindex Redirecting Output +@cindex diversion + +AutoGen provides a means for redirecting the template output to different +files or, in @file{M4} parlance, to various diversions. It is accomplished +by providing a set of Scheme functions named @code{out-*} +(@pxref{AutoGen Functions}). + +@table @samp +@item out-push-new (@pxref{SCM out-push-new}) +This allows you to logically "push" output files onto a stack. +If you supply a string name, then a file by that name is created +to hold the output. If you do not supply a name, then the text is +written to a scratch pad and retrieved by passing a @code{#t} argument +to the @code{out-pop} (@pxref{SCM out-pop}) function. + +@item out-pop (@pxref{SCM out-pop}) +This function closes the current output file and resumes output to the next +one in the stack. At least one output must have been pushed onto the output +stack with the @code{out-push-new} (@pxref{SCM out-push-new}) function. If +@code{#t} is passed in as an argument, then the entire contents of the +diversion (or file) is returned. + +@item out-suspend (@pxref{SCM out-suspend}) +This function does not close the current output, but instead sets it aside +for resumption by the given name with @code{out-resume}. The current output +must have been pushed on the output queue with @code{out-push-new} +(@pxref{SCM out-push-new}). + +@item out-resume (@pxref{SCM out-resume}) +This will put a named file descriptor back onto the top of +stack so that it becomes the current output again. + +@item out-switch (@pxref{SCM out-switch}) +This closes the current output and creates a new file, +purging any preexisting one. This is a shortcut for "pop" +followed by "push", but this can also be done at the base level. + +@item out-move (@pxref{SCM out-move}) +Renames the current output file without closing it. +@end table + +There are also several functions for determining the output +status. @xref{AutoGen Functions}. + +@ignore + +* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + +@end ignore + +@page +@node Augmenting AutoGen +@chapter Augmenting AutoGen Features +@cindex Augmenting AutoGen + +AutoGen was designed to be simple to enhance. You can do it by +providing shell commands, Guile/Scheme macros or callout functions +that can be invoked as a Guile macro. Here is how you do these. + +@menu +* shell commands:: Shell Output Commands +* guile macros:: Guile Macros +* guile callouts:: Guile Callout Functions +* AutoGen macros:: AutoGen Macros +@end menu + +@c === SECTION MARKER + +@node shell commands +@section Shell Output Commands + +Shell commands are run inside of a server process. This means that, +unlike @file{make}, context is kept from one command to the next. +Consequently, you can define a shell function in one place inside of +your template and invoke it in another. You may also store values +in shell variables for later reference. If you load functions from +a file containing shell functions, they will remain until AutoGen exits. + +If your shell script should determine that AutoGen should stop +processing, the recommended method for stopping AutoGen is: +@example +die "some error text" +@end example + +@noindent +That is a shell function added by AutoGen. It will send a SIGTERM +to autogen and exit from the "persistent" shell. + +@c === SECTION MARKER + +@node guile macros +@section Guile Macros + +Guile also maintains context from one command to the next. This means you may +define functions and variables in one place and reference them elsewhere. +If your Scheme script should determine that AutoGen should stop +processing, the recommended method for stopping AutoGen is: +@example +(error "some error text") +@end example + +@c === SECTION MARKER + +@node guile callouts +@section Guile Callout Functions + +Callout functions must be registered with Guile to work. This can +be accomplished either by putting your routines into a shared library +that contains a @code{void scm_init(void)} routine that registers +these routines, or by building them into AutoGen. + +To build them into AutoGen, you must place your routines in the source +directory and name the files @file{exp*.c}. You also must have a stylized +comment that @file{getdefs} can find that conforms to the following: + +@example +/*=gfunc <function-name> + * + * what: <short one-liner> + * general_use: + * string: <invocation-name-string> + * exparg: <name>, <description> [, ['optional'] [, 'list']] + * doc: A long description telling people how to use + * this function. +=*/ +SCM +ag_scm_<function-name>( SCM arg_name[, ...] ) +@{ <code> @} +@end example + +@table @samp +@item gfunc +You must have this exactly thus. + +@item <function-name> +This must follow C syntax for variable names + +@item <short one-liner> +This should be about a half a line long. +It is used as a subsection title in this document. + +@item general_use: +You must supply this unless you are an AutoGen maintainer and are writing +a function that queries or modifies the state of AutoGen. + +@item <invocation-name-string> +Normally, the @var{function-name} string will be transformed into +a reasonable invocation name. However, that is not always true. +If the result does not suit your needs, then supply an alternate string. + +@item exparg: +You must supply one for each argument to your function. +All optional arguments must be last. +The last of the optional arguments may be a list, if you choose. + +@item doc: +Please say something meaningful. + +@item [, ...] +Do not actually specify an ANSI ellipsis here. You must provide +for all the arguments you specified with @var{exparg}. +@end table + +See the Guile documentation for more details. +More information is also available in a large comment at the +beginning of the @file{agen5/snarf.tpl} template file. + +@c === SECTION MARKER + +@node AutoGen macros +@section AutoGen Macros + +There are two kinds@: those you define yourself and AutoGen native. +The user-defined macros may be defined in your templates, +@xref{DEFINE}. + +As for AutoGen native macros, do not add any. It is easy to do, but I +won't like it. The basic functions needed to accomplish looping over +and selecting blocks of text have proved to be sufficient over a period +of several years. New text transformations can be easily added via any +of the AutoGen extension methods, as discussed above. + +@ignore +END == AUGMENTING == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@ignore +START == INSTALLATION == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@page +@node Installation +@chapter Configuring and Installing + +@menu +* configuring:: Configuring AutoGen +* AutoGen CGI:: AutoGen as a CGI server +* signal names:: Signal Names +* installing:: Installing AutoGen +@end menu + +@c === SECTION MARKER + +@node configuring +@section Configuring AutoGen +@cindex configuring + +AutoGen is configured and built using Libtool, Automake and Autoconf. +Consequently, you can install it wherever you wish using the @samp{--prefix} +and other options. To the various configuration options supplied by these +tools, AutoGen adds a few of its own: + +@table @samp +@item --disable-shell +AutoGen is now capable of acting as a CGI forms server, @xref{AutoGen CGI}. +As such, it will gather its definitions using either @samp{GET} or +@samp{POST} methods. All you need to do is have a template named +@file{cgi.tpl} handy or specify a different one with a command line +option. + +However, doing this without disabling the server shell brings +considerable risk. If you were to pass user input to a script +that contained, say, the classic "@samp{`rm -rf /`}", you might have +a problem. This configuration option will cause shell template +commands to simply return the command string as the result. +No mistakes. Much safer. Strongly recommended. +The default is to have server shell scripting enabled. + +Disabling the shell will have some build side effects, too. + +@itemize @bullet +@item +Many of the make check tests will fail, since they assume +a working server shell. +@item +The getdefs and columns programs are not built. +The options are distributed as definition files and they +cannot be expanded with a shell-disabled AutoGen. +@item +Similarly, the documentation cannot be regenerated because +the documentation templates depend on subshell functionality. +@end itemize + +@item --enable-debug +Turning on AutoGen debugging enables very detailed inspection of +the input definitions and monitoring shell script processing. +These options are not particularly useful to anyone not directly +involved in maintaining AutoGen. If you do choose to enable AutoGen +debugging, be aware that the usage page was generated without these +options, so when the build process reaches the documentation rebuild, +there will be a failure. @samp{cd} into the @file{agen5} build +directory, @samp{make} the @samp{autogen.texi} file and all will +be well thereafter. + +@item --with-regex-header +@itemx --with-header-path +@itemx --with-regex-lib +These three work together to specify how to compile with and link to a +particular POSIX regular expression library. The value for +@file{--with-regex-header=value} must be the name of the relevant header file. +The AutoGen sources will attempt to include that source with a +@code{#include <value>} C preprocessing statement. The @var{path} from the +@option{--with-header-path=path} will be added to @code{CPPFLAGS} as +@option{-Ipath}. The @var{lib-specs} from @option{--with-regex-lib=lib-specs} +will be added to @code{LDFLAGS} without any adornment. +@end table + +@c === SECTION MARKER + +@page +@node AutoGen CGI +@section AutoGen as a CGI server + +AutoGen is now capable of acting as a CGI forms server. +It behaves as a CGI server if the definitions input is from stdin +and the environment variable @env{REQUEST_METHOD} is defined +and set to either "GET" or "POST". If set to anything else, +AutoGen will exit with a failure message. When set to one of those +values, the CGI data will be converted to AutoGen definitions +(@pxref{Definitions File}) and the template named "@file{cgi.tpl}" +will be processed. + +This works by including the name of the real template to process +in the form data and having the "@file{cgi.tpl}" template include +that template for processing. I do this for processing the form +@url{http://autogen.sourceforge.net/conftest.html}. The "@file{cgi.tpl}" +looks approximately like this: + +@example +<? AutoGen5 Template ?> +<? +IF (not (exist? "template")) ?><? + form-error ?><? + +ELIF (=* (get "template") "/") ?><? + form-error ?><? + +ELIF (define tpl-file (string-append "cgi-tpl/" + (get "template"))) + (access? tpl-file R_OK) ?><? + INCLUDE (. tpl-file) ?><? + +ELIF (set! tpl-file (string-append tpl-file ".tpl")) + (access? tpl-file R_OK) ?><? + INCLUDE (. tpl-file) ?><? + +ELSE ?><? + form-error ?><? +ENDIF ?> +@end example + +@noindent +This forces the template to be found in the "@file{cgi-tpl/}" +directory. Note also that there is no suffix specified in the +pseudo macro (@pxref{pseudo macro}). That tells AutoGen to emit +the output to @file{stdout}. + +The output is actually spooled until it is complete so that, +in the case of an error, the output can be discarded and a proper +error message can be written in its stead. + +@strong{Please also note} that it is advisable, @emph{especially} for network +accessible machines, to configure AutoGen (@pxref{configuring}) with +shell processing disabled (@option{--disable-shell}). That will make it +impossible for any referenced template to hand data to a subshell for +interpretation. + +@c === SECTION MARKER + +@node signal names +@section Signal Names +@cindex Signal Names + +When AutoGen is first built, it tries to use @code{psignal(3)}, +@code{sys_siglist}, @code{strsigno(3)} and @code{strsignal(3)} from the +host operating system. If your system does not supply these, the +AutoGen distribution will. However, it will use the distributed mapping +and this mapping is unlikely to match what your system uses. This can +be fixed. Once you have installed autogen, the mapping can be rebuilt +on the host operating system. To do so, you must perform the +following steps: + +@enumerate +@item +Build and install AutoGen in a place where it will be found in your +search path. +@item +@file{cd $@{top_srcdir@}/compat} +@item +@samp{autogen strsignal.def} +@item +Verify the results by examining the @file{strsignal.h} file produced. +@item +Re-build and re-install AutoGen. +@end enumerate + +If you have any problems or peculiarities that cause this process to +fail on your platform, please send me copies of the header files +containing the signal names and numbers, along with the full path names +of these files. I will endeavor to fix it. There is a shell script +inside of @file{strsignal.def} that tries to hunt down the information. + +@c === SECTION MARKER + +@node installing +@section Installing AutoGen +@cindex Installing + +There are several files that get installed. The number depend +whether or not both shared and archive libraries are to be +installed. The following assumes that everything is installed +relative to @env{$prefix}. You can, of course, use +@command{configure} to place these files where you wish. + +@strong{NB}@: AutoGen does not contain any compiled-in path names. +All support directories are located via option processing, +the environment variable @env{HOME} or finding the directory where +the executable came from. + +The installed files are: + +@enumerate +@item +The executables in @file{bin} (autogen, getdefs and columns). + +@item +The AutoOpts link libraries as @file{lib/libopts.*}. + +@item +An include file in @file{include/options.h}, needed for +Automated Option Processing (see next chapter). + +@item +Several template files and a scheme script in @file{share/autogen}, needed +for Automated Option Processing (@pxref{AutoOpts}), parsing definitions +written with scheme syntax (@pxref{Dynamic Text}), the templates for +producing documentation for your program (@pxref{documentation attributes}), +autoconf test macros, and AutoFSM. + +@item +Info-style help files as @file{info/autogen.info*}. +These files document AutoGen, the option processing +library AutoOpts, and several add-on components. + +@item +The three man pages for the three executables are installed in man/man1. +@end enumerate + +This program, library and supporting files can be installed +with three commands: + +@itemize @bullet +@item +<src-dir>/configure [ <configure-options> ] +@item +make +@item +make install +@end itemize + +However, you may wish to insert @samp{make check} +before the @samp{make install} command. + +If you do perform a @samp{make check} and there are any failures, you +will find the results in @file{<module>/test/FAILURES}. Needless to say, I +would be interested in seeing the contents of those files and any +associated messages. If you choose to go on and analyze one of these +failures, you will need to invoke the test scripts individually. You +may do so by specifying the test (or list of test) in the TESTS make +variable, thus: + +@example +gmake TESTS=test-name.test check +@end example + +I specify @command{gmake} because most makes will not let you override +internal definitions with command line arguments. @command{gmake} does. + +All of the AutoGen tests are written to honor the contents of the +@t{VERBOSE} environment variable. Normally, any commentary generated +during a test run is discarded unless the @t{VERBOSE} environment +variable is set. So, to see what is happening during the test, you +might invoke the following with @i{bash} or @i{ksh}: + +@example +VERBOSE=1 gmake TESTS="for.test forcomma.test" check +@end example + +@noindent +Or equivalently with @i{csh}: + +@example +env VERBOSE=1 gmake TESTS="for.test forcomma.test" check +@end example + +@ignore +END == INSTALLATION == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@ignore +START == AUTOFSM == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@c === SECTION MARKER + +@node AutoFSM +@section Automated Finite State Machine +@cindex AutoFSM +@cindex finite state machine + +The templates to generate a finite state machine in C or C++ is included +with AutoGen. The documentation is not. The documentation is in HTML +format for @uref{http://www.gnu.org/software/autogen/autofsm.html,viewing}, +or you can @uref{http://download.sourceforge.net/autogen/,download FSM}. + +@node AutoXDR +@section Combined RPC Marshalling +@cindex RPC +@cindex rpcgen +@cindex remote procedure call +@cindex AutoXDR +@cindex XDR + +The templates and NFSv4 definitions are not included with AutoGen in any way. +The folks that designed NFSv4 noticed that much time and bandwidth was +wasted sending queries and responses when many of them could be bundled. +The protocol bundles the data, but there is no support for it in rpcgen. +That means you have to write your own code to do that. Until now. +Download this and you will have a large, complex example of how to use +@code{AutoXDR} for generating the marshaling and unmarshaling of combined +RPC calls. There is a brief example +@uref{http://www.gnu.org/software/autogen/xdr/index.html,on the web}, but +you should @uref{http://download.sourceforge.net/autogen/,download AutoXDR}. + +@c === SECTION MARKER + +@node AutoEvents +@section Automated Event Management +@cindex AutoEvents + +Large software development projects invariably have a need to manage +the distribution and display of state information and state changes. +In other words, they need to manage their software events. Generally, +each such project invents its own way of accomplishing this and then +struggles to get all of its components to play the same way. It is a +difficult process and not always completely successful. This project +helps with that. + +AutoEvents completely separates the tasks of supplying the data +needed for a particular event from the methods used to manage the +distribution and display of that event. Consequently, the programmer +writing the code no longer has to worry about that part of the +problem. Likewise the persons responsible for designing the event +management and distribution no longer have to worry about getting +programmers to write conforming code. + +This is a work in progress. See my +@uref{http://www.gnu.org/software/autogen/autoevents.html,web page} +on the subject, if you are interested. +I have some useful things put together, but it is not ready +to call a product. + +@ignore +END == AUTOFSM == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +@c +@c AUTOOPTS SECTIONS +@c +@c +@ignore +START == AUTOOPTS == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +All the features notwithstanding, some applications simply have +well-established command line interfaces. Even still, those programs +may use the configuration file parsing portion of the library. +See the ``AutoOpts Features'' and ``Configuration File Format'' sections. + +@menu +* Features:: AutoOpts Features +* Licensing:: AutoOpts Licensing +* Caveats:: Developer and User Notes +* Quick Start:: Quick Start +* Option Definitions:: Option Definitions +* AutoOpts API:: Programmatic Interface +* Multi-Threading:: Multi-Threading +* option descriptor:: Option Descriptor File +* Using AutoOpts:: Using AutoOpts +* Presetting Options:: Configuring your program +* Config File Format:: Configuration File Format +* shell options:: AutoOpts for Shell Scripts +* AutoInfo:: Automated Info Docs +* AutoMan pages:: Automated Man Pages +* getopt_long:: Using getopt(3C) +* i18n:: Internationalizing AutoOpts +* Naming Conflicts:: Naming Conflicts +* All Attribute Names:: All Attribute Names +* Option Define Names:: Option Definition Name Index +@end menu + +@c === SECTION MARKER + +@node Features +@section AutoOpts Features +@cindex features + +AutoOpts supports option processing; option state saving; and +program documentation with innumerable features. Here, we list +a few obvious ones and some important ones, but the full list is +really defined by all the attributes defined in the @ref{Option Definitions} +section. + +@enumerate +@item +POSIX-compliant short (flag) option processing. + +@item +GNU-style long options processing. Long options +are recognized without case sensitivity, and they may be abbreviated. + +@item +Environment variable initializations, @xref{environrc}. + +@item +Initialization from configuration files (aka RC or INI files), and +saving the option state back into one, @xref{loading rcfile}. + +@item +Config files may be partitioned. One config file may be used by several +programs by partitioning it with lines containing, +@code{[PROGRAM_NAME]} or @code{<?program-name>}, @xref{loading rcfile}. + +@item +Config files may contain AutoOpts directives. +@code{<?auto-options [[option-text]]>} +may be used to set @code{AutoOpts} option processing options. +Viz., @acronym{GNU} usage layout versus @code{AutoOpts} conventional layout, +and @code{misuse-usage} versus @code{no-misuse-usage}, @xref{usage attributes}. + +@item +Options may be marked as @code{@i{dis}-abled} with a disablement prefix. +Such options may default to either an enabled or a disabled state. You +may also provide an enablement prefix, too, e.g., @option{--allow-mumble} +and @option{--prevent-mumble} (@pxref{Common Attributes}). + +@item +Verify that required options are present between the minimum and maximum +number of times on the command line. Verify that conflicting options do not +appear together. Verify that options requiring the presence of other options +are, in fact, used in the presence of other options. +See @xref{Common Attributes}, and @xref{Option Conflict Attributes}. + +@item +There are several @ref{automatic options, automatically supported options}. +They will have short flags if any options have option flags and the flags +are not suppressed. The associated flag may be altered or suppressed by +specifying no value or an alternate character for @code{xxx-value;} in +the option definition file. @code{xxx} is the name of the option below: + +@table @samp +@item --help +@itemx --more-help +These are always available. @samp{--more-help} will pass the full usage +text through a pager. +@item --usage +@vindex usage-opt +This is added to the option list if @code{usage-opt} is specified. +It yields the abbreviated usage to @file{stdout}. +@item --version +This is added to the option list if @code{version = xxx;} is specified. +@item --load-opts +@itemx --save-opts +These are added to the option list if @code{homerc} is specified. Mostly. +If, @code{disable-save} is specified, then @option{--save-opts} is disabled. +@end table + +@item +Various forms of main procedures can be added to the output, +@xref{Generated main}. There are four basic forms: + +@enumerate a +@item +A program that processes the arguments and writes to standard out +portable shell commands containing the digested options. + +@item +A program that will generate portable shell commands to parse the defined +options. The expectation is that this result will be copied into a +shell script and used there. + +@item +A @code{for-each} main that will invoke a named function once for either +each non-option argument on the command line or, if there are none, +then once for each non-blank, non-comment input line read from stdin. + +@item +A main procedure of your own design. Its code can be supplied in the +option description template or by incorporating another template. +@end enumerate + +@item +There are several methods for handling option arguments. +@itemize @bullet +@item +nothing (@pxref{OPT_ARG}) option argument strings are globally available. +@item +user supplied (@pxref{Option Argument Handling}) +@item +stack option arguments (@pxref{Option Argument Handling}) +@item +integer numbers (@pxref{arg-type number}) +@item +true or false valued (@pxref{arg-type boolean}) +@item +enumerated list of names (@pxref{arg-type keyword}) +@item +an enumeration (membership) set (@pxref{arg-type set membership}) +@item +a list of name/value pairs (option @code{subopts}) +(@pxref{arg-type hierarchy}) +@item +a time duration or a specific time and date +@item +validated file name (@pxref{arg-type file name}) +@item +optional option argument (@pxref{arg-optional}) +@end itemize + +@item +The generated usage text can be emitted in either AutoOpts standard format +(maximizing the information about each option), or GNU-ish normal form. The +default form is selected by either specifying or not specifying the +@code{gnu-usage} attribute (@pxref{information attributes}). This can be +overridden by the user himself with the @env{AUTOOPTS_USAGE} environment +variable. If it exists and is set to the string @samp{gnu}, it will force +GNU-ish style format; if it is set to the string @samp{autoopts}, it will +force AutoOpts standard format; otherwise, it will have no effect. + +@item +The usage text and many other strings are stored in a single character array +(@pxref{SCM string-table-new,string table functions}). This reduces fixup +costs when loading the program or library. The downside is that if GCC +detects that any of these strings are used in a printf format, you may get the +warning, @code{embedded '\0' in format}. To eliminate the warning, you must +provide GCC with the @option{-Wno-format-contains-nul} option. + +@item +If you compile with @code{ENABLE_NLS} defined and @code{_()} defined to a +localization function (e.g. @code{gettext(3GNU)}), then the option processing +code will be localizable (@pxref{i18n}). Provided also that you do not define +the @code{no-xlate} attribute to @emph{anything} +(@pxref{presentation attributes}). + +You should also ensure that the @code{ATTRIBUTE_FORMAT_ARG()} gets +@code{#define}-ed to something useful. There is an autoconf macro +named @code{AG_COMPILE_FORMAT_ARG} in @file{ag_macros.m4} that will +set it appropriately for you. If you do not do this, then translated +formatting strings may trigger GCC compiler warnings. + +@item +Provides a callable routine to parse +a text string as if it were from one of the rc/ini/config files, +hereafter referred to as a configuration file. + +@item +By adding a @samp{doc} and @samp{arg-name} attributes to each option, +AutoGen will also be able to produce a man page and the @samp{invoking} +section of a texinfo document. + +@item +Intermingled option processing. AutoOpts options may be intermingled with +command line operands and options processed with other parsing techniques. +This is accomplished by setting the @code{allow-errors} +(@pxref{program attributes}) attribute. When processing reaches a point +where @code{optionProcess} (@pxref{libopts-optionProcess}) needs to be called +again, the current option can be set with @code{RESTART_OPT(n)} +(@pxref{RESTART_OPT}) before calling @code{optionProcess}. + +See: @xref{library attributes}. + +@item +Library suppliers can specify command line options that their +client programs will accept. They specify option definitions +that get @code{#include}-d into the client option definitions +and they specify an "anchor" option that has a callback and must be invoked. +That will give the library access to the option state for their options. + +@item +library options. An AutoOpt-ed library may export its options for use in +an AutoOpt-ed program. This is done by providing an option definition file +that client programs @code{#include} into their own option definitions. +See ``AutoOpt-ed Library for AutoOpt-ed Program'' (@pxref{lib and program}) +for more details. +@end enumerate + +@c === SECTION MARKER + +@node Licensing +@section AutoOpts Licensing +@cindex Licensing + +When AutoGen is installed, the AutoOpts project is installed with it. +AutoOpts includes various AutoGen templates and a pair of shared +libraries. These libraries may be used under the terms of version 3 +of the GNU Lesser General Public License (LGPL). + +One of these libraries (@code{libopts}) is needed by programs that are built +using AutoOpts generated code. This library is available as a separate +``tear-off'' source tarball. It is redistributable for use under either of +two licenses: The above mentioned GNU Lesser General Public License, and +the advertising-clause-free BSD license. Both of these license terms are +incorporated into appropriate COPYING files included with the @code{libopts} +source tarball. This source may be incorporated into your package with +the following simple commands: + +@example +rm -rf libopts libopts-* +gunzip -c `autoopts-config libsrc` | \ + tar -xvf - +mv libopts-*.*.* libopts +@end example + +View the @file{libopts/README} file for further integration information. + +@c === SECTION MARKER + +@page +@node Caveats +@section Developer and User Notes + +The formatting of the usage message can be controlled with the use of the +@env{AUTOOPTS_USAGE} environment variable. If it contains any of five +possible comma separated values, it will affect @file{libopts} behavior. +Any extraneous or conflicting data will cause its value to be ignored. + +If the program attributes @code{long-usage} and @code{short-usage} have been +specified (@pxref{usage attributes,Usage and Version Info Display}), these +strings are used for displaying full usage and abbreviated usage. +``Full usage'' is used when usage is requested, ``abbreviated usage'' +when a usage error is detected. If these strings are not provided, +the usage text is computed. + +The @env{AUTOOPTS_USAGE} environment variable may be set to the comma and/or +white space separated list of the following strings: + +@table @samp +@item compute +Ignore the provision of @code{long-usage} and @code{short-usage} attributes, +and compute the usage strings. This is useful, for example, if you wish to +regenerate the basic form of these strings and either tweak them or translate +them. The methods used to compute the usage text are not suitable for +translation. + +@item gnu +@cindex gnu +The format of the usage text will be displayed in GNU-normal form. +The default display for @option{--version} will be to include a note +on licensing terms. + +@item autoopts +@cindex autoopts +The format of the extended usage will be in AutoOpts' native layout. The +default version display will be one line of text with the last token the +version. @code{gnu} and @code{autoopts} conflict and may not be used +together. + +@item no-misuse-usage +@cindex no-misuse-usage +When an option error is made on the command line, the abbreviated usage text +will be suppressed. An error message and the method for getting full usage +information will be displayed. + +@item misuse-usage +@cindex misuse-usage +When an option error is made on the command line, the abbreviated usage text +will be shown. @code{misuse-usage} and @code{no-misuse-usage} conflict and +may not be used together. +@end table + +@code{misuse-usage} and @code{autoopts} are the defaults. +These defaults may be flipped to @code{no-misuse-usage} and @code{gnu} +by specifying @code{gnu-usage} and @code{no-misuse-usage} +program attributes, respectively, in the option definition file. + +@noindent +@i{Note for developers}: + +The templates used to implement AutoOpts depend heavily upon token pasting. +That mens that if you name an option, @code{debug}, for example, the generated +header will expect to be able to emit @code{#define} macros such as this: +@example +#define DESC(n) (autogenOptions.pOptDesc[INDEX_OPT_## n]) +@end example +and expect @code{DESC(DEBUG)} to expand correctly into +@code{(autogenOptions.pOptDesc[INDEX_OPT_DEBUG])}. +If @code{DEBUG} is @code{#defined} to something else, then +that something else will be in the above expansion. + +If you discover you are having strange problems like this, +you may wish to use some variation of the @code{guard-option-names} +@xref{program attributes}. + +@c === SECTION MARKER + +@page +@node Quick Start +@section Quick Start +@cindex example, simple AutoOpts + +Since it is generally easier to start with a simple example than it is +to look at the options that AutoGen uses itself, here is a very simple +AutoOpts example. You can copy this example out of the Info file and +into a source file to try it. You can then embellish it into what you +really need. For more extensive examples, you can also examine the help +output and option definitions for the commands @command{columns}, +@command{getdefs} and @command{autogen} itself. + +If you are looking for a more extensive example, +you may search the autogen sources for files named @file{*opts.def}. +@command{xml2ag} is ridiculous and @command{autogen} is very lengthy, +but @command{columns} and @command{getdefs} are not too difficult. +The @command{sharutils} sources are fairly reasonable, too. + +@menu +* quick ao problem:: Example option requirements +* quick ao def:: Example option definitions +* quick ao build:: Build the example options +* quick ao help:: Example option help text +* quick ao usage:: Using the example options +* quick ao docs:: Example option documentation +@end menu + +@node quick ao problem +@subsection Example option requirements + +For our simple example, assume you have a program named @command{check} +that takes two options: + +@enumerate +@item +A list of directories to check over for whatever it is @command{check} does. +You want this option available as a POSIX-style flag option +and a GNU long option. You want to allow as many of these +as the user wishes. +@item +An option to show or not show the definition tree being used. +Only one occurrence is to be allowed, specifying one or the other. +@end enumerate + +@node quick ao def +@subsection Example option definitions + +@noindent +First, specify your program attributes and its options to AutoOpts, +as with the following example. + +@example +@ignore +END == AUTOOPTS == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@ignore +START == AUTOOPTS-MAIN == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@node quick ao usage +@subsection Using the example options + +Normally, however, you would not use the @code{main} clause. Instead, +the file would be named something like @file{checkopt.def}, you would +compile @file{checkopt.c} the usual way, and link the object with the rest +of your program. + +The options are processed by calling @code{optionProcess} +(@pxref{libopts-optionProcess}): + +@example +main( int argc, char** argv ) +@{ + @{ + int optct = optionProcess( &checkOptions, argc, argv ); + argc -= optct; + argv += optct; + @} +@end example + +The options are tested and used as in the following fragment. +@code{ENABLED_OPT} is used instead of @code{HAVE_OPT} for the +@option{--show-defs} option because it is an enabled/disabled option type: + +@example + if ( ENABLED_OPT( SHOW_DEFS ) + && HAVE_OPT( CHECK_DIRS )) @{ + int dirct = STACKCT_OPT( CHECK_DIRS ); + char** dirs = STACKLST_OPT( CHECK_DIRS ); + while (dirct-- > 0) @{ + char* dir = *dirs++; + ... +@end example + +@node quick ao docs +@subsection Example option documentation + +The @code{doc} clauses are used in the flag stanzas for man pages and texinfo +invoking documentation. With the definition file described above, the two +following commands will produce the two documentation files @file{check.1} and +@file{invoke-check.texi}. The latter file will be generated as a chapter, +rather than a section or subsection. + +@example +autogen -Tagman-cmd check.def +autogen -DLEVEL=chapter -Tagtexi-cmd -binvoke-check.texi check.def +@end example + +@noindent +The result of which is left as an exercise for the reader. + +A lot of magic happens to make this happen. +The rest of this chapter will describe the myriad of option attributes +supported by AutoOpts. However, keep in mind that, in general, you won't +need much more than what was described in this "quick start" section. + +@node Option Definitions +@section Option Definitions +@cindex Option Definitions + +AutoOpts uses an AutoGen definitions file for the definitions of the +program options and overall configuration attributes. +The complete list of program and option attributes is quite extensive, +so if you are reading to understand how to use AutoOpts, I recommend +reading the "Quick Start" section (@pxref{Quick Start}) and paying +attention to the following: + +@enumerate +@item +@code{prog-name}, @code{prog-title}, and @code{argument}, program +attributes, @xref{program attributes}. +@item +@code{name} and @code{descrip} option attributes, @xref{Required Attributes}. +@item +@code{value} (flag character) and @code{min} (occurrence counts) +option attributes, @xref{Common Attributes}. +@item +@code{arg-type} from the option argument specification section, +@xref{Option Arguments}. +@item +Read the overall how to, @xref{Using AutoOpts}. +@item +Highly recommended, but not required, are the several "man" and +"info" documentation attributes, @xref{documentation attributes}. +@end enumerate + +Keep in mind that the majority are rarely used and can be safely +ignored. However, when you have special option processing requirements, +the flexibility is there. + +@menu +* program attributes:: Program Description Attributes +* library attributes:: Options for Library Code +* information attributes:: Program Information Attributes +* Generated main:: Generating main procedures +* option attributes:: Option Attributes +* Option Arguments:: Option Argument Specification +* Option Argument Handling:: Option Argument Handling +* Internationalizing Options:: Internationalizing Options +* documentation attributes:: Man and Info doc Attributes +* automatic options:: Automatically Supported Options +* standard options:: Library of Standard Options +@end menu + +@node program attributes +@subsection Program Description Attributes +@cindex program attributes + +The following global definitions are used to define attributes of the entire +program. These generally alter the configuration or global behavior of the +AutoOpts option parser. The first two are required of every program. The +third is required if there are to be any left over arguments (operands) +after option processing. The rest have been grouped below. Except as noted, +there may be only one copy of each of these definitions: + +@table @samp + +@item prog-name +@vindex prog-name +This attribute is required. Variable names derived from this name +are derived using @code{string->c_name!} (@pxref{SCM string->c-name!}). + +@item prog-title +@vindex prog-title +This attribute is required and may be any descriptive text. + +@item argument +@vindex argument +This attribute is required if your program uses operand arguments. +It specifies the syntax of the arguments that @strong{follow} the options. +It may not be empty, but if it is not supplied, then option processing +must consume all the arguments. If it is supplied and starts with an +open bracket (@code{[}), then there is no requirement on the presence or +absence of command line arguments following the options. Lastly, if it +is supplied and does not start with an open bracket, then option +processing must @strong{not} consume all of the command line arguments. + +@item config-header +@vindex config-header +If your build has a configuration header, it must be included before +anything else. Specifying the configuration header file name with this +attribute will cause that to happen. +@end table + +@menu +* usage attributes:: Usage and Version Info Display +* config attributes:: Program Configuration +* programming attributes:: Programming Details +* presentation attributes:: User Presentation Attributes +@end menu + +@c +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +@c +@node usage attributes +@subsubsection Usage and Version Info Display + +These will affect the way usage is seen and whether or not version +information gets displayed. + +@table @samp +@item full-usage +@vindex full-usage +If this attribute is provided, it may specify the full length +usage text, or a variable name assignable to a @code{char const *} pointer, +or it may be empty. The meanings are determined by the length. +@itemize @bullet +@item +If not provided, the text will be computed as normal. +@item +If the length is zero, then the usage text will be derived from +the current settings and inserted as text into the generated .c file. +@item +If the length is 1 to 32 bytes, then it is presumed to be a variable +name that either points to or is an array of const chars. +@item +If it is longer than that, it is presumed to be the help text itself. +This text will be inserted into the generated .c file. +@end itemize + +This string should be readily translatable. Provision will be made +to translate it if this is provided, if the source code is compiled with +@code{ENABLE_NLS} defined, and @code{no-xlate} has not been set to the +value @emph{anything}. The untranslated text will be handed to +@code{dgettext("libopts", @i{txt})} and then @code{gettext(@i{txt})} +for translation, one paragraph at a time. + +To facilitate the creation and maintenance of this text, you can +force the string to be ignored and recomputed by specifying +@example +AUTOOPTS_USAGE=compute +@end example +@noindent +in the environment and requesting help or usage information. +See @xref{Caveats, Developer and User Notes}. + +@item short-usage +@vindex short-usage +If this attribute is provided, it is used to specify an abbreviated +version of the usage text. This text is constructed in the same way +as the @code{full-usage}, described above. + +@item gnu-usage +@vindex gnu-usage +AutoOpts normaly displays usage text in a format that provides more +information than the standard GNU layout, but that also means it is +not the standard GNU layout. This attribute changes the default to +GNU layout, with the @env{AUTOOPTS_USAGE} environment variable used +to request @code{autoopts} layout. +See @xref{Caveats, Developer and User Notes}. + +@item usage-opt +@vindex usage-opt +I apologize for too many confusing usages of usage. +This attribute specifies that @option{--usage} and/or @option{-u} be +supported. The help (usage) text displayed will be abbreviated +when compared to the default help text. + +@item no-misuse-usage +@vindex no-misuse-usage +When there is a command line syntax error, by default AutoOpts will +display the abbreviated usage text, rather than just a one line +``you goofed it, ask for usage'' message. You can change the default +behavior for your program by supplying this attribute. The user may +override this choice, again, with the @env{AUTOOPTS_USAGE} environment +variable. See @xref{Caveats, Developer and User Notes}. + +@item prog-group +@vindex prog-group +The version text in the @file{getopt.tpl} template will include this +text in parentheses after the program name, when this attribute is specified. +For example: +@example +mumble (stumble) 1.0 +@end example +@noindent +says that the @samp{mumble} program is version 1.0 and is part of the +@samp{stumble} group of programs. + +@item usage +@vindex usage +If your program has some cleanup work that must be done before exiting +on usage mode issues, or if you have to customize the usage message in +some way, specify this procedure and it will be called instead of the +default @code{optionUsage()} function. For example, if a program is +using the curses library and needs to invoke the usage display, then +you must arrange to call @code{endwin()} before invoking the library +function @code{optionUsage()}. This can be handled by specifying your +own usage function, thus: +@example +void +my_usage(tOptions * opts, int ex) +@{ + if (curses_window_active) + endwin(); + optionUsage(opts, ex); +@} +@end example + +@item version +@vindex version +Specifies the program version and activates the VERSION option, +@xref{automatic options}. +@end table + +@c +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +@c +@node config attributes +@subsubsection Program Configuration + +Programs may be ``pre-configured'' before normal command line options +are processed (See @pxref{Immediate Action, Immediate Action Attributes}). +How configuration files and environment variables are handled get +specified with these attributes. + +@table @samp +@item disable-load +@itemx disable-save +@vindex disable-load +@vindex disable-save +Indicates that the command line usage of @option{--load-opts} and/or +@option{--save-opts} are disallowed. + +@item environrc +@vindex environrc +Indicates looking in the environment for values of variables named, +@env{PROGRAM_OPTNAME} or @env{PROGRAM}, where @env{PROGRAM} is the +upper cased @var{C-name} of the program and @samp{OPTNAME} is the +upper cased @var{C-name} of a specific option. The contents of +the @env{PROGRAM} variable, if found, are tokenized and processed. +The contents of @env{PROGRAM_OPTNAME} environment variables are taken +as the option argument to the option nameed @option{--optname}. + +@item homerc +@vindex homerc +Specifies that option settings may be loaded from and stored into +configuration files. Each instance of this attribute is either a directory +or a file using a specific path, a path based on an environment variable or +a path relative to installation directories. The method used depends on +the name. If the one entry is empty, it enables the loading and storing of +settings, but no specific files are searched for. Otherwise, a series of +configuration files are hunted down and, if found, loaded. + +If the first character of the @samp{homerc} value is not the dollar +character (@code{$}), then it is presumed to be a path name based on the +current directory. Otherwise, the method depends on the second character: + +@table @code +@item $ +The path is relative to the directory where the executable was found. +@item @@ +The path is relative to the package data directory, e.g. +@file{/usr/local/share/autogen}. +@item [a-zA-Z] +The path is derived from the named environment variable. +@end table + +Use as many as you like. The presence of this attribute +activates the @option{--save-opts} and @option{--load-opts} options. +However, saving into a file may be disabled with the @samp{disable-save}. +@xref{loading rcfile}. +See the @code{optionMakePath(3AGEN)} man page for excruciating details. + +@item rcfile +@vindex rcfile +Specifies the configuration file name. This is only useful if you +have provided at least one @code{homerc} attribute. +@example +default: .<prog-name>rc +@end example + +@item vendor-opt +@vindex vendor-opt +This option implements the @option{-W} vendor option command line option. + +For POSIX specified utilities, the options are constrained to the options +that are specified by POSIX. Extensions should be handled with @option{-W} +command line options, the short flag form. Long option name processing +must be disabled. In fact, the @code{long-opts} attribute must not be +provided, and some options must be specified without flag values. + +The @option{-W long-name} is processed by looking up the long option +name that follows it. It cannot be a short flag because that would +conflict with the POSIX flag name space. It will be processed as if +long options were accepted and @option{--long-name} were found on the +command line. +@end table + +@c +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +@c +@node programming attributes +@subsubsection Programming Details + +These attributes affect some of the ways that the option data are +used and made available to the program. + +@table @samp +@item config-header +@vindex config-header +The contents of this attribute should be just the name of the configuration +file. A "#include" naming this file will be inserted at the top of the +generated header. + +@item exit-name +@itemx exit-desc +@vindex exit-name +@vindex exit-desc +These values should be defined as indexed values, thus: +@example +exit-name[0] = success; +exit-desc[0] = 'Successful program execution.'; +exit-name[1] = failure; +exit-desc[1] = 'The operation failed or command syntax was not valid.'; +@end example +By default, all programs have these effectively defined for them. +They may be overridden by explicitly defining any or all of these values. +Additional names and descriptions may be defined. +They will cause an enumeration to be emitted, like this one +for @command{getdefs}: +@example +typedef enum @{ + GETDEFS_EXIT_SUCCESS = 0, + GETDEFS_EXIT_FAILURE = 1 +@} getdefs_exit_code_t; +@end example +@noindent +which will be augmented by any @code{exit-name} definitions beyond @samp{1}. + +Some of the generated code will exit non-zero if there is an allocation error. +This exit will always be code @samp{1}, unless there is an exit named @samp{no_mem} +or @samp{nomem}. In that case, that value will be used. Additionally, if +there is such a value, and if @code{die-code} is specified, then a function +@code{nomem_err(size_t len, char const * what)} will be emitted as an inline +function for reporting out-of-memory conditions. + +@item usage-message +@vindex usage-message +This attribute will cause two procedures to be added to the code file: +@code{usage_message()} and @code{vusage_message()}, with any applicable prefix +(see @code{prefix}, below). They are declared in the +generated header, thus: +@example +noreturn extern void vusage_message(char const * fmt, va_list ap); +noreturn extern void usage_message(char const * fmt, ...); +@end example +@noindent +These functions print the message to @file{stderr} and invoke the usage +function with the exit code set to @code{1} (@code{EXIT_FAILURE}). + +@item die-code +@vindex die-code +This tells AutoOpts templates to emit code for @code{vdie()}, @code{die()}, +@code{fserr()}, and, possibly the @code{nomem_err()} functions. The latter is +emitted if an exit name of @samp{no-mem} or @samp{nomem} is specified. If the +@code{die-code} is assigned a text value, then that code will be inserted in +the @code{vdie} function immediately before it prints the death rattle +message. + +The profiles for these functions are: +@example +noreturn extern void vdie( int exit_code, char const * fmt, va_list); +noreturn extern void die( int exit_code, char const * fmt, ...); +noreturn extern void fserr(int exit_code, char const * op, char const * fname); +noreturn static inline void +nomem_err(size_t sz, char const * what) @{...@} +@end example + +@item export +@vindex export +This string is inserted into the .h interface file. Generally used for +global variables or @code{#include} directives required by +@code{flag-code} text and shared with other program text. +Do not specify your configuration header (@file{config.h}) in this +attribute or the @code{include} attribute. Instead, use +@code{config-header}, above. + +@item guard-option-names +@vindex guard-option-names +AutoOpts generates macros that presume that there are no @command{cpp} macros +with the same name as the option name. For example, if you have an option +named, @option{--debug}, then you must not use @code{#ifdef DEBUG} in your +code. If you specify this attribute, every option name will be guarded. If +the name is @code{#define}-d, then a warning will be issued and the name +undefined. If you do not specify this and there is a conflict, you will get +strange error messages. + +This attribute may be set to any of four recognized states: + +@itemize @bullet +@item +Not defined. AutoOpts will behave as described above. + +@item +Defined, but set to the empty string. Text will be emitted into the header +to undefine (@code{#undef}) any conflicting preprocessor macros. The code +will include compiler warnings (via @code{#warning}). Some compilers are +not ANSI-C-99 compliant yet and will error out on those warnings. You may +compile with @option{-DNO_OPTION_NAME_WARNINGS} to silence or mostly silence +them. + +@item +Defined and set to the string, @code{no-warning}. All of the needed +@code{#undef}s will be emitted, without any conflict checking @code{#warning} +directives emitted. + +@item +Defined and set to the string, @code{full-enum}. The option manipulation +preprocessor macros will not token paste the option names to the index +enumeration prefix. e.g. you will need to use @code{HAVE_OPT(INDEX_OPT_DEBUG)} +instead of @code{HAVE_OPT(DEBUG)}. +@end itemize + +@item include +@vindex include +This string is inserted into the .c file. Generally used for global +variables required only by @code{flag-code} program text. + +@item no-libopts +@vindex no-libopts +If you are going to handle your option processing with the @file{getopt.tpl} +template instead of using libopts, then specify this attribute. It will +suppress mention of @option{--more-help} in the generated documentation. +(@code{getopt_long} does not support @option{--more-help}.) + +@item prefix +@vindex prefix +This value is inserted into @strong{all} global names. This will +disambiguate them if more than one set of options are to be compiled +into a single program. +@end table + +@c +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +@c +@node presentation attributes +@subsubsection User Presentation Attributes + +Attributes that affect the user's experience. + +@table @samp +@item allow-errors +@vindex allow-errors +The presence of this attribute indicates ignoring any command line +option errors. This may also be turned on and off by invoking the +macros @code{ERRSKIP_OPTERR} and @code{ERRSTOP_OPTERR} from the +generated interface file. + +@item long-opts +@vindex long-opts +@cindex named option mode +Presence indicates GNU-standard long option processing. Partial name +matches are accepted, if they are at least two characters long and the +partial match is unique. The matching is not case sensitive, and the +underscore, hyphen and carat characters are all equivalent (they match). + +If any options do not have an option value (flag character) specified, +and least one does specify such a value, then you must specify +@code{long-opts}. If none of your options specify an option value +(flag character) and you do not specify @code{long-opts}, then command +line arguments are processed in "named option mode". This means that: + +@itemize @bullet +@item +Every command line argument must be a long option. +@item +The flag markers @option{-} and @option{--} are completely optional. +@item +The @code{argument} program attribute is disallowed. +@item +One of the options may be specified as the default +(as long as it has a required option argument). +@end itemize + +@item no-xlate +@vindex no-xlate +Modifies when or whether option names get translated. If provided, +it must be assigned one of these values: +@table @samp +@item opt-cfg +to suppress option name translation for configuration file and and environment +variable processing. +@item opt +to suppress option name translation completely. The usage text will +always be translated if @code{ENABLE_NLS} is defined and you have +translations for that text. +@item anything +Specifies disabling all internationalization support for option code, completely. +@end table +See also the various @code{XLAT} interface entries in the +AutoOpts Programmatic Interface section (@pxref{AutoOpts API}). + +@item reorder-args +@vindex reorder-args +Normally, POSIX compliant commands do not allow for options to be interleaved +with operands. If this is necessary for historical reasons, there are two +approaches available: +@itemize @bullet +@item +Allow @code{optionProcess} to return the index of the operand like it normally +does and process the operand(s). When an operand is encountered that starts +with a hyphen, then set the AutoOpts current index with the @code{RESTART_OPT} +macro (see @pxref{RESTART_OPT}), and re-invoke @code{optionProcess}. This +will also allow you to process the operands in context. + +@item +Specify this attribute. AutoOpts will re-order the command arguments +so that the operands appear (in the original order) at the end of +the argument list. Differing configuration state is not possible +to detect after all options have been processed. +@end itemize + +@item resettable +@vindex resettable +Specifies that the @option{--reset-option} command line option is to be +supported. This makes it possible to suppress any setting that might be +found in a configuration file or environment variable. +@end table + +@node library attributes +@subsection Options for Library Code +@cindex library attributes + +Some libraries provide their own code for processing command line +options, and this may be used by programs that utilize AutoOpts. +You may also wish to write a library that gets configured with AutoOpts +options and config files. Such a library may either supply its own +configury routine and process its own options, or it may export its +option descriptions to programs that also use AutoOpts. This section +will describe how to do all of these different things. + +@menu +* lib and program:: AutoOpt-ed Library for AutoOpt-ed Program +* lib called:: AutoOpt-ed Library for Regular Program +* prog calls lib:: AutoOpt-ed Program Calls Regular Library +@end menu + +@node lib and program +@subsubsection AutoOpt-ed Library for AutoOpt-ed Program + +The library source code must provide an option definition file that consists +of only the attribute @code{library} +@vindex library +and @code{flag} entries. The @code{library} attribute does not need any +associated value, so it will generally appeary by itself on a line folowed +by a semi-colon. The first @code{flag} entry must contain the following +attributes: + +@table @samp +@item name +This name is used in the construction of a global pointer of type +@code{tOptDesc const*}. It is always required. +@item documentation +@vindex documentation +It tells @code{AutoOpts} that this option serves no normal purpose. +It will be used to add usage clarity and to locate option descriptors +in the library code. +@item descrip +This is a string that is inserted in the extended usage display +before the options specific to the current library. It is always required. +@item lib-name +@vindex lib-name +This should match the name of the library. This string is also used in +the construction of the option descriptor pointer name. In the end, it +looks like this: +@example +extern tOptDesc const* <<lib-name>>_<<name>>_optDesc_p; +@end example +@noindent +and is used in the macros generated for the library's @file{.h} file. +@end table + +In order to compile this @code{AutoOpts} using library, you must create a +special header that is not used by the client program. This is accomplished +by creating an option definition file that contains essentially exactly the +following: + +@example +AutoGen definitions options; +prog-name = does-not-matter; // but is always required +prog-title = 'also does not matter'; // also required +config-header = 'config.h'; // optional, but common +library; +#include library-options-only.def +@end example + +@noindent +and nothing else. AutoGen will produce only the @file{.h} file. +You may now compile your library, referencing just this @file{.h} file. +The macros it creates will utilize a global variable that will be defined +by the @code{AutoOpts}-using client program. That program will need to +have the following @code{#include} in @i{its} option definition file: + +@example +#include library-options-only.def +@end example + +@noindent +All the right things will magically happen so that the global variables +named @var{<<lib-name>>_<<name>>_optDesc_p} are initialized correctly. +For an example, please see the @code{AutoOpts} test script: +@file{autoopts/test/library.test}. + +@node lib called +@subsubsection AutoOpt-ed Library for Regular Program + +In this case, your library must provide an option processing function +to a calling program. This is accomplished by setting the @code{allow-errors} +global option attribute. Each time your option handling function is called, +you must determine where your scan is to resume and tell the AutoOpts library +by invoking: + +@example +RESTART_OPT(next_arg_index); +@end example + +@noindent +and then invoke @code{not_opt_index = optionProcess(...)}. +The @code{not_opt_index} value can be used to set @code{optind}, +if that is the global being used to scan the program argument array. + +In this method, do @strong{NOT} utilize the global @code{library} attribute. +Your library must specify its options as if it were a complete program. +You may choose to specify an alternate @code{usage()} function so that +usage for other parts of the option interface may be displayed as well. +See ``Program Information Attributes'' (@pxref{information attributes}). + +At the moment, there is no method for calling @code{optionUsage()} telling +it to produce just the information about the options and not the program +as a whole. Some later revision after somebody asks. + +@node prog calls lib +@subsubsection AutoOpt-ed Program Calls Regular Library + +As with providing an @code{AutoOpt}-ed library to a non-@code{AutoOpt}-ed +program, you must write the option description file as if you were writing +all the options for the program, but you should specify the +@code{allow-errors} global option attribute and you will likely want an +alternate @code{usage()} function (see ``Program Information Attributes'' +@pxref{information attributes}). In this case, though, when +@code{optionProcess()} returns, you need to test to see if there might be +library options. If there might be, then call the library's exported +routine for handling command line options, set the next-option-to-process +with the @code{RESTART_OPT()} macro, and recall @code{optionProcess()}. +Repeat until done. + +@node information attributes +@subsection Program Information Attributes +@cindex information attributes + +These attributes are used to define how and what information is displayed +to the user of the program. + +@table @samp +@item copyright +@vindex copyright +The @code{copyright} is a structured value containing three to five +values. If @code{copyright} is used, then the first three are required. + +@enumerate +@item +@vindex date +@file{date} - the list of applicable dates for the copyright. +@item +@vindex owner +@file{owner} - the name of the copyright holder. +@item +@vindex type +@file{type} - specifies the type of distribution license. +AutoOpts/AutoGen supports the text of the GNU Public License (@file{gpl}), +the GNU Lesser General Public License with Library extensions +(@file{lgpl}), the Modified Free BSD license (@file{mbsd}) and a few others. +Other licenses may be specified, but you must provide your own license file. +The list of license files provided by AutoOpts may be seen by typing: +@example +ls $(autoopts-config pkgdatadir)/*.lic +@end example +@item +@vindex text +@file{text} - the text of the copyright notice. This must be provided +if @file{type} is set to @file{NOTE}. +@item +@vindex author +@file{author} - in case the author name is to appear in the documentation +and is different from the copyright owner. +@item +@vindex eaddr +@file{eaddr} - email address for receiving praises and complaints. +Typically that of the author or copyright holder. +@end enumerate +@* +An example of this might be: +@example +copyright = @{ + date = "1992-2015"; + owner = "Bruce Korb"; + eaddr = 'bkorb@@gnu.org'; + type = GPL; +@}; +@end example + +@item detail +@vindex detail +This string is added to the usage output when the HELP option is +selected. + +@item explain +@vindex explain +Gives additional information whenever the usage routine is invoked. + +@item package +@vindex package +The name of the package the program belongs to. This will appear +parenthetically after the program name in the version and usage output, +e.g.: @code{autogen @i{(GNU autogen)} - The Automated Program Generator}. + +@item preserve-case +@vindex preserve-case +This attribute will not change anything except appearance. Normally, the +option names are all documented in lower case. However, if you specify this +attribute, then they will display in the case used in their specification. +Command line options will still be matched without case sensitivity. +This is useful for specifying option names in camel-case. + +@item prog-desc @strong{and} +@itemx opts-ptr +@vindex prog-desc +@vindex opts-ptr +These define global pointer variables that point to the program +descriptor and the first option descriptor for a library option. This +is intended for use by certain libraries that need command line and/or +initialization file option processing. These definitions have no effect +on the option template output, but are used for creating a library +interface file. Normally, the first "option" for a library will be a +documentation option that cannot be specified on the command line, but +is marked as @code{settable}. The library client program will invoke the +@code{SET_OPTION} macro which will invoke a handler function that will +finally set these global variables. + +@item usage +@vindex usage +Optionally names the usage procedure, if the library routine +@code{optionUsage()} does not work for you. If you specify +@code{my_usage} as the value of this attribute, for example, you will +use a procedure by that name for displaying usage. Of course, you will +need to provide that procedure and it must conform to this profile: +@example +void @i{my_usage}( tOptions* pOptions, int exitCode ) +@end example + +@item gnu-usage +@vindex gnu-usage +Normally, the default format produced by the @code{optionUsage} procedure +is @i{AutoOpts Standard}. By specifying this attribute, the default format +will be @i{GNU-ish style}. Either default may be overridden by the user with +the @env{AUTOOPTS_USAGE} environment variable. If it is set to @code{gnu} +or @code{autoopts}, it will alter the style appropriately. This attribute +will conflict with the @code{usage} attribute. + +@item reorder-args +@vindex reorder-args +Some applications traditionally require that the command operands be +intermixed with the command options. In order to handle that, the arguments +must be reordered. If you are writing such an application, specify this +global option. All of the options (and any associated option arguments) +will be brought to the beginning of the argument list. New applications +should not use this feature, if at all possible. This feature is +@i{disabled} if @env{POSIXLY_CORRECT} is defined in the environment. +@end table + +@node Generated main +@subsection Generating main procedures +@cindex main procedure + +When AutoOpts generates the code to parse the command line options, it has +the ability to produce any of several types of @code{main()} procedures. +This is done by specifying a global structured value for +@vindex main +@code{main}. The values that it contains are dependent on the value set for +the one value it must have: @code{main-type}. + +@vindex main-type +The recognized values for @code{main-type} are @code{guile}, +@code{shell-process}, @code{shell-parser}, @code{main}, @code{include}, +@code{invoke}, and @code{for-each}. + +@menu +* main guile:: guile: main and inner_main procedures +* main shell-process:: shell-process: emit Bourne shell results +* main shell-parser:: shell-parser: emit Bourne shell script +* main main:: main: user supplied main procedure +* main include:: include: code emitted from included template +* main invoke:: invoke: code emitted from AutoGen macro + +The @code{for-each} main procedure has a number of attributes that +must be specified: + +* main for-each:: for-each: perform function on each operand +* main-for-each-proc:: procedure to handle each argument +* main-for-each-type:: handler procedure type +* main-for-each-code:: code for handler procedure +* main-for-each-opts:: for-each main procedure options +@end menu + +@node main guile +@subsubsection guile: main and inner_main procedures + +When the @code{main-type} is specified to be @code{guile}, +a @code{main()} procedure is generated that calls @code{gh_enter()}, providing +it with a generated @code{inner_main()} to invoke. If you must perform +certain tasks before calling @code{gh_enter()}, you may specify such code +in the value for the +@vindex before-guile-boot +@code{before-guile-boot} attribute. + +The @code{inner_main()} procedure itself will process the command line +arguments (by calling @code{optionProcess()}, +@pxref{libopts-optionProcess}), and then either invoke the code +specified with the +@vindex guile-main +@code{guile-main} attribute, or else export the parsed options to Guile +symbols and invoke the @code{scm_shell()} function from the Guile library. +This latter will render the program nearly identical to the stock +@code{guile(1)} program. + +@node main shell-process +@subsubsection shell-process: emit Bourne shell results + +This will produce a @code{main()} procedure that parses the command line +options and emits to @file{stdout} Bourne shell commands that puts the +option state into environment variables. This can be used within a +shell script as follows: + +@example +unset OPTION_CT +eval "`opt_parser \"$@@\"`" +test $@{OPTION_CT@} -gt 0 && shift $@{OPTION_CT@} +@end example + +If the option parsing code detects an error or a request for usage or version, +it will emit a command to exit with an appropriate exit code to @file{stdout}. +This form of @code{main} will cause all messages, including requested usage +and version information, to be emitted to @file{stderr}. Otherwise, a numeric +value for @code{OPTION_CT} is guaranteed to be emitted, along with assignments +for all the options parsed, something along the lines of the following will be +written to @file{stdout} for evaluation: + +@example +OPTION_CT=4 +export OPTION_CT +MYPROG_SECOND='first' +export MYPROG_SECOND +MYPROG_ANOTHER=1 # 0x1 +export MYPROG_ANOTHER +@end example + +@noindent +If the arguments are to be reordered, however, then the resulting set +of operands will be emitted and @env{OPTION_CT} will be set to zero. +For example, the following would be appended to the above: + +@example +set -- 'operand1' 'operand2' 'operand3' +OPTION_CT=0 +@end example + +@noindent +@env{OPTION_CT} is set to zero since it is not necessary to shift +off any options. + +@node main shell-parser +@subsubsection shell-parser: emit Bourne shell script + +This will produce a @code{main()} procedure that emits a shell script +that will parse the command line options. That script can be emitted +to @file{stdout} or inserted or substituted into a pre-existing shell +script file. Improbable markers are used to identify previously inserted +parsing text: + +@example +# # # # # # # # # # -- do not modify this marker -- +@end example + +@noindent +The program is also pretty insistent upon starting its parsing script +on the second line. + +@node main main +@subsubsection main: user supplied main procedure + +You must supply a value for the @code{main-text} attribute. +You may also supply a value for +@vindex option-code +@code{option-code}. If you do, then the @code{optionProcess} invocation +will not be emitted into the code. AutoOpts will wrap the @code{main-text} +inside of: + +@example +int +main( int argc, char** argv ) +@{ + int res = <<success-exit-code>>; + @{ // replaced by option-code, if that exists + int ct = optionProcess( &<<prog-name>>Options, argc, argv); + argc -= ct; + argv += ct; + @} +<<main-text>> + return res; +@} +@end example + +@noindent +so you can most conveniently set the value with a @code{here string} +(@pxref{here-string}): + +@example +code = <<- _EndOfMainProc_ + <<your text goes here>> + _EndOfMainProc_; +@end example + +@node main include +@subsubsection include: code emitted from included template + +You must write a template to produce your main procedure. +You specify the name of the template with the @code{tpl} attribute +and it will be incorporated at the point where AutoOpts is ready +to emit the @code{main()} procedure. + +This can be very useful if, in your working environment, you have +many programs with highly similar @code{main()} procedures. All you need +to do is parameterize the variations and specify which variant is needed +within the @code{main} AutoOpts specification. Since you are coding +the template for this, the attributes needed for this variation would +be dictated by your template. + +Here is an example of an @code{include} variation: + +@example +main = @{ + main-type = include; + tpl = "main-template.tpl"; +@}; +@end example + +@node main invoke +@subsubsection invoke: code emitted from AutoGen macro + +You must write a template to produce your main procedure. That template +must contain a definition for the function specified with the @code{func} +attribute to this @code{main()} procedure specification. This +variation operates in much the same way as @code{include} +(@pxref{main include}) method. + +@node main for-each +@subsubsection for-each: perform function on each operand + +This produces a main procedure that invokes a procedure once for each operand +on the command line (non-option arguments), @strong{OR} once for each +non-blank, non-comment @code{stdin} input line. Leading and trailing white +space is trimmed from the input line and comment lines are lines that are +empty or begin with a comment character, defaulting to a hash ('#') character. + +@strong{NB}: +The @code{argument} program attribute (@pxref{program attributes}) +must begin with the @code{[} character, to indicate that there are +command operands, but that they are optional. + +@noindent +For an example of the produced main procedure, in the @file{autoopts/test} +build directory, type the following command and look at @file{main.c}: +@example +make verbose TESTS=main.test +@end example + +@node main-for-each-proc +@unnumberedsubsubsec procedure to handle each argument + +@vindex handler-proc +The @code{handler-proc} attribute is required. It is used to name the +procedure to call. That procedure is presumed to be external, but if +you provide the code for it, then the procedure is emitted as a static +procedure in the generated code. + +This procedure should return 0 on success, a cumulative error code on warning +and exit without returning on an unrecoverable error. As the cumulative +warning codes are @i{or}-ed together, the codes should be some sort of bit +mask in order to be ultimately decipherable (if you need to do that). + +If the called procedure needs to cause a fail-exit, it is expected to call +@code{exit(3)} directly. If you want to cause a warning exit code, then this +handler function should return a non-zero status. That value will be +@strong{OR}-ed into a result integer for computing the final exit code. E.g., +here is part of the emitted code: + +@example + int res = 0; + if (argc > 0) @{ + do @{ + res |= @var{my_handler}( *(argv++) ); + @} while (--argc > 0); + @} else @{ ... +@end example + +@node main-for-each-type +@unnumberedsubsubsec handler procedure type + +@vindex handler-type +If you do not supply the @code{handler-type} attribute, your handler +procedure must be the default type. The profile of the procedure must be: + +@example +int @var{my_handler}(char const * pz_entry); +@end example + +@noindent +However, if you do supply this attribute, you may set the value to any of +four alternate flavors: + +@table @samp +@item name-of-file +This is essentially the same as the default handler type, except that before +your procedure is invoked, the generated code has verified that the string +names an existing file. The profile is unchanged. + +@item file-X +Before calling your procedure, the file is f-opened according to the @code{X}, +where @code{X} may be any of the legal modes for @code{fopen(3C)}. In this +case, the profile for your procedure must be: + +@example +int @var{my_handler}(char const * pz_fname, FILE * entry_fp); +@end example + +@noindent +When processing inputs as file pointer stream files, there are several +ways of treating standard input. It may be an ordinary input file, +or it may contain a list of files to operate on. + +If the file handler type is more specifically set to @samp{file-r} and +a command line operand consists of a single hyphen, then @var{my_handler} +will be called with @code{entry_fp} set to @code{stdin} and the @code{pz_fname} +set to the translatable string, "standard input". Consequently, +in this case, if the input list is being read from @code{stdin}, a line +containing a hyphen by itself will be ignored. + +@item stdin-input +This attribute specifies that standard input is a data input file. +By default, @code{for-each} main procedures will read standard input for +operands if no operands appear on the command line. If there are operands +after the command line options, then standard input is typically ignored. +It can always be processed as an input data file, however, if a single bare +hyphen is put on the command line. + +@item text-of-file +@itemx some-text-of-file +Before calling your procedure, the contents of the file are read or mapped +into memory. (Excessively large files may cause problems.) The +@samp{some-text-of-file} disallows empty files. Both require regular files. +In this case, the profile for your procedure must be: + +@example +program_exit_code_t +@var{my_handler}(char const * fname, char * file_text, + size_t text_size); +@end example + +@noindent +Note that though the @code{file_text} is not @code{const}, any changes made to +it are not written back to the original file. It is merely a memory image of +the file contents. Also, the memory allocated to hold the text is +@code{text_size + 1} bytes long and the final byte is always @code{NUL}. The +file contents need not be text, as the data are read with the @code{read(2)} +system call. + +@code{file_text} is automatically freed, unless you specify a +@vindex handler-frees +@code{handler-frees} attribute. Then your code must @code{free(3)} the text. +@end table + +If you select one of these file type handlers, then on access or usage errors +the @code{PROGRAM_EXIT_FAILURE} exit code will, by default, be or-ed +into the final exit code. This can be changed by specifying the +global @code{file-fail-code} attribute and naming a different value. +That is, something other than @code{failure}. You may choose @code{success}, +in which case file access issues will not affect the exit code and the error +message will not be printed. + +@node main-for-each-code +@unnumberedsubsubsec code for handler procedure + +@vindex MYHANDLER-code +With the @code{MYHANDLER-code} attribute, you provide the code for +your handler procedure in the option definition file. Note that the +spelling of this attribute depends on the name provided with the +@code{handler-proc} attribute, so we represent it here with +@code{MYHANDLER} as a place holder. As an example, your @code{main()} +procedure specification might look something like this: + +@example +main = @{ + main-type = for-each; + handler-proc = @var{MYHANDLER}; + @var{MYHANDLER}-code = <<- EndOfMyCode + /* whatever you want to do */ + EndOfMyCode; +@}; +@end example + +@noindent +and instead of an emitted external reference, a procedure will be emitted +that looks like this: + +@example +static int +@var{MYHANDLER}( char const* pz_entry ) +@{ + int res = 0; + <<@var{MYHANDLER}-code goes here>> + return res; +@} +@end example + +@node main-for-each-opts +@unnumberedsubsubsec for-each main procedure options + +These attributes affect the main procedure and how it processes +each argument or input line. + +@table @samp +@item interleaved +@vindex interleaved +If this attribute is specified, then options and operands may be +interleaved. Arguments or input lines beginning with a hyphen will +cause it to be passed through to an option processing function and +will take effect for the remainder of the operands (or input lines) +processed. + +@item main-init +@vindex main-init +This is code that gets inserted after the options have been processed, but +before the handler procs get invoked. + +@item main-fini +@vindex main-fini +This is code that gets inserted after all the entries have been processed, +just before returning from @code{main()}. + +@item comment-char +@vindex comment-char +When reading operands from standard input, if you wish comment lines to +start with a character other than a hash (@code{#}) character, then +specify one character with this attribute. If string value is empty, +then only blank lines will be considered comments. +@end table + +@node option attributes +@subsection Option Attributes +@cindex option attributes + +For each option you wish to specify, you must have a block macro named +@code{flag} defined. There are two required attributes: @code{name} and +@code{descrip}. If any options do not have a @code{value} (traditional flag +character) attribute, then the @code{long-opts} program attribute must also +be defined. As a special exception, if no options have a @code{value} +@strong{and} @code{long-opts} is not defined @strong{and} @code{argument} is +not defined, then all arguments to the program are named options. In this +case, the @option{-} and @option{--} command line option markers are optional. + +@menu +* Required Attributes:: Required Attributes +* Common Attributes:: Common Option Attributes +* Immediate Action:: Immediate Action Attributes +* Option Conflict Attributes:: Option Conflict Attributes + +These option attributes do not fit well with the above categories. + +* opt-attr settable:: Program may set option +* opt-attr no-preset:: Option cannot be pre-configured +* opt-attr equivalence:: Option Equivalence Class +* opt-attr aliases:: Option Aliasing +* opt-attr default option:: Default Option +* opt-attr documentation:: Option Sectioning Comment +* opt-attr translators:: Translator Notes +@end menu + +@node Required Attributes +@subsubsection Required Attributes +@cindex Required Attributes + +Every option must have exactly one copy of both of these attributes. + +@table @samp +@item name +@vindex name +Long name for the option. Even if you are not accepting long options +and are only accepting flags, it must be provided. AutoOpts generates +private, named storage that requires this name. This name also causes +a @code{#define}-d name to be emitted. It must not conflict with any +other names you may be using in your program. + +For example, if your option name is, @code{debug} or @code{munged-up}, +you must not use the @code{#define} names @code{DEBUG} (or +@code{MUNGED_UP}) in your program for non-AutoOpts related purposes. +They are now used by AutoOpts. + +Sometimes (most especially under Windows), you may get a surprise. +For example, @code{INTERFACE} is apparently a user space name that +one should be free to use. Windows usurps this name. To solve this, +you must do one of the following: + +@enumerate +@item +Change the name of your option +@item +add the program attribute (@pxref{program attributes}): + +@example +export = '#undef INTERFACE'; +@end example +@item +add the program attribute: + +@example +guard-option-names; +@end example +@end enumerate + +@item descrip +@vindex descrip +Except for documentation options, a @strong{very} brief description of the +option. About 40 characters on one line, maximum, not counting any texinfo +markups. Texinfo markups are stripped before printing in the usage text. It +appears on the @code{usage()} output next to the option name. + +If, however, the option is a documentation option, it will appear on one or +more lines by itself. It is thus used to visually separate and comment upon +groups of options in the usage text. +@end table + +@node Common Attributes +@subsubsection Common Option Attributes +@cindex Common Option Attributes + +These option attributes are optional. Any that do appear in the +definition of a flag, may appear only once. + +@table @samp +@item value +@vindex value +The flag character to specify for traditional option flags, e.g., @option{-L}. + +@item max +@vindex max +Maximum occurrence count (invalid if @var{disable} present). +The default maximum is 1. @code{NOLIMIT} can be used for the value, +otherwise it must be a number or a @code{#define} that evaluates to a number. + +@item min +@vindex min +Minimum occurrence count. If present, then the option @strong{must} +appear on the command line. Do not define it with the value zero (0). + +@item must-set +@vindex must-set +If an option must be specified, but it need not be specified on +the command line, then specify this attribute for the option. + +@item deprecated +@vindex deprecated +There are two effects to this attribute: the usage text will not +show the option, and the generated documentation will mark it with: +@emph{NOTE: THIS OPTION IS DEPRECATED}. + +@item disable +@vindex disable +Prefix for disabling (inverting sense of) the option. Only useful +if long option names are being processed. When an option has this +attribute, the test @code{ENABLED_OPT(OPTNAME)} is false when either +of the following is true: +@itemize @bullet +@item +The option has not been specified and the @code{enable} attribute has +not been specified. +@item +The option has been specified with this disabling prefix. +@end itemize +To detect that the option has been specified with the disabling +prefix, you must use: +@example +HAVE_OPT(OPTNAME) && ! ENABLED_OPT(OPTNAME) +@end example + +@item enable +@vindex enable +Long-name prefix for enabling the option (invalid if @var{disable} +@strong{not} present). Only useful if long option names are being +processed. + +@item enabled +@vindex enabled +If default is for option being enabled. (Otherwise, the OPTST_DISABLED +bit is set at compile time.) Only useful if the option can be disabled. + +@item ifdef +@itemx ifndef +@itemx omitted-usage +@vindex ifdef +@vindex ifndef +@vindex omitted-usage +If an option is relevant on certain platforms or when certain features +are enabled or disabled, you can specify the compile time flag used +to indicate when the option should be compiled in or out. For example, +if you have a configurable feature, @code{mumble} that is indicated +with the compile time define, @code{WITH_MUMBLING}, then add: + +@example +ifdef = WITH_MUMBLING; +@end example + +@noindent +Take care when using these. There are several caveats: + +@itemize @bullet +@item +The case and spelling must match whatever is specified. +@item +Do not confuse these attributes with the AutoGen directives of the +same names, @xref{Directives}. These cause C preprocessing directives +to be inserted into the generated C text. +@item +Only one of @code{ifdef} and @code{ifndef} may apply to any one option. +@item +The @code{VALUE_OPT_} values are @code{#define}-d. If @code{WITH_MUMBLING} +is not defined, then the associated @code{VALUE_OPT_} value will not be +@code{#define}-d either. So, if you have an option named, @code{MUMBLING} +that is active only if @code{WITH_MUMBLING} is @code{#define}-d, then +@code{VALUE_OPT_MUMBLING} will be @code{#define}-d iff @code{WITH_MUMBLING} +is @code{#define}-d. Watch those switch statements. +@item +If you specify @code{omitted-usage}, then the option will be recognized +as disabled when it is configured out of the build, but will yield the +message, ``This option has been disabled.'' You may specify an alternate +message by giving @code{omitted-usage} a string value. e.g.: +@example +omitted-usage = 'you cannot do this'; +@end example +@end itemize + +@item no-command +@vindex no-command +This option specifies that the option is not allowed on the command line. +Such an option may not take a @code{value} (flag character) attribute. The +program must have the @code{homerc} (@pxref{program attributes}) option set. +@end table + +@node Immediate Action +@subsubsection Immediate Action Attributes +@cindex immediate action + +Certain options may need to be processed early. For example, in order to +suppress the processing of configuration files, it is necessary to process the +command line option @option{--no-load-opts} @strong{before} the config files +are processed. To accommodate this, certain options may have their enabled or +disabled forms marked for immediate processing. The consequence of this is +that they are processed ahead of all other options in the reverse of normal +order. + +Normally, the first options processed are the options specified in the first +@code{homerc} file, followed by then next @code{homerc} file through to the +end of config file processing. Next, environment variables are processed and +finally, the command line options. The later options override settings +processed earlier. That actually gives them higher priority. Command line +immediate action options actually have the lowest priority of all. They would +be used only if they are to have an effect on the processing of subsequent +options. + +@table @samp +@item immediate +@vindex immediate +Use this option attribute to specify that the enabled form of the option +is to be processed immediately. The @code{help} and @code{more-help} +options are so specified. They will also call @code{exit()} upon +completion, so they @strong{do} have an effect on the processing +of the remaining options :-). + +@item immed-disable +@vindex immed-disable +Use this option attribute to specify that the disabled form of the +option is to be processed immediately. The @code{load-opts} option is +so specified. The @option{--no-load-opts} command line option will +suppress the processing of config files and environment variables. +Contrariwise, the @option{--load-opts} command line option is +processed normally. That means that the options specified in that file +will be processed after all the @code{homerc} files and, in fact, after +options that precede it on the command line. + +@item also +If either the @code{immediate} or the @code{immed-disable} attributes +are set to the string, @code{also}, then the option will actually be +processed twice: first at the immediate processing phase and again +at the normal time. +@end table + +@node Option Conflict Attributes +@subsubsection Option Conflict Attributes +@cindex Option Conflict Attributes + +These attributes may be used as many times as you need. +They are used at the end of the option processing to verify +that the context within which each option is found does not +conflict with the presence or absence of other options. + +This is not a complete cover of all possible conflicts and +requirements, but it simple to implement and covers the +more common situations. + +@table @samp +@cindex flags-must +@item flags-must +one entry for every option that @strong{must} be present +when this option is present + +@cindex flags-cant +@item flags-cant +one entry for every option that @strong{cannot} be present +when this option is present +@end table + +@node opt-attr settable +@subsubsection Program may set option +@vindex settable +If the option can be set outside of option processing, specify +@code{settable}. If this attribute is defined, special macros for setting +this particular option will be inserted into the interface file. For example, +@code{TEMPL_DIRS} is a settable option for AutoGen, so a macro named +@code{SET_OPT_TEMPL_DIRS(a)} appears in the interface file. This attribute +interacts with the @var{documentation} attribute. + +@node opt-attr no-preset +@subsubsection Option cannot be pre-configured +@vindex no-preset +@cindex configuration file +If presetting this option is not allowed, specify @code{no-preset}. +(Thus, environment variables and values set in configuration files will be +ignored.) + +@node opt-attr equivalence +@subsubsection Option Equivalence Class +@vindex equivalence +Generally, when several options are mutually exclusive and basically serve the +purpose of selecting one of several processing modes, specify the +@code{equivalence} attribute. These options will be considered an +equivalence class. Sometimes, it is just easier to deal with them as such. +All members of the equivalence class must contain the same equivalenced-to +option, including the equivalenced-to option itself. Thus, it must be a class +member. + +For an option equivalence class, there is a single occurrence counter for +the class. It can be referenced with the interface macro, +@code{COUNT_OPT(BASE_OPTION)}, where @var{BASE_OPTION} is the equivalenced-to +option name. + +Also, please take careful note: since the options are mapped to the +equivalenced-to option descriptor, any option argument values are mapped to +that descriptor also. Be sure you know which ``equivalent option'' was +selected before getting an option argument value! + +During the presetting phase of option processing +(@pxref{Presetting Options}), equivalenced options may be specified. +However, if different equivalenced members are specified, only the last +instance will be recognized and the others will be discarded. A conflict +error is indicated only when multiple different members appear on the +command line itself. + +As an example of where equivalenced options might be useful, @code{cpio(1)} +has three options @option{-o}, @option{-i}, and @option{-p} that define the +operational mode of the program (@code{create}, @code{extract} and +@code{pass-through}, respectively). They form an equivalence class from +which one and only one member must appear on the command line. If +@code{cpio} were an AutoOpt-ed program, then each of these option +definitions would contain: + +@example +equivalence = create; +@end example + +and the program would be able to determine the operating mode +with code that worked something like this: + +@example +switch (WHICH_IDX_CREATE) @{ +case INDEX_OPT_CREATE: ... +case INDEX_OPT_EXTRACT: ... +case INDEX_OPT_PASS_THROUGH: ... +default: /* cannot happen */ +@} +@end example + +@node opt-attr aliases +@subsubsection Option Aliasing + +Sometimes, for backwards compatibility or tradition or just plain convenience, +it works better to define one option as a pure alias for another option. +For such situations, provide the following pieces of information: +@example +flag = @{ + name = @i{aliasing-option-name}; + value = @i{aliasing-flag-char}; // optional ! + aliases = @i{aliased-to-option}; +@}; +@end example +Do not provide anything else. The usage text for such an option will be: +@example + This is an alias for @i{aliased-to-option} +@end example + +@node opt-attr default option +@subsubsection Default Option +@vindex default +If your program processes its arguments in named option mode (See +@code{long-opts} in @ref{program attributes}), then you may select +@strong{one} of your options to be the default option. Do so by using +attribute @code{default} with one of the options. The option so specified +must have an @code{arg-type} (@pxref{Option Arguments}) specified, but not the +@code{arg-optional} (@pxref{arg-optional}) attribute. That is to say, the +option argument must be required. + +If you have done this, then any arguments that do not match an option name and +do not contain an equal sign (@code{=}) will be interpreted as an option +argument to the default option. + +@node opt-attr documentation +@subsubsection Option Sectioning Comment +This attribute means the option exists for the purpose of separating option +description text in the usage output and texi documentation. Without this +attribute, every option is a separate node in the texi docs. With this +attribute, the documentation options become texi doc nodes and the options are +collected under them. Choose the name attribute carefully because it will +appear in the texi documentation. + +Libraries may also choose to make it settable so that the library can +determine which command line option is the first one that pertains to the +library. + +@vindex documentation +If the @samp{documentation} attribute is present, then all other +attributes are disabled except @code{settable}, @code{call-proc} and +@code{flag-code}. @code{settable} must be and is only specified if +@code{call-proc}, @code{extract-code} or @code{flag-code} has been specified. +When present, the @code{descrip} attribute will be displayed only when the +@option{--help} option has been specified. It will be displayed flush to the +left hand margin and may consist of one or more lines of text, filled to 72 +columns. + +The name of the option will not be printed in the help text. It @i{will}, +however, be printed as section headers in the texi documentation. If the +attribute is given a non-empty value, this text will be reproduced in the man +page and texi doc immediately after the @code{descrip} text. + +@node opt-attr translators +@subsubsection Translator Notes +@vindex translators +If you need to give the translators a special note about a particular option, +please use the @code{translators} attribute. The attribute text will be +emitted into the generated @code{.c} text where the option related strings get +defined. To make a general comment about all of the option code, add comments +to an @code{include} attribute (@pxref{program attributes}). Do @strong{not} +use this attribute globally, or it will get emitted into every option +definition block. + +@node Option Arguments +@subsection Option Argument Specification +@cindex Option Arguments + +Command line options come in three flavors: options that do not +take arguments, those that do and those that may. Without an +"arg-type" attribute, AutoOpts will not process an argument to an +option. If "arg-type" is specified and "arg-optional" is also +specified, then the next command line token will be taken to +be an argument, unless it looks like the name of another option. + +If the argument type is specified to be anything other than "str[ing]", then +AutoOpts will specify a callback procedure to handle the argument. Some of +these procedures will be created and inserted into the generated @file{.c} +file, and others are already built into the @file{libopts} library. +Therefore, if you write your own callback procedure +(@pxref{Option Argument Handling}), then you must either not specify an +"arg-type" attribute, or else specify it to be of type "str[ing]". Your +callback function will be able to place its own restrictions on what that +string may contain or represent. + +Option argument handling attributes depend upon the value set for the +@vindex arg-type +@code{arg-type} attribute. It specifies the type of argument the option +will take. If not present, the option cannot take an argument. If present, +it must be an entry in the following table. The first three letters is +sufficient. + +@menu +* arg-type string:: Arg Type String +* arg-type number:: Arg Type Number +* arg-type boolean:: Arg Type Boolean +* arg-type keyword:: Arg Type Keyword +* arg-type set membership:: Arg Type Set Membership +* arg-type hierarchy:: Arg Type Hierarchical +* arg-type file name:: Arg Type File Name +* arg-type time-duration:: Arg Type Time Duration +* arg-type time-date:: Arg Type Time and Date + +Supporting attributes for particular argument types: + +* arg-keyword:: Keyword list +* arg-optional:: Option Argument Optional +* arg-default:: Default Option Argument Value +@end menu + +@node arg-type string +@subsubsection Arg Type String +@code{arg-type = string;} + +The argument may be any arbitrary string, though your program or option +callback procedure may place additional constraints upon it. + + +@node arg-type number +@subsubsection Arg Type Number +@code{arg-type = number;} + +The argument must be a correctly formed integer, without any trailing U's or +L's. AutoOpts contains a library procedure to convert the string to a number. +If you specify range checking with @code{arg-range} (see below), then AutoOpts +produces a special purpose procedure for this option. + +@table @samp +@item scaled +@vindex scaled +@code{scaled} marks the option so that suffixes of @samp{k}, @samp{K}, +@samp{m}, @samp{M}, @samp{g}, @samp{G}, @samp{t}, and @samp{T} will multiply +the given number by a power of 1000 or 1024. Lower case letters scale by a +power of 1000 and upper case scale by a power of 1024. + +@item arg-range +@vindex arg-range +@code{arg-range} is used to create a callback procedure for validating the +range of the option argument. It must match one of the range entries. Each +@code{arg-range} should consist of either an integer by itself or an integer +range. The integer range is specified by one or two integers separated by the +two character sequence, @code{->}. Be sure to quote the entire range string. +The definitions parser will not accept the range syntax as a single string +token. + +The generated procedure imposes the range constraints as follows: +@itemize @bullet +@item +A number by itself will match that one value. +@item +The high end of the range may not be @code{INT_MIN}, both for obvious +reasons and because that value is used to indicate a single-valued match. +@item +An omitted lower value implies a lower bound of INT_MIN. +@item +An omitted upper value implies a upper bound of INT_MAX. +@item +The argument value is required. It may not be optional. +@item +The value must match one of the entries. If it can match more than one, +then you have redundancies, but no harm will come of it. +@end itemize +@end table + + +@node arg-type boolean +@subsubsection Arg Type Boolean +@code{arg-type = boolean;} + +The argument will be interpreted and always yield either AG_TRUE or +AG_FALSE. False values are@: the empty string, the number zero, or a +string that starts with @code{f}, @code{F}, @code{n} or @code{N} +(representing False or No). Anything else will be interpreted as True. + + +@node arg-type keyword +@subsubsection Arg Type Keyword +@code{arg-type = keyword;} + +The argument must match a specified list of strings (@pxref{arg-keyword}). +Assuming you have named the option, @code{optn-name}, the strings will be +converted into an enumeration of type @code{te_Optn_Name} with the values +@code{OPTN_NAME_KEYWORD}.* If you have @strong{not} specified a default +value, the value @code{OPTN_NAME_UNDEFINED} will be inserted with the value +zero. The option will be initialized to that value. You may now use this +in your code as follows: + +@example +te_Optn_Name opt = OPT_VALUE_OPTN_NAME; +switch (opt) @{ +case OPTN_NAME_UNDEFINED: /* undefined things */ break; +case OPTN_NAME_KEYWORD: /* `keyword' things */ break; +default: /* utterly impossible */ ; +@} +@end example + +AutoOpts produces a special purpose procedure for this option. +You may not specify an alternate handling procedure. + +If you have need for the string name of the selected keyword, you +may obtain this with the macro, @code{OPT_OPTN_NAME_VAL2STR(val)}. +The value you pass would normally be @code{OPT_VALUE_OPTN_NAME}, +but anything with numeric value that is legal for @code{te_Optn_Name} +may be passed. Anything out of range will result in the string, +@samp{"*INVALID*"} being returned. The strings are read only. +It may be used as in: + +@example +te_Optn_Name opt = OPT_VALUE_OPTN_NAME; +printf( "you selected the %s keyword\n", + OPT_OPTN_NAME_VAL2STR(opt) ); +@end example + +* Note: you may replace the @code{OPTN_NAME} enumeration prefix with +another prefix by specifying a +@vindex prefix-enum +@code{prefix-enum} attribute. + +Finally, users may specify the argument either by name or by number. +Since the numeric equivalents change by having new entries inserted +into the keyword list, this would not be a recommended practice. +However, either @code{-1} or @code{~0} will always be equivalent to +specifying the last keyword. + +@node arg-type set membership +@subsubsection Arg Type Set Membership +@code{arg-type = set;} + +The argument must be a list of names each of which must match the strings +``@code{all}'', ``@code{none}'' or one of the keywords (@pxref{arg-keyword}) +specified for this option. @code{all} will turn on all membership bits and +@code{none} will turn them all off. Specifying one of the keywords will set +the corresponding set membership bit on (or off, if negated) . Literal +numbers may also be used and may, thereby, set or clear more than one bit. + +The membership result starts with the previous (or initialized) result. To +clear previous results, either start the membership string with @samp{none +} +or with the equals character (@samp{=}). To invert (bit flip) the final +result (regardless of whether the previous result is carried over or not), +start the string with a carat character (@samp{^}). If you wish to invert the +result and start without a carried over value, use one of the following: +@code{=^} or @code{^none+}. These are equivalent. + +The list of names or numbers must be separated by one of the following +characters: @samp{+-|!,} or whitespace. The comma is equivalent to +whitespace, except that only one may appear between two entries and it may not +appear in conjunction with the @var{or} bar (@samp{|}). The @samp{+|} leading +characters or unadorned name signify adding the next named bit to the mask, +and the @samp{-!} leading characters indicate removing it. + +The number of keywords allowed is constrained by the number of bits in a +pointer, as the bit set is kept in a @code{void *} pointer. + +If, for example, you specified @code{first} in your list of keywords, +then you can use the following code to test to see if either @code{first} +or @code{all} was specified: + +@example +uintptr_t opt = OPT_VALUE_OPTN_NAME; +if (opt & OPTN_NAME_FIRST) + /* OPTN_NAME_FIRST bit was set */ ; +@end example + +AutoOpts produces a special purpose procedure for this option. +To set multiple bits as the default (initial) value, you must +specify an initial numeric value (which might become inaccurate over +time), or else specify @code{arg-default} multiple times. Do not +specify a series of names conjoined with @code{+} symbols as the +value for any of the @code{arg-default} attributes. That works for +option parsing, but not for the option code generation. + +@node arg-type hierarchy +@subsubsection Arg Type Hierarchical +@code{arg-type = hierarchy;} +@* +@code{arg-type = nested;} + +This denotes an option with a structure-valued argument, a.k.a. +@code{subopts} in @code{getopts} terminology. The argument is parsed +and the values made available to the program via the find and +find next calls (@xref{libopts-optionFindValue}, +@xref{libopts-optionGetValue}, and +@pxref{libopts-optionFindNextValue}). + +@example +tOptionValue * val = optionGetValue(VALUE_OPT_OPTN_NAME, "name"); +while (val != NULL) @{ + process(val); + val = optionNextValue(VALUE_OPT_OPTN_NAME, val); + if (wrong_name(val, "name")) + break; +@} +@end example + + +@node arg-type file name +@subsubsection Arg Type File Name +@code{arg-type = file;} + +This argument type will have some validations on the argument and, +optionally, actually open the file. You must specify several additonal +attributes for the option: + +@table @samp +@item file-exists +@vindex file-exists +If not specified or empty, then the directory portion of the name is checked. +The directory must exist or the argument is rejected and the usage procedure +is invoked. + +Otherwise, both the directory as above and the full name is tested for +existence. If the value begins with the two letters @code{no}, then the file +must not pre-exist. Otherwise, the file is expected to exist. + +@item open-file +@vindex open-file +If not specified or empty, the file is left alone. +If the value begins with the four letters @code{desc}[@i{riptor}], then +@code{open(2)} is used and @code{optArg.argFd} is set. Otherwise, the +file is opened with @code{fopen} and @code{optArg.argFp} is set. + +@item file-mode +@vindex file-mode +If @code{open-file} is set and not empty, then you must specify the open mode. +Set the value to the flag bits or mode string as appropriate for the open +type. +@end table + + +@node arg-type time-duration +@subsubsection Arg Type Time Duration +@code{arg-type = time-duration;} + +The argument will be converted into a number of seconds. It may be +a multi-part number with different parts being multiplied into a seconds +value and added into the final result. Valid forms are in the table +below. Upper cased letters represent numbers that must be used in the +expressions. + +@table @samp +@item [[HH:]MM:]SS +@code{HH} is multiplied by @code{3600} and @code{MM} multiplied by @code{60} +before they are added to @code{SS}. This time specification may not be +followed by any other time specs. @code{HH} and @code{MM} are both optional, +though @code{HH} cannot be specified without @code{MM}. + +@item DAYS d +@code{DAYS} is multiplied by the number of seconds in a day. This value may +be followed by (and added to) values specified by @code{HH:MM:SS} or the +suffixed values below. If present, it must always be first. + +@item HRS h +@code{HRS} is multiplied by the number of seconds in an hour. This value may +be followed by (and added to) values specified by @code{MM:SS} or the +suffixed values below. + +@item MINS m +@code{MINS} is multiplied by the number of seconds in a minute. This value +may be followed by (and added to) a count of seconds. + +@item SECS s +This value can only be the last value in a time specification. The @code{s} +suffix is optional. +@end table + +@example + 5 d 1:10:05 ==> 5 days + 1 hour 10 minutes and 5 seconds + 5 d 1 h 10 m 5 ==> yields: 436205 seconds + 5d1h10m5s ==> same result -- spaces are optional. +@end example + +When saved into a config file, the value will be stored as a simple count +of seconds. There are actually more (many) accepted time duration strings. +The full documentation can be found with ISO-8601 documentation and the +more extedded documentation when @code{parse_duration()} becomes more widely +available. + + +@node arg-type time-date +@subsubsection Arg Type Time and Date +@code{arg-type = time-date;} + +The argument will be converted into the number of seconds since the epoch. +The conversion rules are very complicated, please see the +@file{getdate_r(3GNU)} man page. There are some additional restrictions: + +@enumerate +@item +Your project must be compiled with @code{PKGDATADIR} defined and naming a +valid directory. +@item +The @env{DATEMSK} environment variable will be set to the @file{datemsk} file +within that directory. +@end enumerate + +If that file is not accessible for any reason, the string will be +parsed as a time duration (@pxref{arg-type time-duration}) instead of a +specific date and time. + +@node arg-keyword +@subsubsection Keyword list +@vindex keyword +If the @code{arg-type} is @code{keyword} (@pxref{arg-type keyword}) or +@code{set-membership} (@pxref{arg-type set membership}), then you must specify +the list of keywords by a series of @code{keyword} entries. The interface +file will contain values for @env{@i{<OPTN_NAME>}_@i{<KEYWORD>}} for each +keyword entry. @code{keyword} option types will have an enumeration and +@code{set-membership} option types will have a set of unsigned bits +@code{#define}-d. + +If the @code{arg-type} is specifically @code{keyword}, you may also add +special handling code with a +@vindex extra-code +@code{extra-code} attribute. After @code{optionEnumerationVal} has +converted the input string into an enumeration, you may insert code to +process this enumeration value (@code{pOptDesc->optArg.argEnum}). + +@node arg-optional +@subsubsection Option Argument Optional +@vindex arg-optional +The @code{arg-optional} attribute indicates that the argument to the option is +optional (need not be specified on the command line). This is only valid if +the @var{arg-type} is @code{string} (@pxref{arg-type string}) or +@code{keyword} (@pxref{arg-type keyword}). If it is @code{keyword}, then this +attribute may also specify the default keyword to assume when the argument is +not supplied. If left empty, @var{arg-default} (@pxref{arg-default}) or the +zero-valued keyword will be used. + +The syntax rules for identifying the option argument are: +@itemize @bullet +@item +If the option is specified with a flag character and there is a character +following the flag character, then string following that flag character is the +option argument. +@item +If the flag character is the last character in an argument, then +the first character of the next argument is examined. If it is a hyphen, +then the option is presumed to not have an argument. Otherwise, the entire +next argument is the argument for the option. +@item +If the option is specified with a long option name and that name is ended with +an equal sign character (@code{=}), then everything after that character is the +option argument. +@item +If the long name is ended by the end of the argument, then the first character +of the next argument is examined, just as with the flag character ending an +argument string. +@end itemize + +This is overridden and the options are required if the libopts library +gets configured with @option{--disable-optional-args}. + +@node arg-default +@subsubsection Default Option Argument Value +@vindex arg-default +This specifies the default option argument value to be used when the option is +not specified or preset. You may specify multiple @code{arg-default} values +if the argument type is @code{set membership}. + +@node Option Argument Handling +@subsection Option Argument Handling +@cindex Option Argument Handling + +AutoOpts will either specify or automatically generate callback procedures +for options that take specialized arguments. The only option argument types +that are not specialized are plain string arguments and no argument at all. +For options that fall into one of those two categories, you may specify your +own callback function, as specified below. If you do this and if you +specify that options are resettable (@pxref{automatic options}), then your +option handling code @strong{must} look for the @samp{OPTST_RESET} bit in +the @code{fOptState} field of the option descriptor. + +If the option takes a string argument, then the @code{stack-arg} attribute can +be used to specify that the option is to be handled by the @code{libopts} +@code{stackOptArg()} and @code{unstackOptArg()} library procedures (see +below). In this case, you may not provide option handling code. + +Finally, @samp{documentation} options (@pxref{opt-attr documentation}) may +also be marked as @option{settable} (@pxref{opt-attr settable}) and have +special callback functions (either @samp{flag-code}, @samp{extract-code}, +or @samp{call-proc}). + +@table @samp +@item flag-code +@vindex flag-code +statements to execute when the option is encountered. This may be used in +conjunction with option argument types that cause AutoOpts to emit handler +code. If you do this, the @samp{flag-code} with index zero (0) is emitted +into the handler code @emph{before} the argument is handled, and the entry +with index one (1) is handled afterward. + +The generated procedure will be laid out something like this: + +@example +static void +doOpt<name>(tOptions* pOptions, tOptDesc* pOptDesc) +@{ +<flag-code[0]> +<AutoOpts defined handler code> +<flag-code[1]> +@} +@end example + +Only certain fields within the @code{tOptions} and @code{tOptDesc} +structures may be accessed. @xref{Option Processing Data}. When writing +this code, you must be very careful with the @code{pOptions} pointer. The +handler code is called with this pointer set to special values for handling +special situations. Your code must handle them. As an example, +look at @code{optionEnumerationVal} in @file{enum.c}. + +@item extract-code +@vindex extract-code +This is effectively identical to @code{flag-code}, except that the +source is kept in the output file instead of the definitions file +and you cannot use this in conjunction with options with arguments, +other than string arguments. + +A long comment is used to demarcate the code. You must not modify +that marker. @i{Before} regenerating the option code file, +the old file is renamed from MUMBLE.c to MUMBLE.c.save. The template +will be looking there for the text to copy into the new output file. + +@item call-proc +@vindex call-proc +external procedure to call when option is encountered. The calling +sequence must conform to the sequence defined above for the generated +procedure, @code{doOpt<name>}. It has the same restrictions +regarding the fields within the structures passed in as arguments. +@xref{Option Processing Data}. + +@item flag-proc +@vindex flag-proc +Name of another option whose @code{flag-code} can be executed +when this option is encountered. + +@item stack-arg +@vindex stack-arg +Call a special library routine to stack the option's arguments. Special +macros in the interface file are provided for determining how many of the +options were found (@code{STACKCT_OPT(NAME)}) and to obtain a pointer to a +list of pointers to the argument values (@code{STACKLST_OPT(NAME)}). +Obviously, for a stackable argument, the @code{max} attribute +(@pxref{Common Attributes}) needs to be set higher than @code{1}. + +If this stacked argument option has a disablement prefix, then the entire +stack of arguments will be cleared by specifying the option with that +disablement prefix. + +@item unstack-arg +@vindex unstack-arg +Call a special library routine to remove (@code{unstack}) strings +from a @code{stack-arg} option stack. This attribute must name +the option that is to be @code{unstacked}. Neither this option nor +the stacked argument option it references may be equivalenced to +another option. +@end table + +@node Internationalizing Options +@subsection Internationalizing Options +@cindex Internationalizing Options + +Normally, AutoOpts produces usage text that is difficult to translate. It is +pieced together on the fly using words and phrases scattered around here and +there, piecing together toe document. This does not translate well. + +Incorporated into this package are some ways around the problem. First, you +should specify the @code{full-usage} and @code{short-usage} program attributes +(@pxref{program attributes}). This will enable your translators to translate +the usage text as a whole. + +Your translators will also be able to translate long option names. The option +name translations will then become the names searched for both on the command +line and in configuration files. However, it will not affect the names of +environment variable names used to configure your program. + +If it is considered desireable to keep configuration files in the @code{C} +locale, then several macros are available to suppress or delay the +translations of option names at run time. These are all disabled if +@code{ENABLE_NLS} is not defined at compile time or if @code{no-xlate} has +been set to the value @emph{anything}. These macros @strong{must} +be invoked before the first invocation of @code{optionProcess}. + +@table @samp +@item OPT_NO_XLAT_CFG_NAMES; +@itemx OPT_XLAT_CFG_NAMES; +Disable (or enable) the translations of option names for configuration files. +If you enable translation for config files, then they will be translated for +command line options. + +@item OPT_NO_XLAT_OPT_NAMES; +@itemx OPT_XLAT_OPT_NAMES; +Disable (or enable) the translations of option names for command line +processing. If you disable the translation for command line processing, +you will also disable it for configuration file processing. Once translated, +the option names will remain translated. +@end table + +@node documentation attributes +@subsection Man and Info doc Attributes +@cindex documentation attributes + +AutoOpts includes AutoGen templates for producing abbreviated man pages +and for producing the invoking section of an info document. To take +advantage of these templates, you must add several attributes to your +option definitions. + +@menu +* per option attributes:: Per option documentation attributes +* global option attributes:: Global documentation attributes +@end menu + +@node per option attributes +@subsubsection Per option documentation attributes + +These attributes are sub-attributes (@i{sub-stanzas}) of the @code{flag} stanzas. + +@table @samp +@item arg-name +@vindex arg-name +If an option has an argument, the argument should have a name for +documentation purposes. It will default to @code{arg-type}, but +it will likely be clearer with something else like, @code{file-name} +instead of @code{string} (the type). + +@item doc +@vindex doc +First, every @code{flag} definition @emph{other than} @code{documentation} +definitions, must have a @code{doc} attribute defined. If the option takes +an argument, then it will need an @code{arg-name} attribute as well. The +@code{doc} text should be in plain sentences with minimal formatting. The +Texinfo commands @code{@@code}, and @code{@@var} will have its enclosed text +made into @strong{\fB} entries in the man page, and the @code{@@file} text +will be made into @strong{\fI} entries. The @code{arg-name} attribute is +used to display the option's argument in the man page. + +Options marked with the @code{documentation} attribute are for documenting +the usage text. All other options should have the @code{doc} attribute in +order to document the usage of the option in the generated man pages. + +Since these blocks of text are inserted into all output forms, +any markup text included in these blocks must be massaged for each +output format. By default, it is presumed to be @file{texi} format. +@end table + +@node global option attributes +@subsubsection Global documentation attributes +@table @samp +@item cmd-section +@vindex cmd-section +If your command is a game or a system management command, +specify this attribute with the value @code{5} or @code{8}, respectively. +The default is a user command (section 1). + +@item detail +@vindex detail +This attribute is used to add a very short explanation about what +a program is used for when the @code{title} attribute is insufficient. +If there is no @code{doc-section} stanza of type @code{DESCRIPTION}, then +this text is used for the man page DESCRIPTION section, too. + +@item addtogroup +@vindex addtogroup +This attribute tells the template that the generated code should be +surrounded with the following doxygen comments: +@example +/** @@file <header-or-code-file-name> + * @@addtogroup <value-of-addtogroup> + * @@@{ + */ +@end example +@noindent +and +@example +/** @@@} */ +@end example + +@item option-format +@vindex option-format +Specify the default markup style for the @code{doc} stanzas. +By default, it is @code{texi}, but @code{man} and @code{mdoc} may +also be selected. There are nine converter programs that do a partial +job of converting one form of markup into another. @command{texi2texi}, +@command{man2man} and @command{mdoc2mdoc} work pretty well. + +You may also post process the document by using @code{doc-sub} stanzas, +see below. + +@item option-info +@vindex option-info +This text will be inserted as a lead-in paragraph in the @code{OPTIONS} +section of the generated man page. + +@item doc-section +@vindex doc-section +This is a compound attribute that requires three @i{sub}attributes: + +@table @i +@item ds-format +This describes the format of the associated @code{ds-text} section. +@code{man}, @code{mdoc} and @code{texi} formats are supported. +Regardless of the chosen format, the formatting tags in the output +text will be converted to @code{man} macros for @code{man} pages, +@code{mdoc} macros for @code{mdoc} pages, and @code{texi} macros for +@code{texinfo} pages. + +@item ds-text +This is the descriptive text, written according to the rules for +@code{ds-format} documents. + +@item ds-type +This describes the section type. Basically, the title of the section +that will be added to all output documentation. There may be only one +@code{doc-section} for any given @code{ds-type}. If there are duplicates, +the results are undefined (it might work, it might not). + +There are five categories of @code{ds-type} sections. +They are those that the documentation templates would otherwise: +@enumerate +@item +always create itself, ignoring any @code{ds-type}s by this name. +These are marked, below, as @code{ao-only}. +@item +create, if none was provided. +These are marked, @code{alternate}. +@item +create, but augment if the @code{doc-section} was provided. +These are marked, @code{augments}. +@item +do nothing, but inserts them into the output in a prescribed order. +These are marked, @code{known} +@item +knows nothing about them. They will be alphabetized and inserted +after the list of leading sections and before the list of trailing +sections. These are not marked because I don't know their names. +@end enumerate + +Some of these are emitted by the documentation templates only if +certain conditions are met. If there are conditions, they are +explained below. If there are no conditions, then you will always +see the named section in the output. + +The output sections will appear in this order: +@table @samp +@item NAME +@code{ao-only}. +@item SYNOPSIS +@code{alternate}. +@item DESCRIPTION +@code{augments}. +@item OPTIONS +@code{ao-only}. +@item OPTION PRESETS +@code{ao-only}, if environment presets or configuration file processing +has been specified. +@item unknown +At this point, the unknown, alphabetized sections are inserted. +@item IMPLEMENTATION NOTES +@code{known} +@item ENVIRONMENT +@code{augments}, if environment presets have been specified. +@item FILES +@code{augments}, if configuration file processing has been specified. +@item EXAMPLES +@code{known} +@item EXIT STATUS +@code{augments}. +@item ERRORS +@code{known} +@item COMPATIBILITY +@code{known} +@item SEE ALSO +@code{known} +@item CONFORMING TO +@code{known} +@item HISTORY +@code{known} +@item AUTHORS +@code{alternate}, if the @code{copyright} stanza has either +an @code{author} or an @code{owner} attribute. +@item COPYRIGHT +@code{alternate}, if there is a @code{copyright} stanza. +@item BUGS +@code{augments}, if the @code{copyright} stanza has an +@code{eaddr} attribute. +@item NOTES +@code{augments}. +@end table +@end table + +@noindent +Here is an example of a @code{doc-section} for a @code{SEE ALSO} type. + +@example +doc-section = @{ + ds-type = 'SEE ALSO'; // or anything else + ds-format = 'man'; // or texi or mdoc format + ds-text = <<-_EOText_ + text relevant to this section type, + in the chosen format + _EOText_; +@}; +@end example + +@item doc-sub +@vindex doc-sub +This attribute will cause the resulting documentation to be post-processed. +This is normally with @command{sed}, see @code{doc-sub-cmd} below. +This attribute has several sub-attributes: + +@table @samp +@item sub-name +This is the name of an autogen text definition value, like @code{prog-name} +or @code{version}. In the @code{sub-text} field, occurrences of this +name preceded by two less than characters and followed by two greater +than characters will be replaced by the text value of the definition, +e.g. @samp{<<prog-name>>}. + +@item sub-text +The text that gets added to the command file for the post processing +program. + +@item sub-type +If this command only applies to certain types of output, specify +this with a regular expression that will match one of the valid +output format types, e.g. @samp{man|mdoc} will match those two kinds, +but not @code{texi} output. If omitted, it will always apply. +@end table + +For example, if you want to reference the program name in the @code{doc} +text for an option common to two programs, put @samp{#PROG#} into the +text. The following will replace all occrrences of @samp{#PROG#} +with the current value for @code{prog}: +@example +doc-sub = @{ + sub-name = prog-name; + sub-text = 's/#PROG#/<<prog-name>>/g'; +@}; +@end example + +@item doc-sub-cmd +@vindex doc-sub-cmd +A formatting string for constructing the post-processing command. +The first parameter is the name of the file with editing commands in it, +and the second is the file containing the unprocessed document. +The default value is: +@example +sed -f %s %s +@end example +@end table + +@node automatic options +@subsection Automatically Supported Options +@cindex automatic options + +AutoOpts provides automated support for several options. @code{help} and +@code{more-help} are always provided. The others are conditional upon +various global program attributes being defined @xref{program attributes}. + +Below are the option names and default flag values. The flags are activated +if and only if at least one user-defined option also uses a flag value. The +long names are supported as option names if @code{long-opts} has been +specified. These option flags may be deleted or changed to characters of your +choosing by specifying +@vindex more-help-value +@vindex usage-value +@vindex version-value +@vindex load-opts-value +@vindex reset-value +@code{xxx-value = "y";}, where @code{xxx} is one of the option names below and +@code{y} is either empty or the character of your choice. For example, to +change the help flag from @code{?} to @code{h}, specify +@vindex help-value +@code{help-value = "h";}; and to require that @code{save-opts} be specified +only with its long option name, specify +@vindex save-opts-value +@code{save-opts-value = "";}. + +Additionally, the procedure that prints out the program version may be +replaced by specifying @code{version-proc}. +@vindex version-proc +This procedure must be defined to be of external scope (non-static). +By default, the AutoOpts library provides @code{optionPrintVersion} +and it will be the specified callback function in the option +definition structure. + +With the exception of the @code{load-opts} option, none of these automatically +supported options will be recognized in configuration files or environment +variables. + +@table @samp +@item help -? +This option will immediately invoke the @code{USAGE()} procedure +and display the usage line, a description of each option with +its description and option usage information. This is followed +by the contents of the definition of the @code{detail} text macro. + +@item more-help -! +This option is identical to the @code{help} option, except that the +output is passed through a pager program. (@code{more} by default, or +the program identified by the @code{PAGER} environment variable.) + +@item usage -u +This option must be requested by specifying, @code{usage-opt} in the option +definition file. It will produce abbreviated help text to @file{stdout} and +exit with zero status (@code{EXIT_SUCCESS}). + +@item version -v + +This will print the program name, title and version. If it is not +followed by anything or is followed by the letter @code{v}, just the +program name and version will be printed. If followed by the letter +@code{c} and a value for @code{copyright} and @code{owner} have been +provided, then the copyright will be printed, too. If it is followed by +the letter @code{n}, then the full copyright notice (if available) will +be printed. The @code{version} attribute must be specified in the +option definition file. + +Because some target platforms discourage optional arguments to options, +the autoopts library can be compiled with @code{NO_OPTIONAL_OPT_ARGS} +defined. Alternatively, the @code{version-type} attribute can be added +to the option definitions and it can specify which flavor is preferred. +In either case, an argument to the @code{--version} option will then be +disallowed. + +@item load-opts -< +@cindex configuration file +This option will load options from the named file. They will be treated +exactly as if they were loaded from the normally found configuration files, +but will not be loaded until the option is actually processed. This can also +be used within another configuration file, causing them to nest. This is the +@strong{only} automatically supported option that can be activated inside of +config files or with environment variables. + +Specifying the negated form of the option (@option{--no-load-opts}) will +suppress the processing of configuration files and environment variables. + +This option is activated by specifying one or more @code{homerc} attributes. + +@item save-opts -> +@cindex configuration file +This option will cause the option state to be printed in the configuration +file format when option processing is done but not yet verified for +consistency. The program will terminate successfully without running when +this has completed. Note that for most shells you will have to quote or +escape the flag character to restrict special meanings to the shell. + +The output file will be the configuration file name (default or provided by +@code{rcfile}) in the last directory named in a @code{homerc} definition. + +This option may be set from within your program by invoking the +"@code{SET_OPT_SAVE_OPTS(@i{filename})}" macro (@pxref{SET_OPT_name}). +Invoking this macro will set the file name for saving the option processing +state, but the state will @strong{not} actually be saved. You must call +@code{optionSaveFile} to do that (@pxref{libopts-optionSaveFile}). +@strong{CAVEAT:} if, after invoking this macro, you call +@code{optionProcess}, the option processing state will be saved to this file +and @code{optionProcess} will not return. You may wish to invoke +@code{CLEAR_OPT( SAVE_OPTS )} (@pxref{CLEAR_OPT}) beforehand if you do need +to reinvoke @code{optionProcess}. + +This option is activated by specifying one or more @code{homerc} attributes. + +The method of saving the state may be altered by specifying flags before +the output file name. ``Flags'' are specified by placing a list of them +before the file name and separating them from the name with one or two +greater-than characters (``>''). There are three flags currently supported: + +@table @samp +@item default +If an option has a default value (has not been set), then the default value +is inserted as a comment. + +@item usage +Every option that can be processed from the configuration file will have a +comment that contains the usage string that gets printed with the @code{--help} text + +@item update +Instead of removing the old file and writing a new one, the output file is kept, +but any pre-existing segment labeled with @code{<?program prog-name>} is removed. +The new program segment is placed at the end of the file. This flag is implied if +the flags are separated from the file name with doubled greater-than characters. +In other words, @code{update,usage > @i{file-name}} and @code{usage >> @i{file-name}} +are identical. +@end table + +@item reset-option -R +This option takes the name of an option for the current program and resets its +state such that it is set back to its original, compile-time initialized +value. If the option state is subsequently stored (via @option{--save-opts}), +the named option will not appear in that file. + +This option is activated by specifying the @code{resettable} attribute. + +@strong{BEWARE}: If the @code{resettable} attribute is specified, all +option callbacks @strong{must} look for the @code{OPTST_RESET} bit in the +@code{fOptState} field of the option descriptor. If set, the @code{optCookie} +and @code{optArg} fields will be unchanged from their last setting. When the +callback returns, these fields will be set to their original values. If you +use this feature and you have allocated data hanging off of the cookie, you +need to deallocate it. +@end table + +@node standard options +@subsection Library of Standard Options +@cindex standard options + +AutoOpts has developed a set of standardized options. +You may incorporate these options in your program simply by @emph{first} +adding a @code{#define} for the options you want, and then the line, + +@example +#include stdoptions.def +@end example + +@noindent +in your option definitions. The supported options are specified thus: + +@example +#define DEBUG +#define DIRECTORY +#define DRY_RUN +#define INPUT +#define INTERACTIVE +#define OUTPUT +#define WARN + +#define SILENT +#define QUIET +#define BRIEF +#define VERBOSE +@end example + +By default, only the long form of the option will be available. +To specify the short (flag) form, suffix these names with @code{_FLAG}. +e.g., + +@example +#define DEBUG_FLAG +@end example + +@option{--silent}, @option{--quiet}, @option{--brief} and @option{--verbose} +are related in that they all indicate some level of diagnostic output. These +options are all designed to conflict with each other. Instead of four +different options, however, several levels can be incorporated by +@code{#define}-ing @code{VERBOSE_ENUM}. In conjunction with @code{VERBOSE}, +it incorporates the notion of @i{5} levels in an enumeration: @code{silent}, +@code{quiet}, @code{brief}, @code{informative} and @code{verbose}; with the +default being @code{brief}. + +@ignore +END == AUTOOPTS-MAIN == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@ignore +START == AUTOOPTS-API == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@c === SECTION MARKER + +@node AutoOpts API +@section Programmatic Interface +@cindex AutoOpts API + +The user interface for access to the argument information is completely +defined in the generated header file and in the portions of the +distributed file "options.h" that are marked "public". + +In the following macros, text marked @var{<NAME>} or @var{name} +is the name of the option @strong{in upper case} and +@strong{segmented with underscores @code{_}}. The macros and enumerations +defined in the options header (interface) file are used as follows: + +To see how these @code{#define} macros are used in a program, +the reader is referred to the several @file{opts.h} files +included with the AutoGen sources. + +@menu +* Option Processing Data:: Data for Option Processing +* CLEAR_OPT:: CLEAR_OPT( <NAME> ) - Clear Option Markings +* COUNT_OPT:: COUNT_OPT( <NAME> ) - Definition Count +* DESC:: DESC( <NAME> ) - Option Descriptor +* DISABLE_OPT_name:: DISABLE_OPT_name - Disable an option +* ENABLED_OPT:: ENABLED_OPT( <NAME> ) - Is Option Enabled? +* ERRSKIP_OPTERR:: ERRSKIP_OPTERR - Ignore Option Errors +* ERRSTOP_OPTERR:: ERRSTOP_OPTERR - Stop on Errors +* HAVE_OPT:: HAVE_OPT( <NAME> ) - Have this option? +* ISSEL_OPT:: ISSEL_OPT( <NAME> ) - Is Option Selected? +* ISUNUSED_OPT:: ISUNUSED_OPT( <NAME> ) - Never Specified? +* OPTION_CT:: OPTION_CT - Full Count of Options +* OPT_ARG:: OPT_ARG( <NAME> ) - Option Argument String +* OPT_NO_XLAT_CFG_NAMES:: OPT_NO_XLAT_CFG_NAMES - option name xlation +* OPT_NO_XLAT_OPT_NAMES:: OPT_NO_XLAT_OPT_NAMES - option name xlation +* OPT_VALUE_name:: OPT_VALUE_name - Option Argument Value +* OPT_XLAT_CFG_NAMES:: OPT_XLAT_CFG_NAMES - option name xlation +* OPT_XLAT_OPT_NAMES:: OPT_XLAT_OPT_NAMES - option name xlation +* RESTART_OPT:: RESTART_OPT( n ) - Resume Option Processing +* SET_OPT_name:: SET_OPT_name - Force an option to be set +* STACKCT_OPT:: STACKCT_OPT( <NAME> ) - Stacked Arg Count +* STACKLST_OPT:: STACKLST_OPT( <NAME> ) - Argument Stack +* START_OPT:: START_OPT - Restart Option Processing +* STATE_OPT:: STATE_OPT( <NAME> ) - Option State +* USAGE:: USAGE( exit-code ) - Usage invocation macro +* VALUE_OPT_name:: VALUE_OPT_name - Option Flag Value +* VERSION:: VERSION - Version and Full Version +* WHICH_IDX_name:: WHICH_IDX_name - Which Equivalenced Index +* WHICH_OPT_name:: WHICH_OPT_name - Which Equivalenced Option +* teOptIndex:: teOptIndex - Option Index and Enumeration +* OPTIONS_STRUCT_VERSION:: OPTIONS_STRUCT_VERSION - active version +* libopts procedures:: libopts External Procedures +@end menu + +@node Option Processing Data +@subsection Data for Option Processing +@cindex Option Processing Data + +This section describes the data that may be accessed from within the +option processing callback routines. The following fields may be used +in the following ways and may be used for read only. The first set is +addressed from the @code{tOptDesc*} pointer: + +@table @samp +@cindex optIndex +@item optIndex +@cindex optValue +@item optValue +These may be used by option procedures to determine which option they +are working on (in case they handle several options). + +@cindex optActualIndex +@item optActualIndex +@cindex optActualValue +@item optActualValue +These may be used by option procedures to determine which option was +used to set the current option. This may be different from the above if +the options are members of an equivalence class. + +@cindex optOccCt +@item optOccCt +If AutoOpts is processing command line arguments, then this value will contain +the current occurrence count. During the option preset phase (reading +configuration files and examining environment variables), the value is zero. + +@cindex fOptState +@item fOptState +The field may be tested for the following bit values +(prefix each name with @code{OPTST_}, e.g. @code{OPTST_INIT}): + +@table @samp +@item INIT +Initial compiled value. As a bit test, it will always yield FALSE. + +@item SET +The option was set via the @code{SET_OPT()} macro. + +@item PRESET +@cindex configuration file +The option was set via a configuration file. + +@item DEFINED +The option was set via a command line option. + +@item SET_MASK +This is a mask of flags that show the set state, one of the +above four values. + +@item EQUIVALENCE +This bit is set when the option was selected by an equivalenced option. + +@item DISABLED +This bit is set if the option is to be disabled. +(Meaning it was a long option prefixed by the disablement prefix, or +the option has not been specified yet and initializes as @code{disabled}.) +@end table + +As an example of how this might be used, in AutoGen I want to allow +template writers to specify that the template output can be left +in a writable or read-only state. To support this, there is a Guile +function named @code{set-writable} (@pxref{SCM set-writable}). +Also, I provide for command options @option{--writable} and +@option{--not-writable}. I give precedence to command line and RC +file options, thus: + +@example +switch (STATE_OPT( WRITABLE )) @{ +case OPTST_DEFINED: +case OPTST_PRESET: + fprintf(stderr, zOverrideWarn, pCurTemplate->pzFileName, + pCurMacro->lineNo); + break; + +default: + if (gh_boolean_p( set ) && (set == SCM_BOOL_F)) + CLEAR_OPT( WRITABLE ); + else + SET_OPT_WRITABLE; +@} +@end example + +@cindex pzLastArg +@item pzLastArg +Pointer to the latest argument string. BEWARE@: If the argument type +is numeric, an enumeration or a bit mask, then this will be the +argument @strong{value} and not a pointer to a string. +@end table + +The following two fields are addressed from the @code{tOptions*} pointer: + +@table @samp +@cindex pzProgName +@item pzProgName +Points to a NUL-terminated string containing the current program +name, as retrieved from the argument vector. + +@cindex pzProgPath +@item pzProgPath +Points to a NUL-terminated string containing the full path of +the current program, as retrieved from the argument vector. +(If available on your system.) + +@end table + +Note@: these fields get filled in during the first call to +@code{optionProcess()}. All other fields are private, for the exclusive +use of AutoOpts code and are subject to change. + +@node CLEAR_OPT +@subsection CLEAR_OPT( <NAME> ) - Clear Option Markings +@findex CLEAR_OPT + +Make as if the option had never been specified. +@code{HAVE_OPT(<NAME>)} will yield @code{FALSE} +after invoking this macro. + +@node COUNT_OPT +@subsection COUNT_OPT( <NAME> ) - Definition Count +@findex COUNT_OPT + +This macro will tell you how many times the option was +specified on the command line. It does not include counts +of preset options. + +@example +if (COUNT_OPT( NAME ) != desired-count) @{ + make-an-undesirable-message. +@} +@end example + +@node DESC +@subsection DESC( <NAME> ) - Option Descriptor +@findex DESC + +This macro is used internally by other AutoOpt macros. +It is not for general use. It is used to obtain the option description +corresponding to its @strong{UPPER CASED} option name argument. +This is primarily used in other macro definitions. + +@node DISABLE_OPT_name +@subsection DISABLE_OPT_name - Disable an option +@findex DISABLE_OPT_name + +This macro is emitted if it is both settable +and it can be disabled. If it cannot be disabled, it may +always be CLEAR-ed (see above). + +The form of the macro will actually depend on whether the +option is equivalenced to another, and/or has an assigned +handler procedure. Unlike the @code{SET_OPT} macro, +this macro does not allow an option argument. + +@example +DISABLE_OPT_NAME; +@end example + +@node ENABLED_OPT +@subsection ENABLED_OPT( <NAME> ) - Is Option Enabled? +@findex ENABLED_OPT + +Yields true if the option defaults to disabled and +@code{ISUNUSED_OPT()} would yield true. It also yields true if +the option has been specified with a disablement prefix, +disablement value or the @code{DISABLE_OPT_NAME} macro was invoked. + +@node ERRSKIP_OPTERR +@subsection ERRSKIP_OPTERR - Ignore Option Errors +@findex ERRSKIP_OPTERR + +When it is necessary to continue (return to caller) +on option errors, invoke this option. It is reversible. +@xref{ERRSTOP_OPTERR}. + +@node ERRSTOP_OPTERR +@subsection ERRSTOP_OPTERR - Stop on Errors +@findex ERRSTOP_OPTERR + +After invoking this macro, if @code{optionProcess()} +encounters an error, it will call @code{exit(1)} rather than return. +This is the default processing mode. It can be overridden by +specifying @code{allow-errors} in the definitions file, +or invoking the macro @xref{ERRSKIP_OPTERR}. + +@node HAVE_OPT +@subsection HAVE_OPT( <NAME> ) - Have this option? +@findex HAVE_OPT + +This macro yields true if the option has been specified +in any fashion at all. It is used thus: + +@example +if (HAVE_OPT( NAME )) @{ + <do-things-associated-with-opt-name>; +@} +@end example + +@node ISSEL_OPT +@subsection ISSEL_OPT( <NAME> ) - Is Option Selected? +@findex ISSEL_OPT + +This macro yields true if the option has been +specified either on the command line or via a SET/DISABLE macro. + +@node ISUNUSED_OPT +@subsection ISUNUSED_OPT( <NAME> ) - Never Specified? +@findex ISUNUSED_OPT + +This macro yields true if the option has +never been specified, or has been cleared via the +@code{CLEAR_OPT()} macro. + +@node OPTION_CT +@subsection OPTION_CT - Full Count of Options +@findex OPTION_CT + +The full count of all options, both those defined +and those generated automatically by AutoOpts. This is primarily +used to initialize the program option descriptor structure. + +@node OPT_ARG +@subsection OPT_ARG( <NAME> ) - Option Argument String +@findex OPT_ARG + +The option argument value as a pointer to string. Note that argument +values that have been specified as numbers are stored as numbers or +keywords. For such options, use instead the @code{OPT_VALUE_name} +define. It is used thus: + +@example +if (HAVE_OPT( NAME )) @{ + char* p = OPT_ARG( NAME ); + <do-things-with-opt-name-argument-string>; +@} +@end example + +@node OPT_NO_XLAT_CFG_NAMES +@subsection OPT_NO_XLAT_CFG_NAMES - option name xlation +@findex OPT_NO_XLAT_CFG_NAMES + +Invoking this macro will disable the translation of option names only while +processing configuration files and environment variables. This must be +invoked before the first call to @code{optionProcess}.. You need not invoke +this if your option definition file contains the attribute assignment, +@code{no-xlate = opt-cfg;}. + +@node OPT_NO_XLAT_OPT_NAMES +@subsection OPT_NO_XLAT_OPT_NAMES - option name xlation +@findex OPT_NO_XLAT_OPT_NAMES + +Invoking this macro will completely disable the translation of option names. +This must be invoked before the first call to @code{optionProcess}. You need +not invoke this if your option definition file contains the attribute +assignment, @code{no-xlate = opt;}. + +@node OPT_VALUE_name +@subsection OPT_VALUE_name - Option Argument Value +@findex OPT_VALUE_name + +This macro gets emitted only for options that take numeric, keyword or set +membership arguments. The macro yields a word-sized integer containing the +enumeration, bit set or numeric value for the option argument. + +@example +int opt_val = OPT_VALUE_name; +@end example + +@node OPT_XLAT_CFG_NAMES +@subsection OPT_XLAT_CFG_NAMES - option name xlation +@findex OPT_XLAT_CFG_NAMES + +If @code{ENABLE_NLS} is defined and @code{no-xlate} has been not set to the +value @emph{anything}, this macro will cause the translation of option names +to happen before starting the processing of configuration files and +environment variables. This will change the recognition of options within the +@code{$PROGRAMNAME} environment variable, but will not alter the names used +for setting options via @code{$PROGRAMNAME_name} environment variables. + +This must be invoked before the first call to @code{optionProcess}. You might +need to use this macro if your option definition file contains the attribute +assignment, @code{no-xlate = opt;} or @code{no-xlate = opt-cfg;}, and +you have determined in some way that you wish to override that. + +@node OPT_XLAT_OPT_NAMES +@subsection OPT_XLAT_OPT_NAMES - option name xlation +@findex OPT_XLAT_OPT_NAMES + +If @code{ENABLE_NLS} is defined and @code{no-xlate} has been not set to the +value @emph{anything}, translate the option names before processing the +command line options. Long option names may thus be localized. (If the names +were translated before configuration processing, they will not be +re-translated.) + +This must be invoked before the first call to @code{optionProcess}. You might +need to use this macro if your option definition file contains the attribute +assignment, @code{no-xlate = opt;} and you have determined in some way that +you wish to override that. + +@node RESTART_OPT +@subsection RESTART_OPT( n ) - Resume Option Processing +@findex RESTART_OPT + +If option processing has stopped (either because of an error +or something was encountered that looked like a program argument), +it can be resumed by providing this macro with the index @code{n} +of the next option to process and calling @code{optionProcess()} again. + +@example +int main(int argc, char ** argv) @{ + for (int ai = 0; ai < argc ;) @{ + restart: + ai = optionProcess(&progOptions, argc, argv); + for (; ai < argc; ai++) @{ + char * arg = arg[ai]; + if (*arg == '-') @{ + RESTART_OPT(ai); + goto restart; + @} + process(arg); + @} + @} +@} +@end example + +If you want a program to operate this way, you might consider specifying a +@code{for-each} main function +(@pxref{main for-each, for-each main procedure}) with the @code{interleaved} +attribute. It will allow you to process interleaved operands and options from +either the command line or when reading them from standard input. + +@node SET_OPT_name +@subsection SET_OPT_name - Force an option to be set +@findex SET_OPT_name + +This macro gets emitted only when the given +option has the @code{settable} attribute specified. + +The form of the macro will actually depend on whether the option is +equivalenced to another, has an option argument and/or has an assigned +handler procedure. If the option has an argument, then this macro will +too. Beware that the argument is not reallocated, so the value must not +be on the stack or deallocated in any other way for as long as the value +might get referenced. + +If you have supplied at least one @file{homerc} file +(@pxref{program attributes}), this macro will be emitted for the +@option{--save-opts} option. + +@example +SET_OPT_SAVE_OPTS( "filename" ); +@end example + +@noindent +@xref{automatic options}, for a discussion of the implications of using +this particular example. + +@node STACKCT_OPT +@subsection STACKCT_OPT( <NAME> ) - Stacked Arg Count +@findex STACKCT_OPT + +When the option handling attribute is specified +as @code{stack_arg}, this macro may be used to determine how +many of them actually got stacked. + +Do not use this on options that have not been stacked or has not been +specified (the @code{stack_arg} attribute must have been specified, +and @code{HAVE_OPT(<NAME>)} must yield TRUE). +Otherwise, you will likely seg fault. + +@example +if (HAVE_OPT( NAME )) @{ + int ct = STACKCT_OPT( NAME ); + char** pp = STACKLST_OPT( NAME ); + + do @{ + char* p = *pp++; + do-things-with-p; + @} while (--ct > 0); +@} +@end example + +@node STACKLST_OPT +@subsection STACKLST_OPT( <NAME> ) - Argument Stack +@findex STACKLST_OPT + +The address of the list of pointers to the +option arguments. The pointers are ordered by the order in +which they were encountered in the option presets and +command line processing. + +Do not use this on options that have not been stacked or has not been +specified (the @code{stack_arg} attribute must have been specified, +and @code{HAVE_OPT(<OPTION>)} must yield TRUE). +Otherwise, you will likely seg fault. + +@example +if (HAVE_OPT( NAME )) @{ + int ct = STACKCT_OPT( NAME ); + char** pp = STACKLST_OPT( NAME ); + + do @{ + char* p = *pp++; + do-things-with-p; + @} while (--ct > 0); +@} +@end example + +@node START_OPT +@subsection START_OPT - Restart Option Processing +@findex START_OPT + +This is just a shortcut for RESTART_OPT(1) (@xref{RESTART_OPT}.) + +@node STATE_OPT +@subsection STATE_OPT( <NAME> ) - Option State +@findex STATE_OPT + +If you need to know if an option was set because of presetting actions +(configuration file processing or environment variables), versus a command +line entry versus one of the SET/DISABLE macros, then use this macro. It +will yield one of four values: @code{OPTST_INIT}, @code{OPTST_SET}, +@code{OPTST_PRESET} or @code{OPTST_DEFINED}. It is used thus: + +@example +switch (STATE_OPT( NAME )) @{ + case OPTST_INIT: + not-preset, set or on the command line. (unless CLEAR-ed) + + case OPTST_SET: + option set via the SET_OPT_NAME() macro. + + case OPTST_PRESET: + option set via an configuration file or environment variable + + case OPTST_DEFINED: + option set via a command line option. + + default: + cannot happen :) +@} +@end example + +@node USAGE +@subsection USAGE( exit-code ) - Usage invocation macro +@findex USAGE + +This macro invokes the procedure registered to display +the usage text. Normally, this will be @code{optionUsage} from the +AutoOpts library, but you may select another procedure by specifying +@code{usage = "proc_name"} program attribute. This procedure must +take two arguments@: first, a pointer to the option descriptor, and +second the exit code. The macro supplies the option descriptor +automatically. This routine is expected to call @code{exit(3)} with +the provided exit code. + +The @code{optionUsage} routine also behaves differently depending +on the exit code: + +@table @code +@item EXIT_SUCCESS (the value zero) +It is assumed that full usage help has been requested. Consequently, more +information is provided than when displaying usage and exiting with a +non-zero exit code. Output will be sent to @file{stdout} and the program will +exit with a zero status code. + +@item EX_USAGE (64) +The abbreviated usage will be printed to @file{stdout} and the program will +exit with a zero status code. @code{EX_USAGE} may or may not be 64. If your +system provides @file{/usr/include/sysexits.h} that has a different value, +then that value will be used. + +@item any other value +The abbreviated usage will be printed to stderr and the program will +exit with the provided status code. +@end table + +@node VALUE_OPT_name +@subsection VALUE_OPT_name - Option Flag Value +@findex VALUE_OPT_name + +This is a #define for the flag character used to +specify an option on the command line. If @code{value} was not +specified for the option, then it is a unique number associated +with the option. @code{option value} refers to this value, +@code{option argument} refers to the (optional) argument to the +option. + +@example +switch (WHICH_OPT_OTHER_OPT) @{ +case VALUE_OPT_NAME: + this-option-was-really-opt-name; +case VALUE_OPT_OTHER_OPT: + this-option-was-really-other-opt; +@} +@end example + +@node VERSION +@subsection VERSION - Version and Full Version +@findex VERSION + +If the @code{version} attribute is defined for the program, +then a stringified version will be #defined as PROGRAM_VERSION and +PROGRAM_FULL_VERSION. PROGRAM_FULL_VERSION is used for printing +the program version in response to the version option. The version +option is automatically supplied in response to this attribute, too. + +You may access PROGRAM_VERSION via @code{programOptions.pzFullVersion}. + +@node WHICH_IDX_name +@subsection WHICH_IDX_name - Which Equivalenced Index +@findex WHICH_IDX_name + +This macro gets emitted only for equivalenced-to options. It is used to +obtain the index for the one of the several equivalence class members +set the equivalenced-to option. + +@example +switch (WHICH_IDX_OTHER_OPT) @{ +case INDEX_OPT_NAME: + this-option-was-really-opt-name; +case INDEX_OPT_OTHER_OPT: + this-option-was-really-other-opt; +@} +@end example + +@node WHICH_OPT_name +@subsection WHICH_OPT_name - Which Equivalenced Option +@findex WHICH_OPT_name + +This macro gets emitted only for equivalenced-to options. It is used to +obtain the value code for the one of the several equivalence class members +set the equivalenced-to option. + +@example +switch (WHICH_OPT_OTHER_OPT) @{ +case VALUE_OPT_NAME: + this-option-was-really-opt-name; +case VALUE_OPT_OTHER_OPT: + this-option-was-really-other-opt; +@} +@end example + +@node teOptIndex +@subsection teOptIndex - Option Index and Enumeration +@findex teOptIndex + +This enum defines the complete set of options, both +user specified and automatically provided. This can be used, +for example, to distinguish which of the equivalenced options +was actually used. + +@example +switch (pOptDesc->optActualIndex) @{ +case INDEX_OPT_FIRST: + stuff; +case INDEX_OPT_DIFFERENT: + different-stuff; +default: + unknown-things; +@} +@end example + +@node OPTIONS_STRUCT_VERSION +@subsection OPTIONS_STRUCT_VERSION - active version + +You will not actually need to reference this value, but you need to be +aware that it is there. It is the first value in the option descriptor +that you pass to @code{optionProcess}. It contains a magic number and +version information. Normally, you should be able to work with a more +recent option library than the one you compiled with. However, if the +library is changed incompatibly, then the library will detect the out of +date magic marker, explain the difficulty and exit. You will then need +to rebuild and recompile your option definitions. This has rarely been +necessary. + +@ignore +END == AUTOOPTS-API == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@ignore +START == AUTOOPTS-DATA == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@c === SECTION MARKER + +@node Multi-Threading +@section Multi-Threading + +AutoOpts was designed to configure a program for running. This generally +happens before much real work has been started. Consequently, it is +expected to be run before multi-threaded applications have started multiple +threads. However, this is not always the case. Some applications may +need to reset and reload their running configuration, and some may use +@code{SET_OPT_xxx()} macros during processing. If you need to dynamically +change your option configuration in your multi-threaded application, it is +your responsibility to prevent all threads from accessing the option +configuration state, except the one altering the configuration. + +The various accessor macros (@code{HAVE_OPT()}, etc.) do not modify state +and are safe to use in a multi-threaded application. It is safe as long +as no other thread is concurrently modifying state, of course. + +@c === SECTION MARKER + +@node option descriptor +@section Option Descriptor File +@cindex option descriptor + +This is the module that is to be compiled and linked with your program. +It contains internal data and procedures subject to change. Basically, +it contains a single global data structure containing all the +information provided in the option definitions, plus a number of static +strings and any callout procedures that are specified or required. You +should never have need for looking at this, except, perhaps, to examine +the code generated for implementing the @code{flag-code} construct. + +@c === SECTION MARKER + +@node Using AutoOpts +@section Using AutoOpts +@cindex using AutoOpts + +There are actually several levels of @code{using} autoopts. +Which you choose depends upon how you plan to distribute +(or not) your application. + +@menu +* local use:: local-only use +* binary not installed:: binary distro, AutoOpts not installed +* binary pre-installed:: binary distro, AutoOpts pre-installed +* source pre-installed:: source distro, AutoOpts pre-installed +* source not installed:: source distro, AutoOpts not installed +@end menu + +@node local use +@subsection local-only use + +To use AutoOpts in your application where you do not have to +worry about distribution issues, your issues are simple and few. + +@itemize @bullet +@item +Create a file @samp{myopts.def}, according to the documentation above. +It is probably easiest to start with the example in @ref{Quick Start} +and edit it into the form you need. + +@item +Run AutoGen to create the option interface file (@code{myopts.h}) +and the option descriptor code (@code{myopts.c}): + +@example +autogen myopts.def +@end example + +@item +In all your source files where you need to refer to option state, +@code{#include "myopts.h"}. +@item +In your main routine, code something along the lines of: + +@example +#define ARGC_MIN some-lower-limit +#define ARGC_MAX some-upper-limit +main( int argc, char** argv ) +@{ + @{ + int arg_ct = optionProcess( &myprogOptions, argc, argv ); + argc -= arg_ct; + if ((argc < ARGC_MIN) || (argc > ARGC_MAX)) @{ + fprintf( stderr, "%s ERROR: remaining args (%d) " + "out of range\n", myprogOptions.pzProgName, + argc ); + + USAGE( EXIT_FAILURE ); + @} + argv += arg_ct; + @} + if (HAVE_OPT(OPTN_NAME)) + respond_to_optn_name(); + ... +@} +@end example + +@item +Compile @samp{myopts.c} and link your program +with the following additional arguments: + +@example +`autoopts-config cflags ldflags` myopts.c +@end example +@end itemize + +@node binary not installed +@subsection binary distro, AutoOpts not installed + +If you will be distributing (or copying) your project to a system that +does not have AutoOpts installed, you will need to statically link the +AutoOpts library, @code{libopts} into your program. Get the link information +with @code{static-libs} instead of @code{ldflags}: + +@example +`autoopts-config static-libs` +@end example + +@node binary pre-installed +@subsection binary distro, AutoOpts pre-installed + +If you will be distributing (or copying) your project to a system that does +have AutoOpts (or only @code{libopts}) installed, you will still need to +ensure that the library is findable at program load time, or you will still +have to statically link. The former can be accomplished by linking your +project with @option{--rpath} or by setting the @env{LD_LIBRARY_PATH} +appropriately. Otherwise, @xref{binary not installed}. + +@node source pre-installed +@subsection source distro, AutoOpts pre-installed + +If you will be distributing your project to a system that will build +your product but it may not be pre-installed with AutoOpts, you will +need to do some configuration checking before you start the build. +Assuming you are willing to fail the build if AutoOpts has not been +installed, you will still need to do a little work. + +AutoOpts is distributed with a configuration check M4 script, +@file{autoopts.m4}. It will add an @code{autoconf} macro named, +@code{AG_PATH_AUTOOPTS}. Add this to your @file{configure.ac} script +and use the following substitution values: + +@table @code +@item AUTOGEN +the name of the autogen executable +@item AUTOGEN_TPLIB +the directory where AutoGen template library is stored +@item AUTOOPTS_CFLAGS +the compile time options needed to find the AutoOpts headers +@item AUTOOPTS_LIBS +the link options required to access the @code{libopts} library +@end table + +@node source not installed +@subsection source distro, AutoOpts not installed + +If you will be distributing your project to a system that will build +your product but it may not be pre-installed with AutoOpts, you may +wish to incorporate the sources for @code{libopts} in your project. +To do this, I recommend reading the tear-off libopts library +@file{README} that you can find in the @file{pkg/libopts} directory. +You can also examine an example package (blocksort) that incorporates +this tear off library in the autogen distribution directory. There is +also a web page that describes what you need to do: +@example +@url{http://autogen.sourceforge.net/blocksort.html} +@end example + +Alternatively, you can pull the @code{libopts} library sources into +a build directory and build it for installation along with your package. +This can be done approximately as follows: +@example +tar -xzvf `autoopts-config libsrc` +cd libopts-* +./bootstrap +configure +make +make install +@end example +That will install the library, but not the headers or anything else. + +@c === SECTION MARKER + +@node Presetting Options +@section Configuring your program +@cindex shell options + +AutoOpts supports the notion of @code{presetting} the value or state of an +option. The values may be obtained either from environment variables or from +configuration files (@file{rc} or @file{ini} files). In order to take +advantage of this, the AutoOpts client program must specify these features in +the option descriptor file (@pxref{program attributes}) with the @code{rcfile} +or @code{environrc} attributes. + +@menu +* loading rcfile:: configuration file presets +* saving rcfile:: Saving the presets into a configuration file +* sample rcfile:: Creating a sample configuration file +* environrc:: environment variable presets +* config example:: Config file only example +@end menu + +It is also possible to configure your program @i{without} using +the command line option parsing code. This is done by using +only the following four functions from the @file{libopts} library: + +@table @samp +@item configFileLoad +(@pxref{libopts-configFileLoad}) will parse the contents of a config +file and return a pointer to a structure representing the hierarchical +value. The values are sorted alphabetically by the value name and all +entries with the same name will retain their original order. +Insertion sort is used. + +@item optionGetValue +(@pxref{libopts-optionGetValue}) will find the first value within the +hierarchy with a name that matches the name passed in. + +@item optionNextValue +(@pxref{libopts-optionNextValue}) will return the next value that +follows the value passed in as an argument. If you wish to get all +the values for a particular name, you must take note when the name +changes. + +@item optionUnloadNested +(@pxref{libopts-optionUnloadNested}). The pointer passed in must be +of type, @code{OPARG_TYPE_HIERARCHY} (see the autoopts/options.h +header file). @code{configFileLoad} will return a @code{tOptionValue} +pointer of that type. This function will release all the associated +memory. @code{AutoOpts} generated code uses this function for its own +needs. Client code should only call this function with pointers +gotten from @code{configFileLoad}. +@end table + +@node loading rcfile +@subsection configuration file presets +@cindex rcfile + +Configuration files are enabled by specifying the program attribute +@code{homerc} (@pxref{program attributes}). Any option not marked +with the @code{no-preset} attribute may appear in a configuration file. +The files loaded are selected both by the @code{homerc} entries and, +optionally, via a command line option. The first component of the +@code{homerc} entry may be an environment variable such as @env{$HOME}, or +it may also be @samp{$$} (@strong{two} dollar sign characters) to specify +the directory of the executable. For example: + +@example +homerc = "$$/../share/autogen"; +@end example + +@noindent +will cause the AutoOpts library to look in the normal autogen datadir +relative to the current installation directory for autogen. + +The configuration files are processed in the order they are specified by +the @code{homerc} attribute, so that each new file will normally override +the settings of the previous files. This may be overridden by marking some +options for @code{immediate action} (@pxref{Immediate Action}). Any such +options are acted upon in @strong{reverse} order. The disabled +@code{load-opts} (@option{--no-load-opts}) option, for example, is an +immediate action option. Its presence in the last @code{homerc} file will +prevent the processing of any prior @code{homerc} files because its effect +is immediate. + +Configuration file processing can be completely suppressed by specifying +@option{--no-load-opts} on the command line, or @code{PROGRAM_LOAD_OPTS=no} in +the environment (if @code{environrc} has been specified). + +See the @code{Configuration File Format} section (@pxref{Config File Format}) +for details on the format of the file. + +@node saving rcfile +@subsection Saving the presets into a configuration file + +When configuration files are enabled for an application, the user is +also provided with an automatically supplied @option{--save-opts} option. +All of the known option state will be written to either the specified +output file or, if it is not specified, then to the last specified +@code{homerc} file. + +@node sample rcfile +@subsection Creating a sample configuration file +@cindex sample rcfile + +AutoOpts is shipped with a template named, @file{rc-sample.tpl}. +If your option definition file specifies the @code{homerc} attribute, +then you may invoke @file{autogen} thus: + +@example +autogen -Trc-sample <your-option-def-file> +@end example + +This will, by default, produce a sample file named, +@file{sample-<prog-name>rc}. It will be named differently if you specify your +configuration (rc) file name with the @code{rcfile} attribute. In that case, +the output file will be named, @file{sample-<rcfile-name>}. It will contain +all of the program options not marked as @code{no-preset}. It will also +include the text from the @code{doc} attribute. + +@ignore +END == AUTOOPTS-DATA == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@ignore +START == AO-DATA1 == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@node environrc +@subsection environment variable presets +@cindex environrc + +If the AutoOpts client program specifies @code{environrc} in its +option descriptor file, then environment variables will be used for +presetting option state. Variables will be looked for that are named, +@env{PROGRAM_OPTNAME} and @env{PROGRAM}. @env{PROGRAM} is the +upper cased @code{C-name} of the program, and @var{OPTNAME} is the +upper cased @code{C-name} of a specific option. (The @code{C-name}s +are the regular names with all special characters converted to +underscores (@code{_}).) + +Option specific environment variables are processed after (and thus +take precedence over) the contents of the @env{PROGRAM} environment +variable. The option argument string for these options takes on the +string value gotten from the environment. Consequently, you can only +have one instance of the @var{OPTNAME}. + +If a particular option may be disabled, then its disabled state is +indicated by setting the @env{PROGRAM_OPTNAME} value to the +disablement prefix. So, for example, if the disablement prefix were +@code{dont}, then you can disable the @code{optname} option by setting +the @env{PROGRAM_OPTNAME}' environment variable to @code{@i{dont}}. +@xref{Common Attributes}. + +The @env{PROGRAM} environment string is tokenized and parsed much +like a command line. Doubly quoted strings have backslash escapes +processed the same way they are processed in C program constant +strings. Singly quoted strings are pretty raw in that backslashes are +honored before other backslashes, apostrophes, newlines and cr/newline +pairs. The options must be introduced with hyphens in the same way as +the command line. + +Note that not all options may be preset. Options that are specified with the +@code{no-preset} attribute and the @option{--help}, @option{--more-help}, +and @option{--save-opts} auto-supported options may not be preset. + +@node config example +@subsection Config file only example +@cindex rcfile +@cindex Configuration File +@cindex Configuration File example + +If for some reason it is difficult or unworkable to integrate configuration +file processing with command line option parsing, the @code{libopts} +(@pxref{libopts procedures}) library can still be used to process +configuration files. Below is a @t{Hello, World!} greeting program that tries +to load a configuration file @file{hello.conf} to see if it should use an +alternate greeting or to personalize the salutation. +@ignore +END == AO-DATA1 == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@ignore +START == AO-DATA2 == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@c === SECTION MARKER + +@node Config File Format +@section Configuration File Format +@cindex Configuration File + +The configuration file is designed to associate names and values, much like +an AutoGen Definition File (@pxref{Definitions File}). Unfortunately, the +file formats are different. Specifically, AutoGen Definitions provide for +simpler methods for the precise control of a value string and provides for +dynamically computed content. Configuration files have some established +traditions in their layout. So, they are different, even though they do +both allow for a single name to be associated with multiple values and they +both allow for hierarchical values. + +@menu +* config name/string-value:: assigning a string value to a configurable +* config integer-values:: integer values +* config nested-values:: hierarchical values +* config directives:: configuration file directives +* config comments:: comments in the configuration file +@end menu + +@node config name/string-value +@subsection assigning a string value to a configurable + +The basic syntax is a name followed by a value on a single line. They are +separated from each other by either white space, a colon (@code{:}) or an +equal sign (@code{=}). The colon or equal sign may optionally be surrounded +by additional white space. If more than one value line is needed, a +backslash (@code{\}) may be used to continue the value. The backslash (but +not the newline) will be erased. Leading and trailing white space is always +stripped from the value. + +Fundamentally, it looks like this: + +@example +name value for that name +name = another \ + multi-line value \ + for that name. +name: a *third* value for @code{name} +@end example + +If you need more control over the content of the value, you may enclose the +value in XML style brackets: +@example +<name>value </name> +@end example +@noindent +Within these brackets you need not (must not) continue the value data with +backslashes. You may also select the string formation rules to use, just +add the attribute after the name, thus: @code{<name keep>}. + +@table @samp +@item keep +This mode will keep all text between the brackets and not strip any +white space. +@item uncooked +This mode strips leading and trailing white space, but not do any +quote processing. This is the default and need not be specified. +@item cooked +The text is trimmed of leading and trailing white space and XML encodings +are processed. These encodings are slightly expanded over the XML +specification. They are specified with an ampersand followed by a value +name or numeric value and then a semicolon: + +@table @samp +@item amp +@itemx lt +@itemx gt +@itemx quot +@itemx apos +@itemx #dd +@itemx #xHH + +These are all per fairly standad HTML and/or XML encodings. +Additionally: + +@item bs +The ASCII back space character. +@item ff +The ASCII form feed character. +@item ht +The ASCII horizontal (normal) tab character. +@item cr +The ASCII carriage return character. +@item vt +The ASCII vertical tab character. +@item bel +The ASCII alarm bell character. +@item nl +The ASCII new line character. +@item space +The ASCII space character. Normally not necessary, but if you want +to preserve leading or trailing space characters, then use this. +@end table +@end table + +And here is an example of an XML-styled value: + +@example +<name cooked> + This is&nl;&ht;another multi-line +&ht;string example. +</name> +@end example + +The string value associated with @code{name} will be exactly the text enclosed +in quotes with the encoded characters @code{cooked} as you would expect (three +text lines with the last line not ending with a newline, but ending with a +period). + +@node config integer-values +@subsection integer values + +A name can be specified as having an integer value. To do this, you +must use the XML-ish format and specify a @code{type} attribute for +the name: + +@example +<name type=integer> 1234 </name> +@end example + +Boolean, enumeration and set membership types will be added as time +allows. @code{type=string} is also supported, but also is the default. + +@node config nested-values +@subsection hierarchical values + +In order to specify a hierarchical value, you *must* use XML-styled +formatting, specifying a type that is shorter and easier to spell: + +@example +<structured-name type=nested> + [[....]] +</structured-name> +@end example + +@noindent +The ellipsis may be filled with any legal configuration file name/value +assignments. + +@node config directives +@subsection configuration file directives +@cindex autoopts directives + +The @code{<?} marker indicates an XML directive. +There is only one directive supported: program sectioning, +though two syntaxes are supported. + +If, for example, you have a collection of programs that work closely +together and, likely, have a common set of options, these programs may use a +single, sectioned, configuration file. The file may be sectioned in either +of two ways. The two ways may not be intermixed in a single configuration +file. All text before the first segmentation line is processed, then only +the segment that applies: + +@table @samp +@item <?auto-options ...> +The @code{...} ellipsis may contain AutoOpts option processing options. +Currently, that consists of one or both of: + +@table @code +@item gnu +@itemx autoopts +to indicate GNU-standard or AutoOpts-standard layout of usage and +version information, and/or + +@item misuse-usage +@itemx no-misuse-usage +to indicate whether the available options should be listed when +an invalid option appears on the command line. +@end table +@noindent +Anything else will be silently ignored. + +@item <?program prog-name> +The @code{<?} marker indicates an XML directive. +The file is partitioned by these lines and the options are processed +for the @code{prog-name} program only before the first @code{<?program} +directive and the program section with a matching program name. + +@item [PROG_NAME] +This is basically an alias for @code{<?program prog-name>}, except that +the program name must be upper cased and segmented only with underscores +and it is @strong{not} recognized as a program segment when updating +configuration files with the @code{--save-opts} option. In other words, +use this only for Windows compatibility. +@end table + +@noindent +Segmentation does not apply if the config file is being parsed with +the @code{configFileLoad(3AutoOpts)} function. + +@node config comments +@subsection comments in the configuration file + +Comments are lines beginning with a hash mark (@code{#}), +XML-style comments (@code{<!-- arbitrary text -->}), and +unrecognized XML directives. + +@example +# this is a comment +<!-- this is also + a comment --> +<?this is + a bad comment ;-> +@end example + +@c === SECTION MARKER + +@node shell options +@section AutoOpts for Shell Scripts +@cindex shell options +@cindex configuration file + +AutoOpts may be used with shell scripts either by automatically creating a +complete program that will process command line options and pass back +the results to the invoking shell by issuing shell variable assignment +commands, or it may be used to generate portable shell code that can +be inserted into your script. + +The functionality of these features, of course, is somewhat constrained +compared with the normal program facilities. Specifically, you cannot +invoke callout procedures with either of these methods. Additionally, +if you generate a shell script to do the parsing: + +@enumerate +@item +You cannot obtain options from configuration files. +@item +You cannot obtain options from environment variables. +@item +You cannot save the option state to an option file. +@item +Option conflict/requirement verification is disabled. +@end enumerate + +Both of these methods are enabled by running AutoGen on +the definitions file with the additional main procedure attribute: + +@example +main = @{ main-type = shell-process; @}; +@end example +@noindent +or: +@example +main = @{ main-type = shell-parser; @}; +@end example + +If you do not supply a @code{proc-to-call}, it will default to +@code{optionPutShell}. That will produce a program that will process the +options and generate shell text for the invoking shell to interpret +(@pxref{binary-parser}). If you supply the name, @code{optionParseShell}, +then you will have a program that will generate a shell script that can parse +the options (@pxref{script-parser}). If you supply a different procedure +name, you will have to provide that routine and it may do whatever you like. + +@menu +* binary-parser:: Parsing with an Executable +* script-parser:: Parsing with a Portable Script +@end menu + +@node binary-parser +@subsection Parsing with an Executable + +The following commands are approximately all that is needed +to build a shell script command line option parser from +an option definition file: + +@example +autogen -L <opt-template-dir> test-errors.def +cc -o test-errors -L <opt-lib-dir> -I <opt-include-dir> \ + -DTEST_PROGRAM_OPTS test-errors.c -lopts +@end example + +The resulting program can then be used within your shell script as follows: + +@example +eval `./test-errors "$@@"` +if [ -z "$@{OPTION_CT@}" ] ; then exit 1 ; fi +test $@{OPTION_CT@} -gt 0 && shift $@{OPTION_CT@} +@end example +@ignore +END == AO-DATA2 == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@ignore +START == AUTOINFO == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@c === SECTION MARKER + +@node AutoInfo +@section Automated Info Docs +@cindex AutoInfo + +AutoOpts provides two templates for producing @file{.texi} documentation. +@file{agtexi-cmd.tpl} for the invoking section, and @file{aginfo3.tpl} for +describing exported library functions and macros. + +For both types of documents, the documentation level is selected by +passing a @samp{-DLEVEL=<level-name>} argument to AutoGen when you build +the document. (See the example invocation below.) + +Two files will be produced, a @file{.texi} file and a @file{.menu} file. +You should include the text in the @file{.menu} file in a @file{@@menu} +list, either with @file{@@include}-ing it or just copying text. +The @file{.texi} file should be @file{@@include}-ed where the invoking +section belongs in your document. + +The @file{.texi} file will contain an introductory paragraph, a menu +and a subordinate section for the invocation usage and for each +documented option. The introductory paragraph is normally the boiler +plate text, along the lines of: + +@example +This chapter documents the @@file@{AutoOpts@} generated usage text +and option meanings for the @@file@{your-program@} program. +@end example + +@noindent +or: + +@example +These are the publicly exported procedures from the lib@i{name} library. +Any other functions mentioned in the @i{header} file are for the private use +of the library. +@end example + +@menu +* command-info:: @code{invoking} info docs +* library-info:: library info docs +@end menu + +@node command-info +@subsection @code{invoking} info docs + +Using the option definitions for an AutoOpt client program, the +@file{agtexi-cmd.tpl} template will produce texinfo text that documents the +invocation of your program. The text emitted is designed to be included +in the full texinfo document for your product. It is not a stand-alone +document. The usage text for the @ref{autogen usage}, +@ref{getdefs usage} and @ref{columns usage} programs, are included in +this document and are all generated using this template. + +If your program's option definitions include a +@samp{prog-info-descrip} section, then that text will replace the +boilerplate introductory paragraph. + +@noindent +These files are produced by invoking the following command: + +@example +autogen -L $@{prefix@}/share/autogen -Tagtexi-cmd.tpl \ + -DLEVEL=section your-opts.def +@end example + +@noindent +Where @file{$@{prefix@}} is the AutoGen installation prefix +and @file{your-opts.def} is the name of your product's option +definition file. + +@node library-info +@subsection library info docs + +The @command{texinfo} doc for libraries is derived from mostly the same +information as is used for producing man pages @xref{man3}. The main +difference is that there is only one output file and the individual +functions are referenced from a @code{texi} menu. There is also +a small difference in the global attributes used: + +@multitable @columnfractions .02 .23 .65 +@item @tab lib_description +@tab A description of the library. This text appears before the menu. +If not provided, the standard boilerplate version will be inserted. +@item +@item @tab see_also +@tab The @code{SEE ALSO} functionality is not supported for the +@file{texinfo} documentation, so any @code{see_also} attribute will be +ignored. +@end multitable + +@noindent +These files are produced by invoking the following commands: + +@example +getdefs linenum srcfile template=aginfo3.tpl output=libexport.def \ + <source-file-list> + +autogen -L $@{prefix@}/share/autogen -DLEVEL=section libexport.def +@end example + +@noindent +Where @file{$@{prefix@}} is the AutoGen installation prefix +and @file{libexport.def} is some name that suits you. + +An example of this can be seen in this document, @xref{libopts procedures}. + +@c === SECTION MARKER + +@node AutoMan pages +@section Automated Man Pages +@cindex AutoMan pages + +AutoOpts provides two templates for producing man pages. +The command (@file{man1}) pages are derived from the options definition +file, and the library (@file{man3}) pages are derived from +stylized comments (@pxref{getdefs Invocation}). + +Man pages include a date in the footer. By default, this is derived from +the current date. However, this may be overridden with the @code{MAN_PAGE_DATE} +environment variable. If set and not empty, its contents will be copied +into where the output of @code{date '+%d %b %Y'} would otherwise go. + +Man pages may be formatted as either traditional man pages or using @code{mdoc} formatting. +The format is selected by selecting the appropriate template. + +@menu +* man1:: command line man pages +* man3:: library man pages +@end menu + +@node man1 +@subsection command line man pages + +Man pages for commands are documented using the @file{agman-cmd.tpl} +and @file{agmdoc-cmd.tpl} templates. If the options specify pulling +information from @file{RC}/@file{ini}/@file{cfg} files, then you may use +the @file{rc-sample.tpl} template to produce an example config file for +your program. + +Using the option definitions for an AutoOpts client program, +the @samp{agman-cmd.tpl} template will produce an nroff document +suitable for use as a @samp{man(1)} page document for a command +line command. The description section of the document is either +the @samp{prog-man-descrip} text, if present, or the @samp{detail} +text. + +Each option in the option definitions file is fully documented +in its usage. This includes all the information documented +above for each option (@pxref{option attributes}), plus +the @samp{doc} attribute is appended. Since the @samp{doc} +text is presumed to be designed for @code{texinfo} documentation, +@code{sed} is used to convert some constructs from @code{texi} +to @code{nroff}-for-@code{man}-pages. Specifically, + +@example +convert @@code, @@var and @@samp into \fB...\fP phrases +convert @@file into \fI...\fP phrases +Remove the '@@' prefix from curly braces +Indent example regions +Delete the example commands +Replace @samp{end example} command with ".br" +Replace the @samp{@@*} command with ".br" +@end example + +@noindent +This document is produced by invoking the following command: + +@example +autogen -L $@{prefix@}/share/autogen -Tagman-cmd.tpl options.def +@end example + +@noindent +Where @file{$@{prefix@}} is the AutoGen installation prefix and +@file{options.def} is the name of your product's option definition file. +I do not use this very much, so any feedback or improvements would be +greatly appreciated. + +@node man3 +@subsection library man pages + +Man pages for libraries are documented using the @file{agman3.tpl} template. + +Two global definitions are required, and then +one library man page is produced for each @code{export_func} definition +that is found. It is generally convenient to place these definitions +as @file{getdefs} comments (@pxref{getdefs Invocation}) near the procedure +definition, but they may also be a separate AutoGen definitions file +(@pxref{Definitions File}). Each function will be cross referenced +with their sister functions in a @file{SEE ALSO} section. A global +@code{see_also} definition will be appended to this cross referencing text. + +@noindent +The two global definitions required are: + +@multitable @columnfractions .02 .15 .77 +@item @tab library +@tab This is the name of your library, without the @file{lib} prefix. +The AutoOpts library is named @file{libopts.so...}, so the @code{library} +attribute would have the value @code{opts}. +@item +@item @tab header +@tab Generally, using a library with a compiled program entails +@code{#include}-ing a header file. Name that header with this attribute. +In the case of AutoOpts, it is generated and will vary based on the +name of the option definition file. Consequently, @file{your-opts.h} is +specified. +@end multitable + +@noindent +The @code{export_func} definition should contain the following attributes: + +@multitable @columnfractions .02 .15 .77 +@item @tab name +@tab The name of the procedure the library user may call. +@item @tab what +@tab A brief sentence describing what the procedure does. +@item @tab doc +@tab A detailed description of what the procedure does. +It may ramble on for as long as necessary to properly describe it. +@item @tab err +@tab A short description of how errors are handled. +@item @tab ret_type +@tab The data type returned by the procedure. +Omit this for @code{void} procedures. +@item @tab ret_desc +@tab Describe what the returned value is, if needed. +@item @tab private +@tab If specified, the function will @strong{not} be documented. +This is used, for example, to produce external declarations for functions +that are not available for public use, but are used in the generated text. +@item +@item @tab arg +@tab This is a compound attribute that contains: +@end multitable +@multitable @columnfractions .02 .15 .15 .62 +@item @tab @tab arg_type +@tab The data type of the argument. +@item @tab @tab arg_name +@tab A short name for it. +@item @tab @tab arg_desc +@tab A brief description. +@end multitable + +@noindent +As a @file{getdefs} comment, this would appear something like this: + +@example +/*=--subblock=arg=arg_type,arg_name,arg_desc =*/ +/*=* + * library: opts + * header: your-opts.h +=*/ +/*=export_func optionProcess + * + * what: this is the main option processing routine + * arg: + tOptions* + pOpts + program options descriptor + + * arg: + int + argc + program arg count + + * arg: + char** + argv + program arg vector + + * ret_type: int + * ret_desc: the count of the arguments processed + * + * doc: This is what it does. + * err: When it can't, it does this. +=*/ +@end example + +@noindent +Note the @code{subblock} and @code{library} comments. +@code{subblock} is an embedded @file{getdefs} +option (@pxref{getdefs subblock}) that tells it how to parse the +@code{arg} attribute. The @code{library} and @code{header} entries +are global definitions that apply to all the documented functions. + +@c === SECTION MARKER + +@node getopt_long +@section Using getopt(3C) +@cindex getopt_long + +There is a template named, @file{getopt.tpl} that is distributed with +AutoOpts. Using that template instead of @file{options.tpl} will produce +completely independent source code that will parse command line options. It +will utilize either the standard @code{getopt(3C)} or the GNU +@code{getopt_long(3GNU)} function to drive the parsing. Which is used is +selected by the presence or absence of the @code{long-opts} program attribute. +It will save you from being dependent upon the @code{libopts} library @i{and} +it produces code ready for internationalization. However, it also carries +with it some limitations on the use of AutoOpts features and some requirements +on the build environment. + +@strong{PLEASE NOTE}: in processing the option definitions to produce +the usage text, it is necessary to compile some generated code in a +temporary directory. That means that all the include directories +needed to compile the code must be full path names and not relative +directory names. ``.'' is a relative directory name. To specify +``-I.'' in the @code{CFLAGS} environment variable, you must expand it. +For example, use: +@example +CFLAGS=-I`pwd` +@end example + +@menu +* getopt limitations:: getopt feature limitations +* getopt building:: getopt build requirements +@end menu + +@node getopt limitations +@subsection getopt feature limitations + +This list of limitations is relative to the full list of AutoOpts +supported features, @xref{Features}. + +@enumerate +@item +You cannot automatically take advantage of environment variable options or +automated parsing of configuration files (@code{rc} or @code{ini} files). +Consequently, the resulting code does not support @file{--load-opts} or +@file{--save-opts} options automatically. + +@item +You cannot use set membership, enumerated, range checked or stacked +argument type options. In fact, you cannot use anything that depends +upon the @code{libopts} library. You are constrained to options that +take @code{@code{string}} arguments, though you may handle the option +argument with a callback procedure. + +@item +Special disablement and/or enablement prefixes are not recognized. + +@item +Option coordination with external libraries will not work. + +@item +Every option must be @code{settable} because the emitted code +depends upon the @code{SET_OPT_XXX} macros having been defined. +Specify this as a global (program) attribute. + +@item +You must specify a main procedure attribute (@pxref{Generated main}). +The @file{getopt.tpl} template depends upon being able to compile the +traditional .c file into a program and get it to emit the usage text. + +@item +For the same reason, the traditional option parsing table code must be +emitted @b{before} the @file{getopt.tpl} template gets expanded. + +@item +The usage text is, therefore, statically defined. +@end enumerate + +@node getopt building +@subsection getopt build requirements + +You must supply some compile and link options via environment variables. + +@table @samp +@item srcdir +In case the option definition file lives in a different directory. +@item CFLAGS +Any special flags required to compile. The flags from +@code{autoopts-config cflags} will be included automatically. Since +the creation of the option parsing code includes creating a program +that prints out help text, if it is necessary to include files from +various directories to compile that program, you will need to specify +those directories with @option{-Idirpath} text in the @code{CFLAGS}. +Some experimentation may be necessary in that case. + +@strong{NOTE}: the @option{-Idirpath} text is only needed if your option +callback functions include code that require additional @code{#include} +directives. +@item LDFLAGS +Any special flags required to link. The flags from +@code{autoopts-config ldflags} will be included automatically. This +is required only if additional link flags for the help text emission +program might be needed. +@item CC +This is needed only if @code{@code{cc}} cannot be found in @env{$PATH} +(or it is not the one you want). +@end table + +To use this, set the exported environment variables and specify @code{getopt} +as the default template in your option definitions file +(@pxref{Identification}). You will have @i{four} new files. Assuming your +definitions were in a file named @file{myprog-opts.def} and your program name +was specified as @file{progname}, the resulting files would be created: +@file{myprog-opts.h}, @file{myprog-opts.c}, @file{getopt-progname.h} and +@file{getopt-progname.c}. You must compile and link both @file{.c} files into +your program. If there are link failures, then you are using AutoOpts +features that require the @file{libopts} library. You must remove these +features, @xref{getopt limitations}. + +These generated files depend upon configure defines to work correctly. +Therefore, you must specify a @code{config-header} attribute +(@pxref{programming attributes}) and ensure it has @code{#defines} for +either @code{HAVE_STDINT_H} or @code{HAVE_INTTYPES_H}; either +@code{HAVE_SYS_LIMITS_H} or @code{HAVE_LIMITS_H}; and +@code{HAVE_SYSEXITS_H}, if the @file{sysexits.h} header is available. +The required header files for these defines are, respectively, +the @file{/usr/include} files named: +@itemize @bullet +@item stdint.h +@item inttypes.h +@item sys/limits.h +@item limits.h +@item sysexits.h +@end itemize + +@noindent +The following header files must also exist on the build platform: +@itemize @bullet +@item sys/types.h +@item stdio.h +@item string.h +@item unistd.h -- or, for getopt_long: +@item getopt.h +@end itemize +@c === SECTION MARKER + +@node i18n +@section Internationalizing AutoOpts +@cindex Internationalizing AutoOpts + +The generated code for AutoOpts will enable and disable the translation of +AutoOpts run time messages. If @code{ENABLE_NLS} is defined at compile time +and @code{no-xlate} has been not set to the value @emph{anything}, then the +@code{_()} macro may be used to specify a translation function. If undefined, +it will default to @code{gettext(3GNU)}. This define will also enable a +callback function that @code{optionProcess} invokes at the beginning of option +processing. The AutoOpts @code{libopts} library will always check for this +@emph{compiled with NLS} flag, so @code{libopts} does not need to be specially +compiled. The strings returned by the translation function will be +@code{strdup(3)-ed} and kept. They will not be re-translated, even if the +locale changes, but they will also not be dependent upon reused or unmappable +memory. + +You should also ensure that the @code{ATTRIBUTE_FORMAT_ARG()} gets +@code{#define}-ed to something useful. There is an autoconf macro +named @code{AG_COMPILE_FORMAT_ARG} in @file{ag_macros.m4} that will +set it appropriately for you. If you do not do this, then translated +formatting strings may trigger GCC compiler warnings. + +To internationalize option processing, you should first internationalize your +program. Then, the option processing strings can be added to your translation +text by processing the AutoOpts-generated @file{my-opts.c} file and adding the +distributed @file{po/usage-txt.pot} file. (Also by extracting the strings +yourself from the @file{usage-txt.h} file.) When you call +@code{optionProcess}, all of the user visible AutoOpts strings will be passed +through the localization procedure established with the @code{_()} +preprocessing macro. + +All of this is @emph{dis}-abled if you specify the global attribute +@code{no-xlate} to @emph{anything}. + +@c === SECTION MARKER + +@node Naming Conflicts +@section Naming Conflicts +@cindex Naming Conflicts + +AutoOpts generates a header file that contains many C preprocessing macros and +several external names. For the most part, they begin with either @code{opt_} +or @code{option}, or else they end with @code{_opt}. If this happens to +conflict with other macros you are using, or if you are compiling multiple +option sets in the same compilation unit, the conflicts can be avoided. You +may specify an external name @code{prefix} (@pxref{program attributes}) for +all of the names generated for each set of option definitions. + +Among these macros, several take an option name as a macro argument. +Sometimes, this will inconveniently conflict. For example, if you specify an +option named, @code{debug}, the emitted code will presume that @code{DEBUG} is +not a preprocessing name. Or also, if you are building on a Windows platform, +you may find that MicroSoft has usurped a number of user space names in its +header files. Consequently, you will get a preprocessing error if you use, +for example, @code{HAVE_OPT(DEBUG)} or @code{HAVE_OPT(INTERNAL)} +(@pxref{HAVE_OPT}) in your code. You may trigger an obvious warning for such +conflicts by specifying the @code{guard-option-names} attribute +(@pxref{program attributes}). That emitted code will also @code{#undef}-ine +the conflicting name. + +@node All Attribute Names +@section All Attribute Names + +This is the list of all the option attributes used in the various +option processing templates. There are several flavors of attributes, +and these are not distinguished here. + +@itemize @bullet +@item +Valid, current attributes that you are encouraged to use. +@item +Internally generated attributes that you cannot use at all. +I need to prefix these with a distinguished prefix. e.g. @code{ao-} +@item +Valid attributes, but are deprecated. Alternates should be documented. +@end itemize + +This list is derived by running many example option definitions through the +option generation and man page templates and noting which attributes are +actually used. There may be a few that are used but not exercised in my +testing. If so, I need to ferret those out and test them, too. + +@example +addtogroup aliases allow_errors arg_default +arg_name arg_optional arg_range arg_type +argument author call_proc cmd_section +comment_char concept config_header copyright +date default deprecated descrip +detail die_code disable disable_load +disable_save doc doc_section doc_sub +doc_sub_cmd documentation ds_format ds_text +ds_type eaddr enable enabled +environrc equivalence exit_desc exit_name +explain export extract_code field +file_fail_code flag flag_code flag_proc +flags_cant flags_must full_usage gnu_usage +guard_option_names handler_proc handler_type help_type +help_value home_rc homerc ifdef +ifndef immed_disable immediate include +interleaved keyword lib_name library +load_opts_value long_opts main_fini main_init +main_type max min more_help_value +must_set name no_command no_libopts +no_misuse_usage no_preset no_xlate omit_texi +omitted_usage open_file opt_state option_format +option_info owner package prefix +prefix_enum preserve_case prog_descrip prog_info_descrip +prog_man_descrip prog_name prog_title rcfile +reorder_args reset_value resettable save_opts_value +scaled set_desc set_index settable +short_usage stack_arg stdin_input sub_name +sub_text sub_type test_main translators +type unshar_file_code unstack_arg usage +usage_message usage_opt usage_value value +vendor_opt version version_proc version_value +@end example + +@node Option Define Names +@section Option Definition Name Index +@printindex vr + +@ignore +END == AUTOINFO == DO NOT CHANGE THIS COMMENT or the surrounding 'ignore's +Extraction from autogen.texi +@end ignore + +@c = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = +@c +@c TRAILER + +@c LocalWords: AutoGen texinfo Korb tpl bruce Exp texi autogen setfilename AG +@c LocalWords: settitle setchapternewpage dne dircategory direntry ifinfo gpl +@c LocalWords: AutoOpts snprintfv titlepage vskip pt filll sp dir xref cindex +@c LocalWords: AutoGen's noindent rc ini enum IDX const az upcase ENDFOR ESAC +@c LocalWords: optargs egcs inclhack sh fixincl autoconf endif var templ dirs +@c LocalWords: def txt cd STR str ifdef alist downcase sprintf arg lexer +@c LocalWords: srcfile linenum subblock defParse srcdir sed POSIX printf expr +@c LocalWords: stdout expr func gfunc tr findex exparg desc desc sep macfunc +@c LocalWords: ing getdefs libopts src ksh forcomma csh env Sourced autoopts +@c LocalWords: mkmerge builddir ADDON AutoGetopts getopt glibc argp perl awk +@c LocalWords: printindex cp fn diff --git a/doc/autogen.info b/doc/autogen.info new file mode 100644 index 0000000..33133c4 --- /dev/null +++ b/doc/autogen.info @@ -0,0 +1,523 @@ +This is autogen.info, produced by makeinfo version 6.5 from +autogen.texi. + +This manual is for GNU AutoGen version 5.18, updated August 2018. + + Copyright (C) 1992-2018 by Bruce Korb. + + Permission is granted to copy, distribute and/or modify this + document under the terms of the GNU Free Documentation License, + Version 1.2 or any later version published by the Free Software + Foundation; with no Invariant Sections, no Front-Cover Texts, and + no Back-Cover Texts. +INFO-DIR-SECTION GNU programming tools +START-INFO-DIR-ENTRY +* AutoGen: (autogen). The Automated Program Generator +END-INFO-DIR-ENTRY + + This file documents GNU AutoGen Version 5.18. + + AutoGen copyright (C) 1992-2018 Bruce Korb AutoOpts copyright (C) +1992-2018 Bruce Korb snprintfv copyright (C) 1999-2000 Gary V. Vaughan + + AutoGen is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation, either version 3 of the License, or (at your +option) any later version. + + AutoGen is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +Public License for more details. + + You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. + + +Indirect: +autogen.info-1: 1430 +autogen.info-2: 303004 + +Tag Table: +(Indirect) +Node: Top1430 +Node: Introduction2868 +Node: Generalities4523 +Node: Example Usage7327 +Node: csh/zsh caveat12566 +Node: Testimonial13929 +Node: Definitions File16140 +Node: Identification18045 +Node: Definitions19332 +Node: def-list21055 +Node: double-quote-string21944 +Node: single-quote-string22813 +Node: simple-string23552 +Node: shell-generated24311 +Node: scheme-generated24996 +Node: here-string25393 +Node: concat-string27411 +Node: Index Assignments28394 +Node: Dynamic Text29855 +Node: Directives31030 +Node: Predefines36529 +Node: Comments38285 +Node: Example38700 +Node: Full Syntax39434 +Node: Alternate Definition53769 +Node: Template File55843 +Node: pseudo macro57472 +Node: naming values63171 +Node: expression syntax64452 +Node: apply code65687 +Node: basic expression68200 +Node: AutoGen Functions70493 +Node: SCM ag-fprintf75477 +Node: SCM ag-function?76258 +Node: SCM base-name76636 +Node: SCM chdir77015 +Node: SCM count77483 +Node: SCM def-file77966 +Node: SCM def-file-line78335 +Node: SCM dne79255 +Node: SCM emit80904 +Node: SCM emit-string-table81412 +Node: SCM error81860 +Node: SCM exist?82781 +Node: SCM find-file83553 +Node: SCM first-for?84095 +Node: SCM for-by84579 +Node: SCM for-from85012 +Node: SCM for-index85450 +Node: SCM for-sep85904 +Node: SCM for-to86447 +Node: SCM found-for?86875 +Node: SCM get87309 +Node: SCM get-c-name87799 +Node: SCM get-down-name88358 +Node: SCM get-up-name88984 +Node: SCM high-lim89600 +Node: SCM insert-file90297 +Node: SCM insert-suspended90667 +Node: SCM last-for?91110 +Node: SCM len91585 +Node: SCM low-lim92098 +Node: SCM make-header-guard92434 +Node: SCM make-tmp-dir94186 +Node: SCM match-value?94541 +Node: SCM max-file-time95444 +Node: SCM mk-gettextable95962 +Node: SCM out-delete96410 +Node: SCM out-depth96906 +Node: SCM out-emit-suspended97254 +Node: SCM out-line97670 +Node: SCM out-move98044 +Node: SCM out-name98527 +Node: SCM out-pop98983 +Node: SCM out-push-add99608 +Node: SCM out-push-new100018 +Node: SCM out-resume100636 +Node: SCM out-suspend101125 +Node: SCM out-switch101827 +Node: SCM output-file-next-line102406 +Node: SCM set-option103336 +Node: SCM set-writable103747 +Node: SCM stack104320 +Node: SCM stack-join104706 +Node: SCM suffix105227 +Node: SCM tpl-file105539 +Node: SCM tpl-file-line106031 +Node: SCM tpl-file-next-line107020 +Node: SCM warn107595 +Node: SCM autogen-version108080 +Node: SCM c-file-line-fmt108439 +Node: Common Functions108860 +Node: SCM agpl114213 +Node: SCM bsd114671 +Node: SCM c-string115148 +Node: SCM error-source-line115914 +Node: SCM extract116447 +Node: SCM format-arg-count119781 +Node: SCM fprintf120691 +Node: SCM gperf121241 +Node: SCM gperf-code121970 +Node: SCM gpl123160 +Node: SCM hide-email123625 +Node: SCM html-escape-encode124088 +Node: SCM in?124588 +Node: SCM join125026 +Node: SCM kr-string125538 +Node: SCM lgpl126105 +Node: SCM license126628 +Node: SCM license-description127175 +Node: SCM license-full127928 +Node: SCM license-info130082 +Node: SCM license-name131038 +Node: SCM make-gperf131398 +Node: SCM makefile-script132393 +Node: SCM max135174 +Node: SCM min135486 +Node: SCM prefix135789 +Node: SCM printf136682 +Node: SCM raw-shell-str137248 +Node: SCM shell137997 +Node: SCM shell-str139001 +Node: SCM shellf141925 +Node: SCM sprintf142373 +Node: SCM string-capitalize142756 +Node: SCM string-capitalize!143218 +Node: SCM *=*143559 +Node: SCM *==*144127 +Node: SCM string-downcase144533 +Node: SCM string-downcase!144944 +Node: SCM *~145305 +Node: SCM *~~145725 +Node: SCM *=146105 +Node: SCM *==146485 +Node: SCM ==146895 +Node: SCM ~147239 +Node: SCM =147708 +Node: SCM *~*148488 +Node: SCM *~~*148900 +Node: SCM ~~149294 +Node: SCM ~*149658 +Node: SCM ~~*150070 +Node: SCM =*150461 +Node: SCM ==*150847 +Node: SCM string-substitute151230 +Node: SCM string-table-add151992 +Node: SCM string-table-add-ref152794 +Node: SCM string-table-new153366 +Node: SCM string-table-size156081 +Node: SCM string->c-name!156503 +Node: SCM string->camelcase157034 +Node: SCM string-tr157528 +Node: SCM string-tr!158005 +Node: SCM string-upcase158664 +Node: SCM string-upcase!159071 +Node: SCM sub-shell-str159433 +Node: SCM sum159884 +Node: SCM time-string->number160217 +Node: SCM version-compare160849 +Node: native macros161791 +Node: AGMacro syntax164990 +Node: BREAK167131 +Node: CASE167487 +Node: COMMENT170195 +Node: CONTINUE170742 +Node: DEBUG171002 +Node: DEFINE171869 +Node: ELIF174100 +Node: ELSE174576 +Node: ENDDEF174949 +Node: ENDFOR175216 +Node: ENDIF175518 +Node: ENDWHILE175796 +Node: ESAC176090 +Node: EXPR176372 +Node: FOR176851 +Node: IF179887 +Node: INCLUDE180924 +Node: INVOKE181572 +Node: RETURN182572 +Node: SELECT183111 +Node: UNKNOWN183603 +Node: WHILE184132 +Node: shell command184895 +Node: guile command185526 +Node: output controls185949 +Node: Augmenting AutoGen187953 +Node: shell commands188503 +Node: guile macros189326 +Node: guile callouts189785 +Node: AutoGen macros191977 +Node: autogen Invocation192594 +Node: autogen usage194540 +Node: autogen input-select200309 +Ref: autogen templ-dirs200618 +Ref: autogen override-tpl201115 +Ref: autogen definitions201539 +Ref: autogen shell202221 +Ref: autogen no-fmemopen202836 +Ref: autogen equate203627 +Node: autogen out-handling203944 +Ref: autogen base-name204226 +Ref: autogen source-time205268 +Ref: autogen writable205759 +Node: autogen debug-tpl205992 +Ref: autogen loop-limit206386 +Ref: autogen timeout206786 +Ref: autogen trace207329 +Ref: autogen trace-out209312 +Ref: autogen show-defs209838 +Ref: autogen used-defines210230 +Ref: autogen core210958 +Node: autogen processing211479 +Ref: autogen skip-suffix211867 +Ref: autogen select-suffix212533 +Ref: autogen define213052 +Ref: autogen undefine214370 +Node: autogen dep-track214820 +Ref: autogen make-dep215094 +Node: autogen autoopts-opts218411 +Ref: autogen no-abort218668 +Node: autogen config218927 +Node: autogen exit status221995 +Node: autogen Examples223357 +Node: Installation224084 +Node: configuring224402 +Node: AutoGen CGI227248 +Node: signal names229692 +Node: installing230911 +Node: AutoOpts233694 +Node: Features235454 +Node: Licensing243393 +Node: Caveats244522 +Node: Quick Start247528 +Node: quick ao problem248699 +Node: quick ao def249313 +Node: quick ao build250563 +Node: quick ao help251164 +Node: quick ao usage251385 +Node: quick ao docs252485 +Node: Option Definitions253402 +Node: program attributes255328 +Node: usage attributes257229 +Node: config attributes261388 +Node: programming attributes264732 +Node: presentation attributes270315 +Node: library attributes273638 +Node: lib and program274515 +Node: lib called276935 +Node: prog calls lib278223 +Node: information attributes279101 +Node: Generated main283754 +Node: main guile285210 +Node: main shell-process286117 +Node: main shell-parser287642 +Node: main main288289 +Node: main include289221 +Node: main invoke290166 +Node: main for-each290654 +Node: main-for-each-proc291586 +Node: main-for-each-type292796 +Node: main-for-each-code296262 +Node: main-for-each-opts297240 +Node: option attributes298378 +Node: Required Attributes299765 +Node: Common Attributes303004 +Node: Immediate Action306911 +Node: Option Conflict Attributes309223 +Node: opt-attr settable310009 +Node: opt-attr no-preset310598 +Node: opt-attr equivalence310957 +Node: opt-attr aliases313181 +Node: opt-attr default option313853 +Node: opt-attr documentation314660 +Node: opt-attr translators316189 +Node: Option Arguments316802 +Node: arg-type string318932 +Node: arg-type number319233 +Node: arg-type boolean321135 +Node: arg-type keyword321583 +Node: arg-type set membership323549 +Node: arg-type hierarchy325940 +Node: arg-type file name326727 +Node: arg-type time-duration327975 +Node: arg-type time-date329929 +Node: arg-keyword330712 +Node: arg-optional331567 +Node: arg-default333223 +Node: Option Argument Handling333582 +Node: Internationalizing Options337810 +Node: documentation attributes339762 +Node: per option attributes340346 +Node: global option attributes341881 +Node: automatic options348917 +Node: standard options356133 +Node: AutoOpts API358461 +Node: Option Processing Data361358 +Node: CLEAR_OPT364966 +Node: COUNT_OPT365290 +Node: DESC365698 +Node: DISABLE_OPT_name366116 +Node: ENABLED_OPT366675 +Node: ERRSKIP_OPTERR367114 +Node: ERRSTOP_OPTERR367445 +Node: HAVE_OPT367899 +Node: ISSEL_OPT368271 +Node: ISUNUSED_OPT368579 +Node: OPTION_CT368889 +Node: OPT_ARG369245 +Node: OPT_NO_XLAT_CFG_NAMES369802 +Node: OPT_NO_XLAT_OPT_NAMES370337 +Node: OPT_VALUE_name370816 +Node: OPT_XLAT_CFG_NAMES371281 +Node: OPT_XLAT_OPT_NAMES372199 +Node: RESTART_OPT372959 +Node: SET_OPT_name374119 +Node: STACKCT_OPT375070 +Node: STACKLST_OPT375859 +Node: START_OPT376686 +Node: STATE_OPT376942 +Node: USAGE377903 +Node: VALUE_OPT_name379368 +Node: VERSION380028 +Node: WHICH_IDX_name380611 +Node: WHICH_OPT_name381175 +Node: teOptIndex381749 +Node: OPTIONS_STRUCT_VERSION382346 +Node: libopts procedures383139 +Node: libopts-ao_string_tokenize384834 +Node: libopts-configFileLoad386866 +Node: libopts-optionFileLoad388242 +Node: libopts-optionFindNextValue389874 +Node: libopts-optionFindValue391150 +Node: libopts-optionFree392268 +Node: libopts-optionGetValue392911 +Node: libopts-optionLoadLine394221 +Node: libopts-optionMemberList395716 +Node: libopts-optionNextValue396369 +Node: libopts-optionOnlyUsage397717 +Node: libopts-optionPrintVersion398434 +Node: libopts-optionPrintVersionAndReturn399037 +Node: libopts-optionProcess399818 +Node: libopts-optionRestore401645 +Node: libopts-optionSaveFile402531 +Node: libopts-optionSaveState403776 +Node: libopts-optionUnloadNested404984 +Node: libopts-optionVersion405628 +Node: libopts-strequate406194 +Node: libopts-streqvcmp406829 +Node: libopts-streqvmap407829 +Node: libopts-strneqvcmp408996 +Node: libopts-strtransform410110 +Node: Multi-Threading410859 +Node: option descriptor411858 +Node: Using AutoOpts412509 +Node: local use413119 +Node: binary not installed414769 +Node: binary pre-installed415270 +Node: source pre-installed415899 +Node: source not installed416958 +Node: Presetting Options418090 +Node: loading rcfile420353 +Node: saving rcfile422061 +Node: sample rcfile422570 +Node: environrc431737 +Node: config example433643 +Node: Config File Format435547 +Node: config name/string-value436593 +Node: config integer-values439444 +Node: config nested-values439949 +Node: config directives440436 +Node: config comments442431 +Node: shell options442861 +Node: binary-parser444680 +Node: script-parser447071 +Node: AutoInfo471404 +Node: command-info472849 +Node: library-info473894 +Node: AutoMan pages475160 +Node: man1476059 +Node: man3477801 +Node: getopt_long481111 +Node: getopt limitations482457 +Node: getopt building484048 +Node: i18n486676 +Node: Naming Conflicts488548 +Node: All Attribute Names489936 +Node: Option Define Names492935 +Node: Add-Ons505441 +Node: AutoFSM506519 +Node: AutoXDR506942 +Node: AutoEvents507772 +Node: Bit Maps509019 +Node: enums509986 +Node: enum-code512915 +Node: masks519381 +Node: columns Invocation521030 +Node: columns usage522811 +Node: columns dimensions526428 +Ref: columns width526672 +Ref: columns columns527121 +Ref: columns col-width527437 +Ref: columns tab-width527749 +Node: columns treatment527942 +Ref: columns spread528181 +Ref: columns fill528546 +Ref: columns indent529008 +Ref: columns first-indent529310 +Ref: columns format530033 +Ref: columns separation530340 +Ref: columns line-separation530596 +Ref: columns ending530842 +Node: columns ordering531005 +Ref: columns by-columns531254 +Ref: columns sort531561 +Node: columns input-text531897 +Ref: columns input532150 +Node: columns config532396 +Node: columns exit status535136 +Node: columns See Also535717 +Node: getdefs Invocation535992 +Node: getdefs usage538886 +Node: getdefs def-selection542179 +Ref: getdefs defs-to-get542475 +Ref: getdefs subblock542800 +Ref: getdefs listattr543743 +Node: getdefs enumerating544443 +Ref: getdefs ordering544703 +Ref: getdefs first-index545297 +Node: getdefs doc-insert545598 +Ref: getdefs filelist545845 +Ref: getdefs assign546218 +Ref: getdefs common-assign546567 +Ref: getdefs copy546912 +Ref: getdefs srcfile547236 +Ref: getdefs linenum547643 +Node: getdefs input-files548030 +Ref: getdefs input548285 +Node: getdefs doc-output548891 +Ref: getdefs output549139 +Ref: getdefs autogen549454 +Ref: getdefs template550020 +Ref: getdefs agarg550204 +Ref: getdefs base-name550615 +Node: getdefs config551096 +Node: getdefs exit status553319 +Node: getdefs See Also554034 +Node: xml2ag Invocation554309 +Node: xml2ag usage556196 +Node: xml2ag the-xml2ag-option560493 +Ref: xml2ag output560775 +Node: xml2ag autogen-options561007 +Ref: xml2ag templ-dirs561488 +Ref: xml2ag override-tpl561764 +Ref: xml2ag definitions561940 +Ref: xml2ag shell562097 +Ref: xml2ag no-fmemopen562282 +Ref: xml2ag equate562393 +Ref: xml2ag base-name562577 +Ref: xml2ag source-time562760 +Ref: xml2ag writable562880 +Ref: xml2ag loop-limit563097 +Ref: xml2ag timeout563263 +Ref: xml2ag trace563437 +Ref: xml2ag trace-out564019 +Ref: xml2ag show-defs564185 +Ref: xml2ag used-defines564307 +Ref: xml2ag core564424 +Ref: xml2ag skip-suffix564996 +Ref: xml2ag select-suffix565371 +Ref: xml2ag define565635 +Ref: xml2ag undefine565906 +Ref: xml2ag make-dep566181 +Node: xml2ag exit status566411 +Node: snprintfv566754 +Node: Future569268 +Node: Copying This Manual569607 +Node: Concept Index569893 +Node: Function Index591435 + +End Tag Table diff --git a/doc/autogen.info-1 b/doc/autogen.info-1 new file mode 100644 index 0000000..b111e17 --- /dev/null +++ b/doc/autogen.info-1 @@ -0,0 +1,7363 @@ +This is autogen.info, produced by makeinfo version 6.5 from +autogen.texi. + +This manual is for GNU AutoGen version 5.18, updated August 2018. + + Copyright (C) 1992-2018 by Bruce Korb. + + Permission is granted to copy, distribute and/or modify this + document under the terms of the GNU Free Documentation License, + Version 1.2 or any later version published by the Free Software + Foundation; with no Invariant Sections, no Front-Cover Texts, and + no Back-Cover Texts. +INFO-DIR-SECTION GNU programming tools +START-INFO-DIR-ENTRY +* AutoGen: (autogen). The Automated Program Generator +END-INFO-DIR-ENTRY + + This file documents GNU AutoGen Version 5.18. + + AutoGen copyright (C) 1992-2018 Bruce Korb AutoOpts copyright (C) +1992-2018 Bruce Korb snprintfv copyright (C) 1999-2000 Gary V. Vaughan + + AutoGen is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation, either version 3 of the License, or (at your +option) any later version. + + AutoGen is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +Public License for more details. + + You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. + + +File: autogen.info, Node: Top, Next: Introduction, Up: (dir) + +The Automated Program Generator +******************************* + +This file documents AutoGen version 5.18. It is a tool designed for +generating program files that contain repetitive text with varied +substitutions. This document is very long because it is intended as a +reference document. For a quick start example, *Note Example Usage::. + + The AutoGen distribution includes the basic generator engine and +several add-on libraries and programs. Of the most general interest +would be Automated Option processing, *Note AutoOpts::, which also +includes stand-alone support for configuration file parsing, *Note +Features::. *Note Add-on packages for AutoGen: Add-Ons, section for +additional programs and libraries associated with AutoGen. + + This edition documents version 5.18, August 2018. + +* Menu: + +* Introduction:: AutoGen's Purpose +* Definitions File:: AutoGen Definitions File +* Template File:: AutoGen Template +* Augmenting AutoGen:: Augmenting AutoGen Features +* autogen Invocation:: Invoking AutoGen +* Installation:: Configuring and Installing +* AutoOpts:: Automated Option Processing +* Add-Ons:: Add-on packages for AutoGen +* Future:: Some ideas for the future. +* Copying This Manual:: Copying This Manual +* Concept Index:: General index +* Function Index:: Function index + + +File: autogen.info, Node: Introduction, Next: Definitions File, Up: Top + +1 Introduction +************** + +AutoGen is a tool designed for generating program files that contain +repetitive text with varied substitutions. Its goal is to simplify the +maintenance of programs that contain large amounts of repetitious text. +This is especially valuable if there are several blocks of such text +that must be kept synchronized in parallel tables. + + An obvious example is the problem of maintaining the code required +for processing program options and configuration settings. Processing +options requires a minimum of four different constructs be kept in +proper order in different places in your program. You need at least: + + 1. The flag character in the flag string, + 2. code to process the flag when it is encountered, + 3. a global state variable or two, and + 4. a line in the usage text. + +You will need more things besides this if you choose to implement long +option names, configuration (rc/ini) file processing, environment +variable settings and keep all the documentation for these up to date. +This can be done mechanically; with the proper templates and this +program. In fact, it has already been done and AutoGen itself uses it +*Note AutoOpts::. For a simple example of Automated Option processing, +*Note Quick Start::. For a full list of the Automated Option features, +*Note Features::. Be forewarned, though, the feature list is +ridiculously extensive. + +* Menu: + +* Generalities:: The Purpose of AutoGen +* Example Usage:: A Simple Example +* csh/zsh caveat:: csh/zsh caveat +* Testimonial:: A User's Perspective + + +File: autogen.info, Node: Generalities, Next: Example Usage, Up: Introduction + +1.1 The Purpose of AutoGen +========================== + +The idea of this program is to have a text file, a template if you will, +that contains the general text of the desired output file. That file +includes substitution expressions and sections of text that are +replicated under the control of separate definition files. + + AutoGen was designed with the following features: + + 1. The definitions are completely separate from the template. By + completely isolating the definitions from the template it greatly + increases the flexibility of the template implementation. A + secondary goal is that a template user only needs to specify those + data that are necessary to describe his application of a template. + + 2. Each datum in the definitions is named. Thus, the definitions can + be rearranged, augmented and become obsolete without it being + necessary to go back and clean up older definition files. Reduce + incompatibilities! + + 3. Every definition name defines an array of values, even when there + is only one entry. These arrays of values are used to control the + replication of sections of the template. + + 4. There are named collections of definitions. They form a nested + hierarchy. Associated values are collected and associated with a + group name. These associated data are used collectively in sets of + substitutions. + + 5. The template has special markers to indicate where substitutions + are required, much like the '${VAR}' construct in a shell 'here + doc'. These markers are not fixed strings. They are specified at + the start of each template. Template designers know best what fits + into their syntax and can avoid marker conflicts. + + We did this because it is burdensome and difficult to avoid + conflicts using either M4 tokenization or C preprocessor + substitution rules. It also makes it easier to specify expressions + that transform the value. Of course, our expressions are less + cryptic than the shell methods. + + 6. These same markers are used, in conjunction with enclosed keywords, + to indicate sections of text that are to be skipped and for + sections of text that are to be repeated. This is a major + improvement over using C preprocessing macros. With the C + preprocessor, you have no way of selecting output text because it + is an unvarying, mechanical substitution process. + + 7. Finally, we supply methods for carefully controlling the output. + Sometimes, it is just simply easier and clearer to compute some + text or a value in one context when its application needs to be + later. So, functions are available for saving text or values for + later use. + + +File: autogen.info, Node: Example Usage, Next: csh/zsh caveat, Prev: Generalities, Up: Introduction + +1.2 A Simple Example +==================== + +This is just one simple example that shows a few basic features. If you +are interested, you also may run "make check" with the 'VERBOSE' +environment variable set and see a number of other examples in the +'agen5/test' directory. + + Assume you have an enumeration of names and you wish to associate +some string with each name. Assume also, for the sake of this example, +that it is either too complex or too large to maintain easily by hand. +We will start by writing an abbreviated version of what the result is +supposed to be. We will use that to construct our output templates. + +In a header file, 'list.h', you define the enumeration and the global +array containing the associated strings: + + typedef enum { + IDX_ALPHA, + IDX_BETA, + IDX_OMEGA } list_enum; + + extern char const* az_name_list[ 3 ]; + +Then you also have 'list.c' that defines the actual strings: + + #include "list.h" + char const* az_name_list[] = { + "some alpha stuff", + "more beta stuff", + "final omega stuff" }; + +First, we will define the information that is unique for each +enumeration name/string pair. This would be placed in a file named, +'list.def', for example. + + autogen definitions list; + list = { list_element = alpha; + list_info = "some alpha stuff"; }; + list = { list_info = "more beta stuff"; + list_element = beta; }; + list = { list_element = omega; + list_info = "final omega stuff"; }; + + The 'autogen definitions list;' entry defines the file as an AutoGen +definition file that uses a template named 'list'. That is followed by +three 'list' entries that define the associations between the +enumeration names and the strings. The order of the differently named +elements inside of list is unimportant. They are reversed inside of the +'beta' entry and the output is unaffected. + + Now, to actually create the output, we need a template or two that +can be expanded into the files you want. In this program, we use a +single template that is capable of multiple output files. The +definitions above refer to a 'list' template, so it would normally be +named, 'list.tpl'. + + It looks something like this. (For a full description, *Note +Template File::.) + + [+ AutoGen5 template h c +] + [+ CASE (suffix) +][+ + == h +] + typedef enum {[+ + FOR list "," +] + IDX_[+ (string-upcase! (get "list_element")) +][+ + ENDFOR list +] } list_enum; + + extern char const* az_name_list[ [+ (count "list") +] ]; + [+ + + == c +] + #include "list.h" + char const* az_name_list[] = {[+ + FOR list "," +] + "[+list_info+]"[+ + ENDFOR list +] };[+ + + ESAC +] + + The '[+ AutoGen5 template h c +]' text tells AutoGen that this is an +AutoGen version 5 template file; that it is to be processed twice; that +the start macro marker is '[+'; and the end marker is '+]'. The +template will be processed first with a suffix value of 'h' and then +with 'c'. Normally, the suffix values are appended to the 'base-name' +to create the output file name. + + The '[+ == h +]' and '[+ == c +]' 'CASE' selection clauses select +different text for the two different passes. In this example, the +output is nearly disjoint and could have been put in two separate +templates. However, sometimes there are common sections and this is +just an example. + + The '[+FOR list "," +]' and '[+ ENDFOR list +]' clauses delimit a +block of text that will be repeated for every definition of 'list'. +Inside of that block, the definition name-value pairs that are members +of each 'list' are available for substitutions. + + The remainder of the macros are expressions. Some of these contain +special expression functions that are dependent on AutoGen named values; +others are simply Scheme expressions, the result of which will be +inserted into the output text. Other expressions are names of AutoGen +values. These values will be inserted into the output text. For +example, '[+list_info+]' will result in the value associated with the +name 'list_info' being inserted between the double quotes and +'(string-upcase! (get "list_element"))' will first "get" the value +associated with the name 'list_element', then change the case of all the +letters to upper case. The result will be inserted into the output +document. + + If you have compiled AutoGen, you can copy out the template and +definitions as described above and run 'autogen list.def'. This will +produce exactly the hypothesized desired output. + + One more point, too. Lets say you decided it was too much trouble to +figure out how to use AutoGen, so you created this enumeration and +string list with thousands of entries. Now, requirements have changed +and it has become necessary to map a string containing the enumeration +name into the enumeration number. With AutoGen, you just alter the +template to emit the table of names. It will be guaranteed to be in the +correct order, missing none of the entries. If you want to do that by +hand, well, good luck. + + +File: autogen.info, Node: csh/zsh caveat, Next: Testimonial, Prev: Example Usage, Up: Introduction + +1.3 csh/zsh caveat +================== + +AutoGen tries to use your normal shell so that you can supply shell code +in a manner you are accustomed to using. If, however, you use csh or +zsh, you cannot do this. Csh is sufficiently difficult to program that +it is unsupported. Zsh, though largely programmable, also has some +anomalies that make it incompatible with AutoGen usage. Therefore, when +invoking AutoGen from these environments, you must be certain to set the +SHELL environment variable to a Bourne-derived shell, e.g., sh, ksh or +bash. + + Any shell you choose for your own scripts need to follow these basic +requirements: + + 1. It handles 'trap ":" $sig' without output to standard out. This is + done when the server shell is first started. If your shell does + not handle this, then it may be able to by loading functions from + its start up files. + 2. At the beginning of each scriptlet, the command '\\cd $PWD' is + inserted. This ensures that 'cd' is not aliased to something + peculiar and each scriptlet starts life in the execution directory. + 3. At the end of each scriptlet, the command 'echo mumble' is + appended. The program you use as a shell must emit the single + argument 'mumble' on a line by itself. + + +File: autogen.info, Node: Testimonial, Prev: csh/zsh caveat, Up: Introduction + +1.4 A User's Perspective +======================== + +Alexandre wrote: +> +> I'd appreciate opinions from others about advantages/disadvantages of +> each of these macro packages. + + I am using AutoGen in my pet project, and find one of its best points +to be that it separates the operational data from the implementation. + + Indulge me for a few paragraphs, and all will be revealed: In the +manual, Bruce cites the example of maintaining command line flags inside +the source code; traditionally spreading usage information, flag names, +letters and processing across several functions (if not files). +Investing the time in writing a sort of boiler plate (a template in +AutoGen terminology) pays by moving all of the option details (usage, +flags names etc.) into a well structured table (a definition file if +you will), so that adding a new command line option becomes a simple +matter of adding a set of details to the table. + + So far so good! Of course, now that there is a template, writing all +of that tedious optargs processing and usage functions is no longer an +issue. Creating a table of the options needed for the new project and +running AutoGen generates all of the option processing code in C +automatically from just the tabular data. AutoGen in fact already ships +with such a template... AutoOpts. + + One final consequence of the good separation in the design of AutoGen +is that it is retargetable to a greater extent. The +egcs/gcc/fixinc/inclhack.def can equally be used (with different +templates) to create a shell script (inclhack.sh) or a c program +(fixincl.c). + + This is just the tip of the iceberg. AutoGen is far more powerful +than these examples might indicate, and has many other varied uses. I +am certain Bruce or I could supply you with many and varied examples, +and I would heartily recommend that you try it for your project and see +for yourself how it compares to m4. + + As an aside, I would be interested to see whether someone might be +persuaded to rationalise autoconf with AutoGen in place of m4... Ben, +are you listening? autoconf-3.0! 'kay? =)O| + +Sincerely, + Gary V. Vaughan + + +File: autogen.info, Node: Definitions File, Next: Template File, Prev: Introduction, Up: Top + +2 Definitions File +****************** + +This chapter describes the syntax and semantics of the AutoGen +definition file. In order to instantiate a template, you normally must +provide a definitions file that identifies itself and contains some +value definitions. Consequently, we keep it very simple. For +"advanced" users, there are preprocessing directives, sparse arrays, +named indexes and comments that may be used as well. + + The definitions file is used to associate values with names. Every +value is implicitly an array of values, even if there is only one value. +Values may be either simple strings or compound collections of +name-value pairs. An array may not contain both simple and compound +members. Fundamentally, it is as simple as: + + prog-name = "autogen"; + flag = { + name = templ_dirs; + value = L; + descrip = "Template search directory list"; + }; + + For purposes of commenting and controlling the processing of the +definitions, C-style comments and most C preprocessing directives are +honored. The major exception is that the '#if' directive is ignored, +along with all following text through the matching '#endif' directive. +The C preprocessor is not actually invoked, so C macro substitution is +*not* performed. + +* Menu: + +* Identification:: The Identification Definition +* Definitions:: Named Definitions +* Index Assignments:: Assigning an Index to a Definition +* Dynamic Text:: Dynamic Text +* Directives:: Controlling What Gets Processed +* Predefines:: Pre-defined Names +* Comments:: Commenting Your Definitions +* Example:: What it all looks like. +* Full Syntax:: Finite State Machine Grammar +* Alternate Definition:: Alternate Definition Forms + + +File: autogen.info, Node: Identification, Next: Definitions, Up: Definitions File + +2.1 The Identification Definition +================================= + +The first definition in this file is used to identify it as a AutoGen +file. It consists of the two keywords, 'autogen' and 'definitions' +followed by the default template name and a terminating semi-colon +(';'). That is: + + AutoGen Definitions TEMPLATE-NAME; + +Note that, other than the name TEMPLATE-NAME, the words 'AutoGen' and +'Definitions' are searched for without case sensitivity. Most lookups +in this program are case insensitive. + +Also, if the input contains more identification definitions, they will +be ignored. This is done so that you may include (*note Directives::) +other definition files without an identification conflict. + +AutoGen uses the name of the template to find the corresponding template +file. It searches for the file in the following way, stopping when it +finds the file: + + 1. It tries to open './TEMPLATE-NAME'. If it fails, + 2. it tries './TEMPLATE-NAME.tpl'. + 3. It searches for either of these files in the directories listed in + the templ-dirs command line option. + + If AutoGen fails to find the template file in one of these places, it +prints an error message and exits. + + +File: autogen.info, Node: Definitions, Next: Index Assignments, Prev: Identification, Up: Definitions File + +2.2 Named Definitions +===================== + +A name is a sequence of characters beginning with an alphabetic +character ('a' through 'z') followed by zero or more alpha-numeric +characters and/or separator characters: hyphen ('-'), underscore ('_') +or carat ('^'). Names are case insensitive. + + Any name may have multiple values associated with it. Every name may +be considered a sparse array of one or more elements. If there is more +than one value, the values my be accessed by indexing the value with +'[index]' or by iterating over them using the FOR (*note FOR::) AutoGen +macro on it, as described in the next chapter. Sparse arrays are +specified by specifying an index when defining an entry (*note Assigning +an Index to a Definition: Index Assignments.). + + There are two kinds of definitions, 'simple' and 'compound'. They +are defined thus (*note Full Syntax::): + + compound_name '=' '{' definition-list '}' ';' + + simple-name[2] '=' string ';' + + no^text^name ';' + +'simple-name' has the third index (index number 2) defined here. +'No^text^name' is a simple definition with a shorthand empty string +value. The string values for definitions may be specified in any of +several formation rules. + +* Menu: + +* def-list:: Definition List +* double-quote-string:: Double Quote String +* single-quote-string:: Single Quote String +* simple-string:: An Unquoted String +* shell-generated:: Shell Output String +* scheme-generated:: Scheme Result String +* here-string:: A Here String +* concat-string:: Concatenated Strings + + +File: autogen.info, Node: def-list, Next: double-quote-string, Up: Definitions + +2.2.1 Definition List +--------------------- + +'definition-list' is a list of definitions that may or may not contain +nested compound definitions. Any such definitions may *only* be +expanded within a 'FOR' block iterating over the containing compound +definition. *Note FOR::. + + Here is, again, the example definitions from the previous chapter, +with three additional name value pairs. Two with an empty value +assigned (FIRST and LAST), and a "global" GROUP_NAME. + + autogen definitions list; + group_name = example; + list = { list_element = alpha; first; + list_info = "some alpha stuff"; }; + list = { list_info = "more beta stuff"; + list_element = beta; }; + list = { list_element = omega; last; + list_info = "final omega stuff"; }; + + +File: autogen.info, Node: double-quote-string, Next: single-quote-string, Prev: def-list, Up: Definitions + +2.2.2 Double Quote String +------------------------- + +The string follows the C-style escaping, using the backslash to quote +(escape) the following character(s). Certain letters are translated to +various control codes (e.g. '\n', '\f', '\t', etc.). 'x' introduces a +two character hex code. '0' (the digit zero) introduces a one to three +character octal code (note: an octal byte followed by a digit must be +represented with three octal digits, thus: '"\0001"' yielding a NUL byte +followed by the ASCII digit 1). Any other character following the +backslash escape is simply inserted, without error, into the string +being formed. + + Like ANSI "C", a series of these strings, possibly intermixed with +single quote strings, will be concatenated together. + + +File: autogen.info, Node: single-quote-string, Next: simple-string, Prev: double-quote-string, Up: Definitions + +2.2.3 Single Quote String +------------------------- + +This is similar to the shell single-quote string. However, escapes '\' +are honored before another escape, single quotes ''' and hash characters +'#'. This latter is done specifically to disambiguate lines starting +with a hash character inside of a quoted string. In other words, + + fumble = ' + #endif + '; + + could be misinterpreted by the definitions scanner, whereas this +would not: + + fumble = ' + \#endif + '; + + + As with the double quote string, a series of these, even intermixed +with double quote strings, will be concatenated together. + + +File: autogen.info, Node: simple-string, Next: shell-generated, Prev: single-quote-string, Up: Definitions + +2.2.4 An Unquoted String +------------------------ + +A simple string that does not contain white space may be left unquoted. +The string must not contain any of the characters special to the +definition text (i.e., '"', '#', ''', '(', ')', ',', ';', '<', '=', '>', +'[', ']', '`', '{', or '}'). This list is subject to change, but it +will never contain underscore ('_'), period ('.'), slash ('/'), colon +(':'), hyphen ('-') or backslash ('\\'). Basically, if the string looks +like it is a normal DOS or UNIX file or variable name, and it is not one +of two keywords ('autogen' or 'definitions') then it is OK to not quote +it, otherwise you should. + + +File: autogen.info, Node: shell-generated, Next: scheme-generated, Prev: simple-string, Up: Definitions + +2.2.5 Shell Output String +------------------------- + +This is assembled according to the same rules as the double quote +string, except that there is no concatenation of strings and the +resulting string is written to a shell server process. The definition +takes on the value of the output string. + + NB The text is interpreted by a server shell. There may be left over +state from previous server shell processing. This scriptlet may also +leave state for subsequent processing. However, a 'cd' to the original +directory is always issued before the new command is issued. + + +File: autogen.info, Node: scheme-generated, Next: here-string, Prev: shell-generated, Up: Definitions + +2.2.6 Scheme Result String +-------------------------- + +A scheme result string must begin with an open parenthesis '('. The +scheme expression will be evaluated by Guile and the value will be the +result. The AutoGen expression functions are *dis*abled at this stage, +so do not use them. + + +File: autogen.info, Node: here-string, Next: concat-string, Prev: scheme-generated, Up: Definitions + +2.2.7 A Here String +------------------- + +A 'here string' is formed in much the same way as a shell here doc. It +is denoted with two less than characters('<<') and, optionally, a +hyphen. This is followed by optional horizontal white space and an +ending marker-identifier. This marker must follow the syntax rules for +identifiers. Unlike the shell version, however, you must not quote this +marker. + + The resulting string will start with the first character on the next +line and continue up to but not including the newline that precedes the +line that begins with the marker token. The characters are copied +directly into the result string. Mostly. + + If a hyphen follows the less than characters, then leading tabs will +be stripped and the terminating marker will be recognized even if +preceded by tabs. Also, if the first character on the line (after +removing tabs) is a backslash and the next character is a tab or space, +then the backslash will be removed as well. No other kind of processing +is done on this string. + + Here are three examples: + str1 = <<- STR_END + $quotes = " ' ` + STR_END; + + str2 = << STR_END + $quotes = " ' ` + STR_END; + STR_END; + + str3 = <<- STR_END + \ $quotes = " ' ` + STR_END; + The first string contains no new line characters. The first +character is the dollar sign, the last the back quote. + + The second string contains one new line character. The first +character is the tab character preceding the dollar sign. The last +character is the semicolon after the 'STR_END'. That 'STR_END' does not +end the string because it is not at the beginning of the line. In the +preceding case, the leading tab was stripped. + + The third string is almost identical to the first, except that the +first character is a tab. That is, it exactly matches the first line of +the second string. + + +File: autogen.info, Node: concat-string, Prev: here-string, Up: Definitions + +2.2.8 Concatenated Strings +-------------------------- + +If single or double quote characters are used, then you also have the +option, a la ANSI-C syntax, of implicitly concatenating a series of them +together, with intervening white space ignored. + + NB You *cannot* use directives to alter the string content. That is, + + str = "fumble" + #ifdef LATER + "stumble" + #endif + ; + +will result in a syntax error. The preprocessing directives are not +carried out by the C preprocessor. However, + + str = '"fumble\n" + #ifdef LATER + " stumble\n" + #endif + '; + +*Will* work. It will enclose the '#ifdef LATER' and '#endif' in the +string. But it may also wreak havoc with the definition processing +directives. The hash characters in the first column should be +disambiguated with an escape '\' or join them with previous lines: +'"fumble\n#ifdef LATER...'. + + +File: autogen.info, Node: Index Assignments, Next: Dynamic Text, Prev: Definitions, Up: Definitions File + +2.3 Assigning an Index to a Definition +====================================== + +In AutoGen, every name is implicitly an array of values. When assigning +values, they are usually implicitly assigned to the next highest slot. +They can also be specified explicitly: + + mumble[9] = stumble; + mumble[0] = grumble; + +If, subsequently, you assign a value to 'mumble' without an index, its +index will be '10', not '1'. If indexes are specified, they must not +cause conflicts. + + '#define'-d names may also be used for index values. This is +equivalent to the above: + + #define FIRST 0 + #define LAST 9 + mumble[LAST] = stumble; + mumble[FIRST] = grumble; + + All values in a range do *not* have to be filled in. If you leave +gaps, then you will have a sparse array. This is fine (*note FOR::). +You have your choice of iterating over all the defined values, or +iterating over a range of slots. This: + + [+ FOR mumble +][+ ENDFOR +] + +iterates over all and only the defined entries, whereas this: + + [+ FOR mumble (for-by 1) +][+ ENDFOR +] + +will iterate over all 10 "slots". Your template will likely have to +contain something like this: + + [+ IF (exist? (sprintf "mumble[%d]" (for-index))) +] + +or else "mumble" will have to be a compound value that, say, always +contains a "grumble" value: + + [+ IF (exist? "grumble") +] + + +File: autogen.info, Node: Dynamic Text, Next: Directives, Prev: Index Assignments, Up: Definitions File + +2.4 Dynamic Text +================ + +There are several methods for including dynamic content inside a +definitions file. Three of them are mentioned above (*note +shell-generated:: and *note scheme-generated::) in the discussion of +string formation rules. Another method uses the '#shell' processing +directive. It will be discussed in the next section (*note +Directives::). Guile/Scheme may also be used to yield to create +definitions. + + When the Scheme expression is preceded by a backslash and single +quote, then the expression is expected to be an alist of names and +values that will be used to create AutoGen definitions. + +This method can be be used as follows: + + \'( (name (value-expression)) + (name2 (another-expr)) ) + +This is entirely equivalent to: + + name = (value-expression); + name2 = (another-expr); + +Under the covers, the expression gets handed off to a Guile function +named 'alist->autogen-def' in an expression that looks like this: + + (alist->autogen-def + ( (name (value-expression)) (name2 (another-expr)) ) ) + + +File: autogen.info, Node: Directives, Next: Predefines, Prev: Dynamic Text, Up: Definitions File + +2.5 Controlling What Gets Processed +=================================== + +Definition processing directives can *only* be processed if the '#' +character is the first character on a line. Also, if you want a '#' as +the first character of a line in one of your string assignments, you +should either escape it by preceding it with a backslash '\', or by +embedding it in the string as in '"\n#"'. + + All of the normal C preprocessing directives are recognized, though +several are ignored. There is also an additional '#shell' - '#endshell' +pair. Another minor difference is that AutoGen directives must have the +hash character ('#') in column 1. Unrecognized directives produce an +error. + + The final tweak is that '#!' is treated as a comment line. Using +this feature, you can use: '#! /usr/local/bin/autogen' as the first line +of a definitions file, set the mode to executable and "run" the +definitions file as if it were a direct invocation of AutoGen. This was +done for its hack value. + + The AutoGen recognized directives are: +'#assert' + This directive is processed, but only if the expression begins with + either a back quote ('`') or an open parenthesis ('('). Text + within the back quotes are handed off to the shell for processing + and parenthesized text is handed off to Guile. Multiple line + expressions must be joined with backslashes. + + If the 'shell-script' or 'scheme-expr' do not yield 'true' valued + results, autogen will be aborted. If '<anything else>' or nothing + at all is provided, then this directive is ignored. + + The result is 'false' (and fails) if the result is empty, the + number zero, or a string that starts with the letters 'n' or 'f' + ("no" or "false"). + +'#define' + Will add the name to the define list as if it were a DEFINE program + argument. Its value will be the first non-whitespace token + following the name. Quotes are *not* processed. + + After the definitions file has been processed, any remaining + entries in the define list will be added to the environment. + +'#elif' + Marks a transition in the #if directive. Error when out of + context. #if blocks are always ignored. + +'#else' + This must follow an '#if', '#ifdef' or '#ifndef'. If it follows + the '#if', then it will be ignored. Otherwise, it will change the + processing state to the reverse of what it was. + +'#endif' + This must follow an '#if', '#ifdef' or '#ifndef'. In all cases, + this will resume normal processing of text. + +'#endmac' + Marks the end of the #macdef directive. Error when out of context. + +'#endshell' + Marks the end of the #shell directive. Error when out of context. + +'#error' + This directive will cause AutoGen to stop processing and exit with + a status of EXIT_FAILURE. + +'#ident' + Ignored directive. + +'#if' + '#if' expressions are not analyzed. *Everything* from here to the + matching '#endif' is skipped. + +'#ifdef' + The definitions that follow, up to the matching '#endif' will be + processed only if there is a corresponding '-Dname' command line + option or if a '#define' of that name has been previously + encountered. + +'#ifndef' + The definitions that follow, up to the matching '#endif' will be + processed only if the named value has *not* been defined. + +'#include' + This directive will insert definitions from another file into the + current collection. If the file name is adorned with double quotes + or angle brackets (as in a C program), then the include is ignored. + +'#let' + Ignored directive. + +'#line' + Alters the current line number and/or file name. You may wish to + use this directive if you extract definition source from other + files. 'getdefs' uses this mechanism so AutoGen will report the + correct file and approximate line number of any errors found in + extracted definitions. + +'#macdef' + This is a new AT&T research preprocessing directive. Basically, it + is a multi-line #define that may include other preprocessing + directives. Text between this line and a #endmac directive are + ignored. + +'#option' + This directive will pass the option name and associated text to the + AutoOpts optionLoadLine routine (*note libopts-optionLoadLine::). + The option text may span multiple lines by continuing them with a + backslash. The backslash/newline pair will be replaced with two + space characters. This directive may be used to set a search path + for locating template files For example, this: + + #option templ-dirs $ENVVAR/dirname + will direct autogen to use the 'ENVVAR' environment variable to + find a directory named 'dirname' that (may) contain templates. + Since these directories are searched in most recently supplied + first order, search directories supplied in this way will be + searched before any supplied on the command line. + +'#pragma' + Ignored directive. + +'#shell' + Invokes '$SHELL' or '/bin/sh' on a script that should generate + AutoGen definitions. It does this using the same server process + that handles the back-quoted '`' text. The block of text handed to + the shell is terminated with the #endshell directive. + + *CAUTION* let not your '$SHELL' be 'csh'. + +'#undef' + Will remove any entries from the define list that match the undef + name pattern. + + +File: autogen.info, Node: Predefines, Next: Comments, Prev: Directives, Up: Definitions File + +2.6 Pre-defined Names +===================== + +When AutoGen starts, it tries to determine several names from the +operating environment and put them into environment variables for use in +both '#ifdef' tests in the definitions files and in shell scripts with +environment variable tests. '__autogen__' is always defined. For other +names, AutoGen will first try to use the POSIX version of the +'sysinfo(2)' system call. Failing that, it will try for the POSIX +'uname(2)' call. If neither is available, then only "'__autogen__'" +will be inserted into the environment. In all cases, the associated +names are converted to lower case, surrounded by doubled underscores and +non-symbol characters are replaced with underscores. + + With Solaris on a sparc platform, 'sysinfo(2)' is available. The +following strings are used: + + * 'SI_SYSNAME' (e.g., "__sunos__") + * 'SI_HOSTNAME' (e.g., "__ellen__") + * 'SI_ARCHITECTURE' (e.g., "__sparc__") + * 'SI_HW_PROVIDER' (e.g., "__sun_microsystems__") + * 'SI_PLATFORM' (e.g., "__sun_ultra_5_10__") + * 'SI_MACHINE' (e.g., "__sun4u__") + + For Linux and other operating systems that only support the +'uname(2)' call, AutoGen will use these values: + + * 'sysname' (e.g., "__linux__") + * 'machine' (e.g., "__i586__") + * 'nodename' (e.g., "__bach__") + + By testing these pre-defines in my definitions, you can select pieces +of the definitions without resorting to writing shell scripts that parse +the output of 'uname(1)'. You can also segregate real C code from +autogen definitions by testing for "'__autogen__'". + + #ifdef __bach__ + location = home; + #else + location = work; + #endif + + +File: autogen.info, Node: Comments, Next: Example, Prev: Predefines, Up: Definitions File + +2.7 Commenting Your Definitions +=============================== + +The definitions file may contain C and C++ style comments. + + /* + * This is a comment. It continues for several lines and closes + * when the characters '*' and '/' appear together. + */ + // this comment is a single line comment + + +File: autogen.info, Node: Example, Next: Full Syntax, Prev: Comments, Up: Definitions File + +2.8 What it all looks like. +=========================== + +This is an extended example: + + autogen definitions 'template-name'; + /* + * This is a comment that describes what these + * definitions are all about. + */ + global = "value for a global text definition."; + + /* + * Include a standard set of definitions + */ + #include standards.def + + a_block = { + a_field; + a_subblock = { + sub_name = first; + sub_field = "sub value."; + }; + + #ifdef FEATURE + a_subblock = { + sub_name = second; + }; + #endif + + }; + + +File: autogen.info, Node: Full Syntax, Next: Alternate Definition, Prev: Example, Up: Definitions File + +2.9 Finite State Machine Grammar +================================ + +The preprocessing directives and comments are not part of the grammar. +They are handled by the scanner/lexer. The following was extracted +directly from the generated defParse-fsm.c source file. The "EVT:" is +the token seen, the "STATE:" is the current state and the entries in +this table describe the next state and the action to take. Invalid +transitions were removed from the table. + + dp_trans_table[ DP_STATE_CT ][ DP_EVENT_CT ] = { + + /* STATE 0: DP_ST_INIT */ + { { DP_ST_NEED_DEF, NULL }, /* EVT: AUTOGEN */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: DEFINITIONS */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: End-Of-File */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: VAR_NAME */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: OTHER_NAME */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: STRING */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: HERE_STRING */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: DELETE_ENT */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: NUMBER */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: ; */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: = */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: , */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: { */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: } */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: [ */ + { DP_ST_INVALID, dp_do_invalid } /* EVT: ] */ + + /* STATE 1: DP_ST_NEED_DEF */ + { { DP_ST_INVALID, dp_do_invalid }, /* EVT: AUTOGEN */ + { DP_ST_NEED_TPL, NULL }, /* EVT: DEFINITIONS */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: End-Of-File */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: VAR_NAME */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: OTHER_NAME */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: STRING */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: HERE_STRING */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: DELETE_ENT */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: NUMBER */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: ; */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: = */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: , */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: { */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: } */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: [ */ + { DP_ST_INVALID, dp_do_invalid } /* EVT: ] */ + + /* STATE 2: DP_ST_NEED_TPL */ + { { DP_ST_INVALID, dp_do_invalid }, /* EVT: AUTOGEN */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: DEFINITIONS */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: End-Of-File */ + { DP_ST_NEED_SEMI, dp_do_tpl_name }, /* EVT: VAR_NAME */ + { DP_ST_NEED_SEMI, dp_do_tpl_name }, /* EVT: OTHER_NAME */ + { DP_ST_NEED_SEMI, dp_do_tpl_name }, /* EVT: STRING */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: HERE_STRING */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: DELETE_ENT */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: NUMBER */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: ; */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: = */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: , */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: { */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: } */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: [ */ + { DP_ST_INVALID, dp_do_invalid } /* EVT: ] */ + + /* STATE 3: DP_ST_NEED_SEMI */ + { { DP_ST_INVALID, dp_do_invalid }, /* EVT: AUTOGEN */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: DEFINITIONS */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: End-Of-File */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: VAR_NAME */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: OTHER_NAME */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: STRING */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: HERE_STRING */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: DELETE_ENT */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: NUMBER */ + { DP_ST_NEED_NAME, NULL }, /* EVT: ; */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: = */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: , */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: { */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: } */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: [ */ + { DP_ST_INVALID, dp_do_invalid } /* EVT: ] */ + + /* STATE 4: DP_ST_NEED_NAME */ + { { DP_ST_NEED_DEF, NULL }, /* EVT: AUTOGEN */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: DEFINITIONS */ + { DP_ST_DONE, dp_do_need_name_end }, /* EVT: End-Of-File */ + { DP_ST_HAVE_NAME, dp_do_need_name_var_name }, /* EVT: VAR_NAME */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: OTHER_NAME */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: STRING */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: HERE_STRING */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: DELETE_ENT */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: NUMBER */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: ; */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: = */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: , */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: { */ + { DP_ST_HAVE_VALUE, dp_do_end_block }, /* EVT: } */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: [ */ + { DP_ST_INVALID, dp_do_invalid } /* EVT: ] */ + + /* STATE 5: DP_ST_HAVE_NAME */ + { { DP_ST_INVALID, dp_do_invalid }, /* EVT: AUTOGEN */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: DEFINITIONS */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: End-Of-File */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: VAR_NAME */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: OTHER_NAME */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: STRING */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: HERE_STRING */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: DELETE_ENT */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: NUMBER */ + { DP_ST_NEED_NAME, dp_do_empty_val }, /* EVT: ; */ + { DP_ST_NEED_VALUE, dp_do_have_name_lit_eq }, /* EVT: = */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: , */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: { */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: } */ + { DP_ST_NEED_IDX, NULL }, /* EVT: [ */ + { DP_ST_INVALID, dp_do_invalid } /* EVT: ] */ + + /* STATE 6: DP_ST_NEED_VALUE */ + { { DP_ST_INVALID, dp_do_invalid }, /* EVT: AUTOGEN */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: DEFINITIONS */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: End-Of-File */ + { DP_ST_HAVE_VALUE, dp_do_str_value }, /* EVT: VAR_NAME */ + { DP_ST_HAVE_VALUE, dp_do_str_value }, /* EVT: OTHER_NAME */ + { DP_ST_HAVE_VALUE, dp_do_str_value }, /* EVT: STRING */ + { DP_ST_HAVE_VALUE, dp_do_str_value }, /* EVT: HERE_STRING */ + { DP_ST_NEED_NAME, dp_do_need_value_delete_ent }, /* EVT: DELETE_ENT */ + { DP_ST_HAVE_VALUE, dp_do_str_value }, /* EVT: NUMBER */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: ; */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: = */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: , */ + { DP_ST_NEED_NAME, dp_do_start_block }, /* EVT: { */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: } */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: [ */ + { DP_ST_INVALID, dp_do_invalid } /* EVT: ] */ + + /* STATE 7: DP_ST_NEED_IDX */ + { { DP_ST_INVALID, dp_do_invalid }, /* EVT: AUTOGEN */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: DEFINITIONS */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: End-Of-File */ + { DP_ST_NEED_CBKT, dp_do_indexed_name }, /* EVT: VAR_NAME */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: OTHER_NAME */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: STRING */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: HERE_STRING */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: DELETE_ENT */ + { DP_ST_NEED_CBKT, dp_do_indexed_name }, /* EVT: NUMBER */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: ; */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: = */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: , */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: { */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: } */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: [ */ + { DP_ST_INVALID, dp_do_invalid } /* EVT: ] */ + + /* STATE 8: DP_ST_NEED_CBKT */ + { { DP_ST_INVALID, dp_do_invalid }, /* EVT: AUTOGEN */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: DEFINITIONS */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: End-Of-File */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: VAR_NAME */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: OTHER_NAME */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: STRING */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: HERE_STRING */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: DELETE_ENT */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: NUMBER */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: ; */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: = */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: , */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: { */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: } */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: [ */ + { DP_ST_INDX_NAME, NULL } /* EVT: ] */ + + /* STATE 9: DP_ST_INDX_NAME */ + { { DP_ST_INVALID, dp_do_invalid }, /* EVT: AUTOGEN */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: DEFINITIONS */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: End-Of-File */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: VAR_NAME */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: OTHER_NAME */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: STRING */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: HERE_STRING */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: DELETE_ENT */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: NUMBER */ + { DP_ST_NEED_NAME, dp_do_empty_val }, /* EVT: ; */ + { DP_ST_NEED_VALUE, NULL }, /* EVT: = */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: , */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: { */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: } */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: [ */ + { DP_ST_INVALID, dp_do_invalid } /* EVT: ] */ + + /* STATE 10: DP_ST_HAVE_VALUE */ + { { DP_ST_INVALID, dp_do_invalid }, /* EVT: AUTOGEN */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: DEFINITIONS */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: End-Of-File */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: VAR_NAME */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: OTHER_NAME */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: STRING */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: HERE_STRING */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: DELETE_ENT */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: NUMBER */ + { DP_ST_NEED_NAME, NULL }, /* EVT: ; */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: = */ + { DP_ST_NEED_VALUE, dp_do_next_val }, /* EVT: , */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: { */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: } */ + { DP_ST_INVALID, dp_do_invalid }, /* EVT: [ */ + { DP_ST_INVALID, dp_do_invalid } /* EVT: ] */ + + +File: autogen.info, Node: Alternate Definition, Prev: Full Syntax, Up: Definitions File + +2.10 Alternate Definition Forms +=============================== + +There are several methods for supplying data values for templates. + +'no definitions' + It is entirely possible to write a template that does not depend + upon external definitions. Such a template would likely have an + unvarying output, but be convenient nonetheless because of an + external library of either AutoGen or Scheme functions, or both. + This can be accommodated by providing the '--override-tpl' and + '--no-definitions' options on the command line. *Note autogen + Invocation::. + +'CGI' + AutoGen behaves as a CGI server if the definitions input is from + stdin and the environment variable 'REQUEST_METHOD' is defined and + set to either "GET" or "POST", *Note AutoGen CGI::. Obviously, all + the values are constrained to strings because there is no way to + represent nested values. + +'XML' + AutoGen comes with a program named, 'xml2ag'. Its output can + either be redirected to a file for later use, or the program can be + used as an AutoGen wrapper. *Note xml2ag Invocation::. + + The introductory template example (*note Example Usage::) can be + rewritten in XML as follows: + + <EXAMPLE template="list.tpl"> + <LIST list_element="alpha" + list_info="some alpha stuff"/> + <LIST list_info="more beta stuff" + list_element="beta"/> + <LIST list_element="omega" + list_info="final omega stuff"/> + </EXAMPLE> + + A more XML-normal form might look like this: + <EXAMPLE template="list.tpl"> + <LIST list_element="alpha">some alpha stuff</LIST> + <LIST list_element="beta" >more beta stuff</LIST> + <LIST list_element="omega">final omega stuff</LIST> + </EXAMPLE> + but you would have to change the template 'list-info' references + into 'text' references. + +'standard AutoGen definitions' + Of course. :-) + + +File: autogen.info, Node: Template File, Next: Augmenting AutoGen, Prev: Definitions File, Up: Top + +3 Template File +*************** + +The AutoGen template file defines the content of the output text. It is +composed of two parts. The first part consists of a pseudo macro +invocation and commentary. It is followed by the template proper. + + This pseudo macro is special. It is used to identify the file as a +AutoGen template file, fixing the starting and ending marks for the +macro invocations in the rest of the file, specifying the list of +suffixes to be generated by the template and, optionally, the shell to +use for processing shell commands embedded in the template. + + AutoGen-ing a file consists of copying text from the template to the +output file until a start macro marker is found. The text from the +start marker to the end marker constitutes the macro text. AutoGen +macros may cause sections of the template to be skipped or processed +several times. The process continues until the end of the template is +reached. The process is repeated once for each suffix specified in the +pseudo macro. + + This chapter describes the format of the AutoGen template macros and +the usage of the AutoGen native macros. Users may augment these by +defining their own macros, *Note DEFINE::. + +* Menu: + +* pseudo macro:: Format of the Pseudo Macro +* naming values:: Naming a value +* expression syntax:: Macro Expression Syntax +* AutoGen Functions:: AutoGen Scheme Functions +* Common Functions:: Common Scheme Functions +* native macros:: AutoGen Native Macros +* output controls:: Redirecting Output + + +File: autogen.info, Node: pseudo macro, Next: naming values, Up: Template File + +3.1 Format of the Pseudo Macro +============================== + +The pseudo macro is used to tell AutoGen how to process a template. It +tells autogen: + + 1. The start macro marker. It consists of punctuation characters used + to demarcate the start of a macro. It may be up to seven + characters long and must be the first non-whitespace characters in + the file. + + It is generally a good idea to use some sort of opening bracket in + the starting macro and closing bracket in the ending macro (e.g. + '{', '(', '[', or even '<' in the starting macro). It helps both + visually and with editors capable of finding a balancing + parenthesis. + + 2. That start marker must be immediately followed by the identifier + strings "AutoGen5" and then "template", though capitalization is + not important. + +The next several components may be intermingled: + + 3. Zero, one or more suffix specifications tell AutoGen how many times + to process the template file. No suffix specifications mean that + it is to be processed once and that the generated text is to be + written to 'stdout'. The current suffix for each pass can be + determined with the '(suffix)' scheme function (*note SCM + suffix::). + + The suffix specification consists of a sequence of POSIX compliant + file name characters and, optionally, an equal sign and a file name + formatting specification. That specification may be either an + ordinary sequence of file name characters with zero, one or two + "%s" formatting sequences in it, or else it may be a Scheme + expression that, when evaluated, produces such a string. The + Scheme result may not be empty. The two string arguments allowed + for that string are the base name of the definition file, and the + current suffix (that being the text to the left of the equal sign). + (Note: "POSIX compliant file name characters" consist of + alphanumerics plus the period ('.'), hyphen ('-') and underscore + ('_') characters.) + + If the suffix begins with one of these three latter characters and + a formatting string is not specified, then that character is + presumed to be the suffix separator. Otherwise, without a + specified format string, a single period will separate the suffix + from the base name in constructing the output file name. + + 4. Shell specification: to specify that the template was written + expecting a particular shell to run the shell commands. By + default, the shell used is the autoconf-ed 'CONFIG_SHELL'. This + will usually be '/bin/sh'. The shell is specified by a hash mark + ('#') followed by an exclamation mark ('!') followed by a full-path + file name (e.g. '/usr/xpg4/bin/sh' on Solaris): + [= Autogen5 Template c + #!/usr/xpg4/bin/sh + =] + + 5. Comments: blank lines, lines starting with a hash mark ('#') and + not specifying a shell, and edit mode markers (text between pairs + of '-*-' strings) are all treated as comments. + + 6. Some scheme expressions may be inserted in order to make + configuration changes before template processing begins. before + template processing begins means that there is no current output + file, no current suffix and, basically, none of the AutoGen + specific functions (*note AutoGen Functions::) may be invoked. + + The scheme expression can also be used, for example, to save a + pre-existing output file for later text extraction (*note SCM + extract::). + + (shellf "mv -f %1$s.c %1$s.sav" (base-name)) + +After these must come the end macro marker: + + 6. The punctuation characters used to demarcate the end of a macro. + Like the start marker, it must consist of seven or fewer + punctuation characters. + + The ending macro marker has a few constraints on its content. Some +of them are just advisory, though. There is no special check for +advisory restrictions. + + * It must not begin with a POSIX file name character (hyphen '-', + underscore '_' or period '.'), the backslash ('\') or open + parenthesis ('('). These are used to identify a suffix + specification, indicate Scheme code and trim white space. + + * If it begins with an equal sign, then it must be separated from any + suffix specification by white space. + + * The closing marker may not begin with an open parenthesis, as that + is used to enclose a scheme expression. + + * It cannot begin with a backslash, as that is used to indicate white + space trimming after the end macro mark. If, in the body of the + template, you put the backslash character ('\') before the end + macro mark, then any white space characters after the mark and + through the newline character are trimmed. + + * It is also helpful to avoid using the comment marker ('#'). It + might be seen as a comment within the pseudo macro. + + * You should avoid using any of the quote characters double, single + or back-quote. It won't confuse AutoGen, but it might well confuse + you and/or your editor. + + As an example, assume we want to use '[+' and '+]' as the start and +end macro markers, and we wish to produce a '.c' and a '.h' file, then +the pseudo macro might look something like this: + + [+ AutoGen5 template -*- Mode: emacs-mode-of-choice -*- + h=chk-%s.h + c + # make sure we don't use csh: + (setenv "SHELL" "/bin/sh") +] + + The template proper starts after the pseudo-macro. The starting +character is either the first non-whitespace character or the first +character after the newline that follows the end macro marker. + + +File: autogen.info, Node: naming values, Next: expression syntax, Prev: pseudo macro, Up: Template File + +3.2 Naming a value +================== + +When an AutoGen value is specified in a template, it is specified by +name. The name may be a simple name, or a compound name of several +components. Since each named value in AutoGen is implicitly an array of +one or more values, each component may have an index associated with it. + +It looks like this: + + comp-name-1 . comp-name-2 [ 2 ] + + Note that if there are multiple components to a name, each component +name is separated by a dot ('.'). Indexes follow a component name, +enclosed in square brackets ('[' and ']'). The index may be either an +integer or an integer-valued define name. The first component of the +name is searched for in the current definition level. If not found, +higher levels will be searched until either a value is found, or there +are no more definition levels. Subsequent components of the name must +be found within the context of the newly-current definition level. +Also, if the named value is prefixed by a dot ('.'), then the value +search is started in the current context only. Backtracking into other +definition levels is prevented. + + If someone rewrites this, I'll incorporate it. :-) + + +File: autogen.info, Node: expression syntax, Next: AutoGen Functions, Prev: naming values, Up: Template File + +3.3 Macro Expression Syntax +=========================== + +AutoGen has two types of expressions: full expressions and basic ones. +A full AutoGen expression can appear by itself, or as the argument to +certain AutoGen built-in macros: CASE, IF, ELIF, INCLUDE, INVOKE +(explicit invocation, *note INVOKE::), and WHILE. If it appears by +itself, the result is inserted into the output. If it is an argument to +one of these macros, the macro code will act on it sensibly. + + You are constrained to basic expressions only when passing arguments +to user defined macros, *Note DEFINE::. + + The syntax of a full AutoGen expression is: + + [[ <apply-code> ] <value-name> ] [ <basic-expr-1> [ <basic-expr-2> ]] + + How the expression is evaluated depends upon the presence or absence +of the apply code and value name. The "value name" is the name of an +AutoGen defined value, or not. If it does not name such a value, the +expression result is generally the empty string. All expressions must +contain either a VALUE-NAME or a BASIC-EXPR. + +* Menu: + +* apply code:: Apply Code +* basic expression:: Basic Expression + + +File: autogen.info, Node: apply code, Next: basic expression, Up: expression syntax + +3.3.1 Apply Code +---------------- + +The "apply code" selected determines the method of evaluating the +expression. There are five apply codes, including the non-use of an +apply code. + +'no apply code' + This is the most common expression type. Expressions of this sort + come in three flavors: + + '<value-name>' + The result is the value of VALUE-NAME, if defined. Otherwise + it is the empty string. + + '<basic-expr>' + The result of the basic expression is the result of the full + expression, *Note basic expression::. + + '<value-name> <basic-expr>' + If there is a defined value for VALUE-NAME, then the + BASIC-EXPR is evaluated. Otherwise, the result is the empty + string. + +'% <value-name> <basic-expr>' + If VALUE-NAME is defined, use BASIC-EXPR as a format string for + sprintf. Then, if the BASIC-EXPR is either a back-quoted string or + a parenthesized expression, then hand the result to the appropriate + interpreter for further evaluation. Otherwise, for single and + double quote strings, the result is the result of the sprintf + operation. Naturally, if VALUE-NAME is not defined, the result is + the empty string. + + For example, assume that 'fumble' had the string value, 'stumble': + [+ % fumble `printf '%%x\\n' $%s` +] + This would cause the shell to evaluate "'printf '%x\n' $stumble'". + Assuming that the shell variable 'stumble' had a numeric value, the + expression result would be that number, in hex. Note the need for + doubled percent characters and backslashes. + +'? <value-name> <basic-expr-1> <basic-expr-2>' + Two BASIC-EXPR-s are required. If the VALUE-NAME is defined, then + the first BASIC-EXPR-1 is evaluated, otherwise BASIC-EXPR-2 is. + +'- <value-name> <basic-expr>' + Evaluate BASIC-EXPR only if VALUE-NAME is not defined. + +'?% <value-name> <basic-expr-1> <basic-expr-2>' + This combines the functions of '?' and '%'. If VALUE-NAME is + defined, it behaves exactly like '%', above, using BASIC-EXPR-1. + If not defined, then BASIC-EXPR-2 is evaluated. + + For example, assume again that 'fumble' had the string value, + 'stumble': + [+ ?% fumble `cat $%s` `pwd` +] + This would cause the shell to evaluate "'cat $stumble'". If + 'fumble' were not defined, then the result would be the name of our + current directory. + + +File: autogen.info, Node: basic expression, Prev: apply code, Up: expression syntax + +3.3.2 Basic Expression +---------------------- + +A basic expression can have one of the following forms: + +''STRING'' + A single quoted string. Backslashes can be used to protect single + quotes ('''), hash characters ('#'), or backslashes ('\') in the + string. All other characters of STRING are output as-is when the + single quoted string is evaluated. Backslashes are processed + before the hash character for consistency with the definition + syntax. It is needed there to avoid preprocessing conflicts. + +'"STRING"' + A double quoted string. This is a cooked text string as in C, + except that they are not concatenated with adjacent strings. + Evaluating "'STRING'" will output STRING with all backslash + sequences interpreted. + +'`STRING`' + A back quoted string. When this expression is evaluated, STRING is + first interpreted as a cooked string (as in '"STRING"') and + evaluated as a shell expression by the AutoGen server shell. This + expression is replaced by the 'stdout' output of the shell. + +'(STRING)' + A parenthesized expression. It will be passed to the Guile + interpreter for evaluation and replaced by the resulting value. If + there is a Scheme error in this expression, Guile 1.4 and Guile 1.6 + will report the template line number where the error occurs. Guile + 1.7 has lost this capability. + + Guile has the capability of creating and manipulating variables + that can be referenced later on in the template processing. If you + define such a variable, it is invisible to AutoGen. To reference + its value, you must use a Guile expression. For example, + [+ (define my-var "some-string-value") +] + can have that string inserted later, but only as in: + [+ (. my-var) +] + + Additionally, other than in the '%' and '?%' expressions, the Guile + expressions may be introduced with the Guile comment character + (';') and you may put a series of Guile expressions within a single + macro. They will be implicitly evaluated as if they were arguments + to the '(begin ...)' expression. The result will be the result of + the last Guile expression evaluated. + + +File: autogen.info, Node: AutoGen Functions, Next: Common Functions, Prev: expression syntax, Up: Template File + +3.4 AutoGen Scheme Functions +============================ + +AutoGen uses Guile to interpret Scheme expressions within AutoGen +macros. All of the normal Guile functions are available, plus several +extensions (*note Common Functions::) have been added to augment the +repertoire of string manipulation functions and manage the state of +AutoGen processing. + + This section describes those functions that are specific to AutoGen. +Please take note that these AutoGen specific functions are not loaded +and thus not made available until after the command line options have +been processed and the AutoGen definitions have been loaded. They may, +of course, be used in Scheme functions that get defined at those times, +but they cannot be invoked. + +* Menu: + +* SCM ag-fprintf:: 'ag-fprintf' - format to autogen stream +* SCM ag-function?:: 'ag-function?' - test for function +* SCM base-name:: 'base-name' - base output name +* SCM chdir:: 'chdir' - Change current directory +* SCM count:: 'count' - definition count +* SCM def-file:: 'def-file' - definitions file name +* SCM def-file-line:: 'def-file-line' - get a definition file+line number +* SCM dne:: 'dne' - "Do Not Edit" warning +* SCM emit:: 'emit' - emit the text for each argument +* SCM emit-string-table:: 'emit-string-table' - output a string table +* SCM error:: 'error' - display message and exit +* SCM exist?:: 'exist?' - test for value name +* SCM find-file:: 'find-file' - locate a file in the search path +* SCM first-for?:: 'first-for?' - detect first iteration +* SCM for-by:: 'for-by' - set iteration step +* SCM for-from:: 'for-from' - set initial index +* SCM for-index:: 'for-index' - get current loop index +* SCM for-sep:: 'for-sep' - set loop separation string +* SCM for-to:: 'for-to' - set ending index +* SCM found-for?:: 'found-for?' - is current index in list? +* SCM get:: 'get' - get named value +* SCM get-c-name:: 'get-c-name' - get named value, mapped to C name syntax +* SCM get-down-name:: 'get-down-name' - get lower cased named value, mapped to C name syntax +* SCM get-up-name:: 'get-up-name' - get upper cased named value, mapped to C name syntax +* SCM high-lim:: 'high-lim' - get highest value index +* SCM insert-file:: 'insert-file' - insert the contents of a (list of) files. +* SCM insert-suspended:: 'insert-suspended' - insert a named suspension in current output +* SCM last-for?:: 'last-for?' - detect last iteration +* SCM len:: 'len' - get count of values +* SCM low-lim:: 'low-lim' - get lowest value index +* SCM make-header-guard:: 'make-header-guard' - make self-inclusion guard +* SCM make-tmp-dir:: 'make-tmp-dir' - create a temporary directory +* SCM match-value?:: 'match-value?' - test for matching value +* SCM max-file-time:: 'max-file-time' - get the maximum input file modification time +* SCM mk-gettextable:: 'mk-gettextable' - print a string in a gettext-able format +* SCM out-delete:: 'out-delete' - delete current output file +* SCM out-depth:: 'out-depth' - output file stack depth +* SCM out-emit-suspended:: 'out-emit-suspended' - emit the text of suspended output +* SCM out-line:: 'out-line' - output file line number +* SCM out-move:: 'out-move' - change name of output file +* SCM out-name:: 'out-name' - current output file name +* SCM out-pop:: 'out-pop' - close current output file +* SCM out-push-add:: 'out-push-add' - append output to file +* SCM out-push-new:: 'out-push-new' - purge and create output file +* SCM out-resume:: 'out-resume' - resume suspended output file +* SCM out-suspend:: 'out-suspend' - suspend current output file +* SCM out-switch:: 'out-switch' - close and create new output +* SCM output-file-next-line:: 'output-file-next-line' - print the file name and next line number +* SCM set-option:: 'set-option' - Set a command line option +* SCM set-writable:: 'set-writable' - Make the output file be writable +* SCM stack:: 'stack' - make list of AutoGen values +* SCM stack-join:: 'stack-join' - stack values then join them +* SCM suffix:: 'suffix' - get the current suffix +* SCM tpl-file:: 'tpl-file' - get the template file name +* SCM tpl-file-line:: 'tpl-file-line' - get the template file+line number +* SCM tpl-file-next-line:: 'tpl-file-next-line' - get the template file plus next line number +* SCM warn:: 'warn' - display warning message and continue +* SCM autogen-version:: 'autogen-version' - "5.18.16" +* SCM c-file-line-fmt:: format file info as, "'#line nn "file"'" + + +File: autogen.info, Node: SCM ag-fprintf, Next: SCM ag-function?, Up: AutoGen Functions + +3.4.1 'ag-fprintf' - format to autogen stream +--------------------------------------------- + +Usage: (ag-fprintf ag-diversion format [ format-arg ... ]) +Format a string using arguments from the alist. Write to a specified +AutoGen diversion. That may be either a specified suspended output +stream (*note SCM out-suspend::) or an index into the output stack +(*note SCM out-push-new::). '(ag-fprintf 0 ...)' is equivalent to +'(emit (sprintf ...))', and '(ag-fprintf 1 ...)' sends output to the +most recently suspended output stream. + + Arguments: +ag-diversion - AutoGen diversion name or number +format - formatting string +format-arg - Optional - list of arguments to formatting string + + +File: autogen.info, Node: SCM ag-function?, Next: SCM base-name, Prev: SCM ag-fprintf, Up: AutoGen Functions + +3.4.2 'ag-function?' - test for function +---------------------------------------- + +Usage: (ag-function? ag-name) +return SCM_BOOL_T if a specified name is a user-defined AutoGen macro, +otherwise return SCM_BOOL_F. + + Arguments: +ag-name - name of AutoGen macro + + +File: autogen.info, Node: SCM base-name, Next: SCM chdir, Prev: SCM ag-function?, Up: AutoGen Functions + +3.4.3 'base-name' - base output name +------------------------------------ + +Usage: (base-name) +Returns a string containing the base name of the output file(s). +Generally, this is also the base name of the definitions file. + + This Scheme function takes no arguments. + + +File: autogen.info, Node: SCM chdir, Next: SCM count, Prev: SCM base-name, Up: AutoGen Functions + +3.4.4 'chdir' - Change current directory +---------------------------------------- + +Usage: (chdir dir) +Sets the current directory for AutoGen. Shell commands will run from +this directory as well. This is a wrapper around the Guile native +function. It returns its directory name argument and fails the program +on failure. + + Arguments: +dir - new directory name + + +File: autogen.info, Node: SCM count, Next: SCM def-file, Prev: SCM chdir, Up: AutoGen Functions + +3.4.5 'count' - definition count +-------------------------------- + +Usage: (count ag-name) +Count the number of entries for a definition. The input argument must +be a string containing the name of the AutoGen values to be counted. If +there is no value associated with the name, the result is an SCM +immediate integer value of zero. + + Arguments: +ag-name - name of AutoGen value + + +File: autogen.info, Node: SCM def-file, Next: SCM def-file-line, Prev: SCM count, Up: AutoGen Functions + +3.4.6 'def-file' - definitions file name +---------------------------------------- + +Usage: (def-file) +Get the name of the definitions file. Returns the name of the source +file containing the AutoGen definitions. + + This Scheme function takes no arguments. + + +File: autogen.info, Node: SCM def-file-line, Next: SCM dne, Prev: SCM def-file, Up: AutoGen Functions + +3.4.7 'def-file-line' - get a definition file+line number +--------------------------------------------------------- + +Usage: (def-file-line ag-name [ msg-fmt ]) +Returns the file and line number of a AutoGen defined value, using +either the default format, "from %s line %d", or else the format you +supply. For example, if you want to insert a "C" language file-line +directive, you would supply the format "# %2$d \"%1$s\"", but that is +also already supplied with the scheme variable *Note SCM +c-file-line-fmt::. You may use it thus: + + (def-file-line "ag-def-name" c-file-line-fmt) + + It is also safe to use the formatting string, "%2$d". AutoGen uses +an argument vector version of printf: *Note snprintfv::. + + Arguments: +ag-name - name of AutoGen value +msg-fmt - Optional - formatting for line message + + +File: autogen.info, Node: SCM dne, Next: SCM emit, Prev: SCM def-file-line, Up: AutoGen Functions + +3.4.8 'dne' - "Do Not Edit" warning +----------------------------------- + +Usage: (dne prefix [ first_prefix ] [ optpfx ]) +Generate a "DO NOT EDIT" or "EDIT WITH CARE" warning string. Which +depends on whether or not the '--writable' command line option was set. + + The first argument may be an option: '-D' or '-d', causing the second +and (potentially) third arguments to be interpreted as the first and +second arguments. The only useful option is '-D': + +'-D' + will add date, timestamp and version information. +'-d' + is ignored, but still accepted for compatibility with older + versions of the "dne" function where emitting the date was the + default. + + If one of these options is specified, then the "prefix" and "first" +arguments are obtained from the following arguments. The presence (or +absence) of this option can be overridden with the environment variable, +'AUTOGEN_DNE_DATE'. The date is disabled if the value is empty or +starts with one of the characters, '0nNfF' - zero or the first letter of +"no" or "false". + + The 'prefix' argument is a per-line string prefix. The optional +second argument is a prefix for the first line only and, in read-only +mode, activates editor hints. + + -*- buffer-read-only: t -*- vi: set ro: + +The warning string also includes information about the template used to +construct the file and the definitions used in its instantiation. + + Arguments: +prefix - string for starting each output line +first_prefix - Optional - for the first output line +optpfx - Optional - shifted prefix + + +File: autogen.info, Node: SCM emit, Next: SCM emit-string-table, Prev: SCM dne, Up: AutoGen Functions + +3.4.9 'emit' - emit the text for each argument +---------------------------------------------- + +Usage: (emit alist ...) +Walk the tree of arguments, displaying the values of displayable SCM +types. EXCEPTION: if the first argument is a number, then that number +is used to index the output stack. "0" is the default, the current +output. + + Arguments: +alist - list of arguments to stringify and emit + + +File: autogen.info, Node: SCM emit-string-table, Next: SCM error, Prev: SCM emit, Up: AutoGen Functions + +3.4.10 'emit-string-table' - output a string table +-------------------------------------------------- + +Usage: (emit-string-table st-name) +Emit into the current output stream a 'static char const' array named +'st-name' that will have 'NUL' bytes between each inserted string. + + Arguments: +st-name - the name of the array of characters + + +File: autogen.info, Node: SCM error, Next: SCM exist?, Prev: SCM emit-string-table, Up: AutoGen Functions + +3.4.11 'error' - display message and exit +----------------------------------------- + +Usage: (error message) +The argument is a string that printed out as part of an error message. +The message is formed from the formatting string: + + DEFINITIONS ERROR in %s line %d for %s: %s\n + + The first three arguments to this format are provided by the routine +and are: The name of the template file, the line within the template +where the error was found, and the current output file name. + + After displaying the message, the current output file is removed and +autogen exits with the EXIT_FAILURE error code. IF, however, the +argument begins with the number 0 (zero), or the string is the empty +string, then processing continues with the next suffix. + + Arguments: +message - message to display before exiting + + +File: autogen.info, Node: SCM exist?, Next: SCM find-file, Prev: SCM error, Up: AutoGen Functions + +3.4.12 'exist?' - test for value name +------------------------------------- + +Usage: (exist? ag-name) +return SCM_BOOL_T iff a specified name has an AutoGen value. The name +may include indexes and/or member names. All but the last member name +must be an aggregate definition. For example: + (exist? "foo[3].bar.baz") + will yield true if all of the following is true: +There is a member value of either group or string type named 'baz' for +some group value 'bar' that is a member of the 'foo' group with index +'3'. There may be multiple entries of 'bar' within 'foo', only one +needs to contain a value for 'baz'. + + Arguments: +ag-name - name of AutoGen value + + +File: autogen.info, Node: SCM find-file, Next: SCM first-for?, Prev: SCM exist?, Up: AutoGen Functions + +3.4.13 'find-file' - locate a file in the search path +----------------------------------------------------- + +Usage: (find-file file-name [ suffix ]) +AutoGen has a search path that it uses to locate template and definition +files. This function will search the same list for 'file-name', both +with and without the '.suffix', if provided. + + Arguments: +file-name - name of file with text +suffix - Optional - file suffix to try, too + + +File: autogen.info, Node: SCM first-for?, Next: SCM for-by, Prev: SCM find-file, Up: AutoGen Functions + +3.4.14 'first-for?' - detect first iteration +-------------------------------------------- + +Usage: (first-for? [ for_var ]) +Returns 'SCM_BOOL_T' if the named FOR loop (or, if not named, the +current innermost loop) is on the first pass through the data. Outside +of any 'FOR' loop, it returns 'SCM_UNDEFINED', *note FOR::. + + Arguments: +for_var - Optional - which for loop + + +File: autogen.info, Node: SCM for-by, Next: SCM for-from, Prev: SCM first-for?, Up: AutoGen Functions + +3.4.15 'for-by' - set iteration step +------------------------------------ + +Usage: (for-by by) +This function records the "step by" information for an AutoGen FOR +function. Outside of the FOR macro itself, this function will emit an +error. *Note FOR::. + + Arguments: +by - the iteration increment for the AutoGen FOR macro + + +File: autogen.info, Node: SCM for-from, Next: SCM for-index, Prev: SCM for-by, Up: AutoGen Functions + +3.4.16 'for-from' - set initial index +------------------------------------- + +Usage: (for-from from) +This function records the initial index information for an AutoGen FOR +function. Outside of the FOR macro itself, this function will emit an +error. *Note FOR::. + + Arguments: +from - the initial index for the AutoGen FOR macro + + +File: autogen.info, Node: SCM for-index, Next: SCM for-sep, Prev: SCM for-from, Up: AutoGen Functions + +3.4.17 'for-index' - get current loop index +------------------------------------------- + +Usage: (for-index [ for_var ]) +Returns the current index for the named 'FOR' loop. If not named, then +the index for the innermost loop. Outside of any FOR loop, it returns +'SCM_UNDEFINED', *Note FOR::. + + Arguments: +for_var - Optional - which for loop + + +File: autogen.info, Node: SCM for-sep, Next: SCM for-to, Prev: SCM for-index, Up: AutoGen Functions + +3.4.18 'for-sep' - set loop separation string +--------------------------------------------- + +Usage: (for-sep separator) +This function records the separation string that is to be inserted +between each iteration of an AutoGen FOR function. This is often +nothing more than a comma. Outside of the FOR macro itself, this +function will emit an error. + + Arguments: +separator - the text to insert between the output of each FOR iteration + + +File: autogen.info, Node: SCM for-to, Next: SCM found-for?, Prev: SCM for-sep, Up: AutoGen Functions + +3.4.19 'for-to' - set ending index +---------------------------------- + +Usage: (for-to to) +This function records the terminating value information for an AutoGen +FOR function. Outside of the FOR macro itself, this function will emit +an error. *Note FOR::. + + Arguments: +to - the final index for the AutoGen FOR macro + + +File: autogen.info, Node: SCM found-for?, Next: SCM get, Prev: SCM for-to, Up: AutoGen Functions + +3.4.20 'found-for?' - is current index in list? +----------------------------------------------- + +Usage: (found-for? [ for_var ]) +Returns SCM_BOOL_T if the currently indexed value is present, otherwise +SCM_BOOL_F. Outside of any FOR loop, it returns SCM_UNDEFINED. *Note +FOR::. + + Arguments: +for_var - Optional - which for loop + + +File: autogen.info, Node: SCM get, Next: SCM get-c-name, Prev: SCM found-for?, Up: AutoGen Functions + +3.4.21 'get' - get named value +------------------------------ + +Usage: (get ag-name [ alt-val ]) +Get the first string value associated with the name. It will either +return the associated string value (if the name resolves), the alternate +value (if one is provided), or else the empty string. + + Arguments: +ag-name - name of AutoGen value +alt-val - Optional - value if not present + + +File: autogen.info, Node: SCM get-c-name, Next: SCM get-down-name, Prev: SCM get, Up: AutoGen Functions + +3.4.22 'get-c-name' - get named value, mapped to C name syntax +-------------------------------------------------------------- + +Usage: (get-c-name ag-name) +Get the first string value associated with the name. It will either +return the associated string value (if the name resolves), the alternate +value (if one is provided), or else the empty string. The result is +passed through "string->c-name!". + + Arguments: +ag-name - name of AutoGen value + + +File: autogen.info, Node: SCM get-down-name, Next: SCM get-up-name, Prev: SCM get-c-name, Up: AutoGen Functions + +3.4.23 'get-down-name' - get lower cased named value, mapped to C name syntax +----------------------------------------------------------------------------- + +Usage: (get-down-name ag-name) +Get the first string value associated with the name. It will either +return the associated string value (if the name resolves), the alternate +value (if one is provided), or else the empty string. The result is +passed through "string->c-name!" and "string->down-case!". + + Arguments: +ag-name - name of AutoGen value + + +File: autogen.info, Node: SCM get-up-name, Next: SCM high-lim, Prev: SCM get-down-name, Up: AutoGen Functions + +3.4.24 'get-up-name' - get upper cased named value, mapped to C name syntax +--------------------------------------------------------------------------- + +Usage: (get-up-name ag-name) +Get the first string value associated with the name. It will either +return the associated string value (if the name resolves), the alternate +value (if one is provided), or else the empty string. The result is +passed through "string->c-name!" and "string->up-case!". + + Arguments: +ag-name - name of AutoGen value + + +File: autogen.info, Node: SCM high-lim, Next: SCM insert-file, Prev: SCM get-up-name, Up: AutoGen Functions + +3.4.25 'high-lim' - get highest value index +------------------------------------------- + +Usage: (high-lim ag-name) +Returns the highest index associated with an array of definitions. This +is generally, but not necessarily, one less than the 'count' value. +(The indexes may be specified, rendering a non-zero based or sparse +array of values.) + + This is very useful for specifying the size of a zero-based array of +values where not all values are present. For example: + + tMyStruct myVals[ [+ (+ 1 (high-lim "my-val-list")) +] ]; + + Arguments: +ag-name - name of AutoGen value + + +File: autogen.info, Node: SCM insert-file, Next: SCM insert-suspended, Prev: SCM high-lim, Up: AutoGen Functions + +3.4.26 'insert-file' - insert the contents of a (list of) files. +---------------------------------------------------------------- + +Usage: (insert-file alist ...) +Insert the contents of one or more files. + + Arguments: +alist - list of files to emit + + +File: autogen.info, Node: SCM insert-suspended, Next: SCM last-for?, Prev: SCM insert-file, Up: AutoGen Functions + +3.4.27 'insert-suspended' - insert a named suspension in current output +----------------------------------------------------------------------- + +Usage: (insert-suspended susp-name) +Emit into the current output the output suspended under a given +diversion name. + + Arguments: +susp-name - the name of the suspended output + + +File: autogen.info, Node: SCM last-for?, Next: SCM len, Prev: SCM insert-suspended, Up: AutoGen Functions + +3.4.28 'last-for?' - detect last iteration +------------------------------------------ + +Usage: (last-for? [ for_var ]) +Returns SCM_BOOL_T if the named FOR loop (or, if not named, the current +innermost loop) is on the last pass through the data. Outside of any +FOR loop, it returns SCM_UNDEFINED. *Note FOR::. + + Arguments: +for_var - Optional - which for loop + + +File: autogen.info, Node: SCM len, Next: SCM low-lim, Prev: SCM last-for?, Up: AutoGen Functions + +3.4.29 'len' - get count of values +---------------------------------- + +Usage: (len ag-name) +If the named object is a group definition, then "len" is the same as +"count". Otherwise, if it is one or more text definitions, then it is +the sum of their string lengths. If it is a single text definition, +then it is equivalent to '(string-length (get "ag-name"))'. + + Arguments: +ag-name - name of AutoGen value + + +File: autogen.info, Node: SCM low-lim, Next: SCM make-header-guard, Prev: SCM len, Up: AutoGen Functions + +3.4.30 'low-lim' - get lowest value index +----------------------------------------- + +Usage: (low-lim ag-name) +Returns the lowest index associated with an array of definitions. + + Arguments: +ag-name - name of AutoGen value + + +File: autogen.info, Node: SCM make-header-guard, Next: SCM make-tmp-dir, Prev: SCM low-lim, Up: AutoGen Functions + +3.4.31 'make-header-guard' - make self-inclusion guard +------------------------------------------------------ + +Usage: (make-header-guard name) +This function will create a '#ifndef'/'#define' sequence for protecting +a header from multiple evaluation. It will also set the Scheme variable +'header-file' to the name of the file being protected and it will set +'header-guard' to the name of the '#define' being used to protect it. +It is expected that this will be used as follows: + [+ (make-header-guard "group_name") +] + ... + #endif /* [+ (. header-guard) +] */ + + #include "[+ (. header-file) +]" +The '#define' name is composed as follows: + + 1. The first element is the string argument and a separating + underscore. + 2. That is followed by the name of the header file with illegal + characters mapped to underscores. + 3. The end of the name is always, "'_GUARD'". + 4. Finally, the entire string is mapped to upper case. + + The final '#define' name is stored in an SCM symbol named +'header-guard'. Consequently, the concluding '#endif' for the file +should read something like: + + #endif /* [+ (. header-guard) +] */ + + The name of the header file (the current output file) is also stored +in an SCM symbol, 'header-file'. Therefore, if you are also generating +a C file that uses the previously generated header file, you can put +this into that generated file: + + #include "[+ (. header-file) +]" + + Obviously, if you are going to produce more than one header file from +a particular template, you will need to be careful how these SCM symbols +get handled. + + Arguments: +name - header group name + + +File: autogen.info, Node: SCM make-tmp-dir, Next: SCM match-value?, Prev: SCM make-header-guard, Up: AutoGen Functions + +3.4.32 'make-tmp-dir' - create a temporary directory +---------------------------------------------------- + +Usage: (make-tmp-dir) +Create a directory that will be cleaned up upon exit. + + This Scheme function takes no arguments. + + +File: autogen.info, Node: SCM match-value?, Next: SCM max-file-time, Prev: SCM make-tmp-dir, Up: AutoGen Functions + +3.4.33 'match-value?' - test for matching value +----------------------------------------------- + +Usage: (match-value? op ag-name test-str) +This function answers the question, "Is there an AutoGen value named +'ag-name' with a value that matches the pattern 'test-str' using the +match function 'op'?" Return SCM_BOOL_T iff at least one occurrence of +the specified name has such a value. The operator can be any function +that takes two string arguments and yields a boolean. It is expected +that you will use one of the string matching functions provided by +AutoGen. +The value name must follow the same rules as the 'ag-name' argument for +'exist?' (*note SCM exist?::). + + Arguments: +op - boolean result operator +ag-name - name of AutoGen value +test-str - string to test against + + +File: autogen.info, Node: SCM max-file-time, Next: SCM mk-gettextable, Prev: SCM match-value?, Up: AutoGen Functions + +3.4.34 'max-file-time' - get the maximum input file modification time +--------------------------------------------------------------------- + +Usage: (max-file-time) +returns the time stamp of the most recently modified sourc file as the +number of seconds since the epoch. If any input is dynamic (a shell +command), then it will be the current time. + + This Scheme function takes no arguments. + + +File: autogen.info, Node: SCM mk-gettextable, Next: SCM out-delete, Prev: SCM max-file-time, Up: AutoGen Functions + +3.4.35 'mk-gettextable' - print a string in a gettext-able format +----------------------------------------------------------------- + +Usage: (mk-gettextable string) +Returns SCM_UNDEFINED. The input text string is printed to the current +output as one puts() call per paragraph. + + Arguments: +string - a multi-paragraph string + + +File: autogen.info, Node: SCM out-delete, Next: SCM out-depth, Prev: SCM mk-gettextable, Up: AutoGen Functions + +3.4.36 'out-delete' - delete current output file +------------------------------------------------ + +Usage: (out-delete) +Remove the current output file. Cease processing the template for the +current suffix. It is an error if there are 'push'-ed output files. +Use the '(error "0")' scheme function instead. *Note output controls::. + + This Scheme function takes no arguments. + + +File: autogen.info, Node: SCM out-depth, Next: SCM out-emit-suspended, Prev: SCM out-delete, Up: AutoGen Functions + +3.4.37 'out-depth' - output file stack depth +-------------------------------------------- + +Usage: (out-depth) +Returns the depth of the output file stack. *Note output controls::. + + This Scheme function takes no arguments. + + +File: autogen.info, Node: SCM out-emit-suspended, Next: SCM out-line, Prev: SCM out-depth, Up: AutoGen Functions + +3.4.38 'out-emit-suspended' - emit the text of suspended output +--------------------------------------------------------------- + +Usage: (out-emit-suspended susp_nm) +This function is equivalent to '(begin (out-resume <name>) (out-pop +#t))' + + Arguments: +susp_nm - A name tag of suspended output + + +File: autogen.info, Node: SCM out-line, Next: SCM out-move, Prev: SCM out-emit-suspended, Up: AutoGen Functions + +3.4.39 'out-line' - output file line number +------------------------------------------- + +Usage: (out-line) +Returns the current line number of the output file. It rewinds and +reads the file to count newlines. + + This Scheme function takes no arguments. + + +File: autogen.info, Node: SCM out-move, Next: SCM out-name, Prev: SCM out-line, Up: AutoGen Functions + +3.4.40 'out-move' - change name of output file +---------------------------------------------- + +Usage: (out-move new-name) +Rename current output file. *Note output controls::. Please note: +changing the name will not save a temporary file from being deleted. It +may, however, be used on the root output file. + + Arguments: +new-name - new name for the current output file + + +File: autogen.info, Node: SCM out-name, Next: SCM out-pop, Prev: SCM out-move, Up: AutoGen Functions + +3.4.41 'out-name' - current output file name +-------------------------------------------- + +Usage: (out-name) +Returns the name of the current output file. If the current file is a +temporary, unnamed file, then it will scan up the chain until a real +output file name is found. *Note output controls::. + + This Scheme function takes no arguments. + + +File: autogen.info, Node: SCM out-pop, Next: SCM out-push-add, Prev: SCM out-name, Up: AutoGen Functions + +3.4.42 'out-pop' - close current output file +-------------------------------------------- + +Usage: (out-pop [ disp ]) +If there has been a 'push' on the output, then close that file and go +back to the previously open file. It is an error if there has not been +a 'push'. *Note output controls::. + + If there is no argument, no further action is taken. Otherwise, the +argument should be '#t' and the contents of the file are returned by the +function. + + Arguments: +disp - Optional - return contents of the file + + +File: autogen.info, Node: SCM out-push-add, Next: SCM out-push-new, Prev: SCM out-pop, Up: AutoGen Functions + +3.4.43 'out-push-add' - append output to file +--------------------------------------------- + +Usage: (out-push-add file-name) +Identical to 'push-new', except the contents are *not* purged, but +appended to. *Note output controls::. + + Arguments: +file-name - name of the file to append text to + + +File: autogen.info, Node: SCM out-push-new, Next: SCM out-resume, Prev: SCM out-push-add, Up: AutoGen Functions + +3.4.44 'out-push-new' - purge and create output file +---------------------------------------------------- + +Usage: (out-push-new [ file-name ]) +Leave the current output file open, but purge and create a new file that +will remain open until a 'pop' 'delete' or 'switch' closes it. The file +name is optional and, if omitted, the output will be sent to a temporary +file that will be deleted when it is closed. *Note output controls::. + + Arguments: +file-name - Optional - name of the file to create + + +File: autogen.info, Node: SCM out-resume, Next: SCM out-suspend, Prev: SCM out-push-new, Up: AutoGen Functions + +3.4.45 'out-resume' - resume suspended output file +-------------------------------------------------- + +Usage: (out-resume susp_nm) +If there has been a suspended output, then make that output descriptor +current again. That output must have been suspended with the same tag +name given to this routine as its argument. + + Arguments: +susp_nm - A name tag for reactivating + + +File: autogen.info, Node: SCM out-suspend, Next: SCM out-switch, Prev: SCM out-resume, Up: AutoGen Functions + +3.4.46 'out-suspend' - suspend current output file +-------------------------------------------------- + +Usage: (out-suspend suspName) +If there has been a 'push' on the output, then set aside the output +descriptor for later reactiviation with '(out-resume "xxx")'. The tag +name need not reflect the name of the output file. In fact, the output +file may be an anonymous temporary file. You may also change the tag +every time you suspend output to a file, because the tag names are +forgotten as soon as the file has been "resumed". + + Arguments: +suspName - A name tag for reactivating + + +File: autogen.info, Node: SCM out-switch, Next: SCM output-file-next-line, Prev: SCM out-suspend, Up: AutoGen Functions + +3.4.47 'out-switch' - close and create new output +------------------------------------------------- + +Usage: (out-switch file-name) +Switch output files - close current file and make the current file +pointer refer to the new file. This is equivalent to 'out-pop' followed +by 'out-push-new', except that you may not pop the base level output +file, but you may 'switch' it. *Note output controls::. + + Arguments: +file-name - name of the file to create + + +File: autogen.info, Node: SCM output-file-next-line, Next: SCM set-option, Prev: SCM out-switch, Up: AutoGen Functions + +3.4.48 'output-file-next-line' - print the file name and next line number +------------------------------------------------------------------------- + +Usage: (output-file-next-line [ line_off ] [ alt_fmt ]) +Returns a string with the current output file name and line number. The +default format is: # <line+1> "<output-file-name>" The argument may be +either a number indicating an offset from the current output line number +or an alternate formatting string. If both are provided, then the first +must be a numeric offset. + + Be careful that you are directing output to the final output file. +Otherwise, you will get the file name and line number of the temporary +file. That won't be what you want. + + Arguments: +line_off - Optional - offset to line number +alt_fmt - Optional - alternate format string + + +File: autogen.info, Node: SCM set-option, Next: SCM set-writable, Prev: SCM output-file-next-line, Up: AutoGen Functions + +3.4.49 'set-option' - Set a command line option +----------------------------------------------- + +Usage: (set-option opt) +The text argument must be an option name followed by any needed option +argument. Returns SCM_UNDEFINED. + + Arguments: +opt - AutoGen option name + its argument + + +File: autogen.info, Node: SCM set-writable, Next: SCM stack, Prev: SCM set-option, Up: AutoGen Functions + +3.4.50 'set-writable' - Make the output file be writable +-------------------------------------------------------- + +Usage: (set-writable [ set? ]) +This function will set the current output file to be writable (or not). +This is only effective if neither the '--writable' nor '--not-writable' +have been specified. This state is reset when the current suffix's +output is complete. + + Arguments: +set? - Optional - boolean arg, false to make output non-writable + + +File: autogen.info, Node: SCM stack, Next: SCM stack-join, Prev: SCM set-writable, Up: AutoGen Functions + +3.4.51 'stack' - make list of AutoGen values +-------------------------------------------- + +Usage: (stack ag-name) +Create a scheme list of all the strings that are associated with a name. +They must all be text values or we choke. + + Arguments: +ag-name - AutoGen value name + + +File: autogen.info, Node: SCM stack-join, Next: SCM suffix, Prev: SCM stack, Up: AutoGen Functions + +3.4.52 'stack-join' - stack values then join them +------------------------------------------------- + +Usage: (stack-join join ag-name) +This function will collect all the values named 'ag-name' (see the *note +stack function: SCM stack.) and join them separated by the 'join' string +(see the *note join function: SCM join.). + + Arguments: +join - string between each element +ag-name - name of autogen values to stack + + +File: autogen.info, Node: SCM suffix, Next: SCM tpl-file, Prev: SCM stack-join, Up: AutoGen Functions + +3.4.53 'suffix' - get the current suffix +---------------------------------------- + +Usage: (suffix) +Returns the current active suffix (*note pseudo macro::). + + This Scheme function takes no arguments. + + +File: autogen.info, Node: SCM tpl-file, Next: SCM tpl-file-line, Prev: SCM suffix, Up: AutoGen Functions + +3.4.54 'tpl-file' - get the template file name +---------------------------------------------- + +Usage: (tpl-file [ full_path ]) +Returns the name of the current template file. If '#t' is passed in as +an argument, then the template file is hunted for in the template search +path. Otherwise, just the unadorned name. + + Arguments: +full_path - Optional - include full path to file + + +File: autogen.info, Node: SCM tpl-file-line, Next: SCM tpl-file-next-line, Prev: SCM tpl-file, Up: AutoGen Functions + +3.4.55 'tpl-file-line' - get the template file+line number +---------------------------------------------------------- + +Usage: (tpl-file-line [ msg-fmt ]) +Returns the file and line number of the current template macro using +either the default format, "from %s line %d", or else the format you +supply. For example, if you want to insert a "C" language file-line +directive, you would supply the format "# %2$d \"%1$s\"", but that is +also already supplied with the scheme variable *Note SCM +c-file-line-fmt::. You may use it thus: + (tpl-file-line c-file-line-fmt) + + It is also safe to use the formatting string, "%2$d". AutoGen uses +an argument vector version of printf: *Note snprintfv::, and it does not +need to know the types of each argument in order to skip forward to the +second argument. + + Arguments: +msg-fmt - Optional - formatting for line message + + +File: autogen.info, Node: SCM tpl-file-next-line, Next: SCM warn, Prev: SCM tpl-file-line, Up: AutoGen Functions + +3.4.56 'tpl-file-next-line' - get the template file plus next line number +------------------------------------------------------------------------- + +Usage: (tpl-file-next-line [ msg-fmt ]) +This is almost the same as *Note SCM tpl-file-line::, except that the +line referenced is the next line, per C compiler conventions, and +consequently defaults to the format: # <line-no+1> "<file-name>" + + Arguments: +msg-fmt - Optional - formatting for line message + + +File: autogen.info, Node: SCM warn, Next: SCM autogen-version, Prev: SCM tpl-file-next-line, Up: AutoGen Functions + +3.4.57 'warn' - display warning message and continue +---------------------------------------------------- + +Usage: (warn message) +The argument is a string that printed out to stderr. The message is +formed from the formatting string: + + WARNING: %s\n + + The template processing resumes after printing the message. + + Arguments: +message - message to display + + +File: autogen.info, Node: SCM autogen-version, Next: SCM c-file-line-fmt, Prev: SCM warn, Up: AutoGen Functions + +3.4.58 'autogen-version' - autogen version number +------------------------------------------------- + +This is a symbol defining the current AutoGen version number string. It +was first defined in AutoGen-5.2.14. It is currently "5.18.16". + + +File: autogen.info, Node: SCM c-file-line-fmt, Prev: SCM autogen-version, Up: AutoGen Functions + +3.4.59 format file info as, "'#line nn "file"'" +----------------------------------------------- + +This is a symbol that can easily be used with the functions *Note SCM +tpl-file-line::, and *Note SCM def-file-line::. These will emit C +program '#line' directives pointing to template and definitions text, +respectively. + + +File: autogen.info, Node: Common Functions, Next: native macros, Prev: AutoGen Functions, Up: Template File + +3.5 Common Scheme Functions +=========================== + +This section describes a number of general purpose functions that make +the kind of string processing that AutoGen does a little easier. Unlike +the AutoGen specific functions (*note AutoGen Functions::), these +functions are available for direct use during definition load time. The +equality test (*note SCM =::) is "overloaded" to do string equivalence +comparisons. If you are looking for inequality, the Scheme/Lisp way of +spelling that is, "(not (= ...))". + +* Menu: + +* SCM agpl:: 'agpl' - GNU Affero General Public License +* SCM bsd:: 'bsd' - BSD Public License +* SCM c-string:: 'c-string' - emit string for ANSI C +* SCM error-source-line:: 'error-source-line' - display of file & line +* SCM extract:: 'extract' - extract text from another file +* SCM format-arg-count:: 'format-arg-count' - count the args to a format +* SCM fprintf:: 'fprintf' - format to a file +* SCM gperf:: 'gperf' - perform a perfect hash function +* SCM gperf-code:: 'gperf-code' - emit the source of the generated gperf program +* SCM gpl:: 'gpl' - GNU General Public License +* SCM hide-email:: 'hide-email' - convert eaddr to javascript +* SCM html-escape-encode:: 'html-escape-encode' - encode html special characters +* SCM in?:: 'in?' - test for string in list +* SCM join:: 'join' - join string list with separator +* SCM kr-string:: 'kr-string' - emit string for K&R C +* SCM lgpl:: 'lgpl' - GNU Library General Public License +* SCM license:: 'license' - an arbitrary license +* SCM license-description:: 'license-description' - Emit a license description +* SCM license-full:: 'license-full' - Emit the licensing information and description +* SCM license-info:: 'license-info' - Emit the licensing information and copyright years +* SCM license-name:: 'license-name' - Emit the name of the license +* SCM make-gperf:: 'make-gperf' - build a perfect hash function program +* SCM makefile-script:: 'makefile-script' - create makefile script +* SCM max:: 'max' - maximum value in list +* SCM min:: 'min' - minimum value in list +* SCM prefix:: 'prefix' - prefix lines with a string +* SCM printf:: 'printf' - format to stdout +* SCM raw-shell-str:: 'raw-shell-str' - single quote shell string +* SCM shell:: 'shell' - invoke a shell script +* SCM shell-str:: 'shell-str' - double quote shell string +* SCM shellf:: 'shellf' - format a string, run shell +* SCM sprintf:: 'sprintf' - format a string +* SCM string-capitalize:: 'string-capitalize' - capitalize a new string +* SCM string-capitalize!:: 'string-capitalize!' - capitalize a string +* SCM *=*:: 'string-contains-eqv?' - caseless substring +* SCM *==*:: 'string-contains?' - substring match +* SCM string-downcase:: 'string-downcase' - lower case a new string +* SCM string-downcase!:: 'string-downcase!' - make a string be lower case +* SCM *~:: 'string-end-eqv-match?' - caseless regex ending +* SCM *~~:: 'string-end-match?' - regex match end +* SCM *=:: 'string-ends-eqv?' - caseless string ending +* SCM *==:: 'string-ends-with?' - string ending +* SCM ==:: 'string-equals?' - string matching +* SCM ~:: 'string-eqv-match?' - caseless regex match +* SCM =:: 'string-eqv?' - caseless match +* SCM *~*:: 'string-has-eqv-match?' - caseless regex contains +* SCM *~~*:: 'string-has-match?' - contained regex match +* SCM ~~:: 'string-match?' - regex match +* SCM ~*:: 'string-start-eqv-match?' - caseless regex start +* SCM ~~*:: 'string-start-match?' - regex match start +* SCM =*:: 'string-starts-eqv?' - caseless string start +* SCM ==*:: 'string-starts-with?' - string starting +* SCM string-substitute:: 'string-substitute' - multiple global replacements +* SCM string-table-add:: 'string-table-add' - Add an entry to a string table +* SCM string-table-add-ref:: 'string-table-add-ref' - Add an entry to a string table, get reference +* SCM string-table-new:: 'string-table-new' - create a string table +* SCM string-table-size:: 'string-table-size' - print the current size of a string table +* SCM string->c-name!:: 'string->c-name!' - map non-name chars to underscore +* SCM string->camelcase:: 'string->camelcase' - make a string be CamelCase +* SCM string-tr:: 'string-tr' - convert characters with new result +* SCM string-tr!:: 'string-tr!' - convert characters +* SCM string-upcase:: 'string-upcase' - upper case a new string +* SCM string-upcase!:: 'string-upcase!' - make a string be upper case +* SCM sub-shell-str:: 'sub-shell-str' - back quoted (sub-)shell string +* SCM sum:: 'sum' - sum of values in list +* SCM time-string->number:: 'time-string->number' - duration string to seconds +* SCM version-compare:: 'version-compare' - compare two version numbers + + +File: autogen.info, Node: SCM agpl, Next: SCM bsd, Up: Common Functions + +3.5.1 'agpl' - GNU Affero General Public License +------------------------------------------------ + +Usage: (agpl prog-name prefix) +Emit a string that contains the GNU Affero General Public License. This +function is now deprecated. Please *Note SCM license-description::. + + Arguments: +prog-name - name of the program under the GPL +prefix - String for starting each output line + + +File: autogen.info, Node: SCM bsd, Next: SCM c-string, Prev: SCM agpl, Up: Common Functions + +3.5.2 'bsd' - BSD Public License +-------------------------------- + +Usage: (bsd prog_name owner prefix) +Emit a string that contains the Free BSD Public License. This function +is now deprecated. Please *Note SCM license-description::. + + Arguments: +prog_name - name of the program under the BSD +owner - Grantor of the BSD License +prefix - String for starting each output line + + +File: autogen.info, Node: SCM c-string, Next: SCM error-source-line, Prev: SCM bsd, Up: Common Functions + +3.5.3 'c-string' - emit string for ANSI C +----------------------------------------- + +Usage: (c-string string) +Reform a string so that, when printed, the C compiler will be able to +compile the data and construct a string that contains exactly what the +current string contains. Many non-printing characters are replaced with +escape sequences. Newlines are replaced with a backslash, an 'n', a +closing quote, a newline, seven spaces and another re-opening quote. +The compiler will implicitly concatenate them. The reader will see line +breaks. + + A K&R compiler will choke. Use 'kr-string' for that compiler. + + Arguments: +string - string to reformat + + +File: autogen.info, Node: SCM error-source-line, Next: SCM extract, Prev: SCM c-string, Up: Common Functions + +3.5.4 'error-source-line' - display of file & line +-------------------------------------------------- + +Usage: (error-source-line) +This function is only invoked just before Guile displays an error +message. It displays the file name and line number that triggered the +evaluation error. You should not need to invoke this routine directly. +Guile will do it automatically. + + This Scheme function takes no arguments. + + +File: autogen.info, Node: SCM extract, Next: SCM format-arg-count, Prev: SCM error-source-line, Up: Common Functions + +3.5.5 'extract' - extract text from another file +------------------------------------------------ + +Usage: (extract file-name marker-fmt [ caveat ] [ default ]) +This function is used to help construct output files that may contain +text that is carried from one version of the output to the next. + + The first two arguments are required, the second are optional: + + * The 'file-name' argument is used to name the file that contains the + demarcated text. + * The 'marker-fmt' is a formatting string that is used to construct + the starting and ending demarcation strings. The sprintf function + is given the 'marker-fmt' with two arguments. The first is either + "START" or "END". The second is either "DO NOT CHANGE THIS COMMENT" + or the optional 'caveat' argument. + * 'caveat' is presumed to be absent if it is the empty string ('""'). + If absent, "DO NOT CHANGE THIS COMMENT" is used as the second + string argument to the 'marker-fmt'. + * When a 'default' argument is supplied and no pre-existing text is + found, then this text will be inserted between the START and END + markers. + +The resulting strings are presumed to be unique within the subject file. +As a simplified example: + + [+ (extract "fname" "// %s - SOMETHING - %s" "" + "example default") +] +will result in the following text being inserted into the output: + + // START - SOMETHING - DO NOT CHANGE THIS COMMENT + example default + // END - SOMETHING - DO NOT CHANGE THIS COMMENT + +The "'example default'" string can then be carried forward to the next +generation of the output, *provided* the output is not named "'fname'" +and the old output is renamed to "'fname'" before AutoGen-eration +begins. + +*NB:* + You can set aside previously generated source files inside the + pseudo macro with a Guile/scheme function, extract the text you + want to keep with this extract function. Just remember you should + delete it at the end, too. Here is an example from my Finite State + Machine generator: + + [+ AutoGen5 Template -*- Mode: text -*- + h=%s-fsm.h c=%s-fsm.c + (shellf + "test -f %1$s-fsm.h && mv -f %1$s-fsm.h .fsm.head + test -f %1$s-fsm.c && mv -f %1$s-fsm.c .fsm.code" (base-name)) + +] + + This code will move the two previously produced output files to + files named ".fsm.head" and ".fsm.code". At the end of the 'c' + output processing, I delete them. + +*also NB:* + This function presumes that the output file ought to be editable so + that the code between the 'START' and 'END' marks can be edited by + the template user. Consequently, when the '(extract ...)' function + is invoked, if the 'writable' option has not been specified, then + it will be set at that point. If this is not the desired behavior, + the '--not-writable' command line option will override this. Also, + you may use the guile function '(chmod "file" mode-value)' to + override whatever AutoGen is using for the result mode. + + Arguments: +file-name - name of file with text +marker-fmt - format for marker text +caveat - Optional - warn about changing marker +default - Optional - default initial text + + +File: autogen.info, Node: SCM format-arg-count, Next: SCM fprintf, Prev: SCM extract, Up: Common Functions + +3.5.6 'format-arg-count' - count the args to a format +----------------------------------------------------- + +Usage: (format-arg-count format) +Sometimes, it is useful to simply be able to figure out how many +arguments are required by a format string. For example, if you are +extracting a format string for the purpose of generating a macro to +invoke a printf-like function, you can run the formatting string through +this function to determine how many arguments to provide for in the +macro. e.g. for this extraction text: + + /*=fumble bumble + * fmt: 'stumble %s: %d\n' + =*/ + +You may wish to generate a macro: + + #define BUMBLE(a1,a2) printf_like(something,(a1),(a2)) + +You can do this by knowing that the format needs two arguments. + + Arguments: +format - formatting string + + +File: autogen.info, Node: SCM fprintf, Next: SCM gperf, Prev: SCM format-arg-count, Up: Common Functions + +3.5.7 'fprintf' - format to a file +---------------------------------- + +Usage: (fprintf port format [ format-arg ... ]) +Format a string using arguments from the alist. Write to a specified +port. The result will NOT appear in your output. Use this to print +information messages to a template user. + + Arguments: +port - Guile-scheme output port +format - formatting string +format-arg - Optional - list of arguments to formatting string + + +File: autogen.info, Node: SCM gperf, Next: SCM gperf-code, Prev: SCM fprintf, Up: Common Functions + +3.5.8 'gperf' - perform a perfect hash function +----------------------------------------------- + +Usage: (gperf name str) +Perform the perfect hash on the input string. This is only useful if +you have previously created a gperf program with the 'make-gperf' +function *Note SCM make-gperf::. The 'name' you supply here must match +the name used to create the program and the string to hash must be one +of the strings supplied in the 'make-gperf' string list. The result +will be a perfect hash index. + + See the documentation for 'gperf(1GNU)' for more details. + + Arguments: +name - name of hash list +str - string to hash + + +File: autogen.info, Node: SCM gperf-code, Next: SCM gpl, Prev: SCM gperf, Up: Common Functions + +3.5.9 'gperf-code' - emit the source of the generated gperf program +------------------------------------------------------------------- + +Usage: (gperf-code st-name) +Returns the contents of the emitted code, suitable for inclusion in +another program. The interface contains the following elements: + +'struct <st-name>_index' + containg the fields: '{char const * name, int const id; };' + +'<st-name>_hash()' + This is the hashing function with local only scope (static). + +'<st-name>_find()' + This is the searching and validation function. The first argument + is the string to look up, the second is its length. It returns a + pointer to the corresponding '<st-name>_index' entry. + + Use this in your template as follows where "<st-name>" was set to be +"'lookup'": + + [+ (make-gperf "lookup" (join "\n" (stack "name_list"))) + (gperf-code "lookup") +] + void my_fun(char * str) { + struct lookup_index * li = lookup_find(str, strlen(str)); + if (li != NULL) printf("%s yields %d\n", str, li->idx); + + Arguments: +st-name - the name of the gperf hash list + + +File: autogen.info, Node: SCM gpl, Next: SCM hide-email, Prev: SCM gperf-code, Up: Common Functions + +3.5.10 'gpl' - GNU General Public License +----------------------------------------- + +Usage: (gpl prog-name prefix) +Emit a string that contains the GNU General Public License. This +function is now deprecated. Please *Note SCM license-description::. + + Arguments: +prog-name - name of the program under the GPL +prefix - String for starting each output line + + +File: autogen.info, Node: SCM hide-email, Next: SCM html-escape-encode, Prev: SCM gpl, Up: Common Functions + +3.5.11 'hide-email' - convert eaddr to javascript +------------------------------------------------- + +Usage: (hide-email display eaddr) +Hides an email address as a java scriptlett. The 'mailto:' tag and the +email address are coded bytes rather than plain text. They are also +broken up. + + Arguments: +display - display text +eaddr - email address + + +File: autogen.info, Node: SCM html-escape-encode, Next: SCM in?, Prev: SCM hide-email, Up: Common Functions + +3.5.12 'html-escape-encode' - encode html special characters +------------------------------------------------------------ + +Usage: (html-escape-encode str) +This function will replace replace the characters ''&'', ''<'' and ''>'' +characters with the HTML/XML escape-encoded strings ('"&"', +'"<"', and '">"', respectively). + + Arguments: +str - string to make substitutions in + + +File: autogen.info, Node: SCM in?, Next: SCM join, Prev: SCM html-escape-encode, Up: Common Functions + +3.5.13 'in?' - test for string in list +-------------------------------------- + +Usage: (in? test-string string-list ...) +Return SCM_BOOL_T if the first argument string is found in one of the +entries in the second (list-of-strings) argument. + + Arguments: +test-string - string to look for +string-list - list of strings to check + + +File: autogen.info, Node: SCM join, Next: SCM kr-string, Prev: SCM in?, Up: Common Functions + +3.5.14 'join' - join string list with separator +----------------------------------------------- + +Usage: (join separator list ...) +With the first argument as the separator string, joins together an +a-list of strings into one long string. The list may contain nested +lists, partly because you cannot always control that. + + Arguments: +separator - string to insert between entries +list - list of strings to join + + +File: autogen.info, Node: SCM kr-string, Next: SCM lgpl, Prev: SCM join, Up: Common Functions + +3.5.15 'kr-string' - emit string for K&R C +------------------------------------------ + +Usage: (kr-string string) +Reform a string so that, when printed, a K&R C compiler will be able to +compile the data and construct a string that contains exactly what the +current string contains. Many non-printing characters are replaced with +escape sequences. New-lines are replaced with a backslash-n-backslash +and newline sequence, + + Arguments: +string - string to reformat + + +File: autogen.info, Node: SCM lgpl, Next: SCM license, Prev: SCM kr-string, Up: Common Functions + +3.5.16 'lgpl' - GNU Library General Public License +-------------------------------------------------- + +Usage: (lgpl prog_name owner prefix) +Emit a string that contains the GNU Library General Public License. +This function is now deprecated. Please *Note SCM +license-description::. + + Arguments: +prog_name - name of the program under the LGPL +owner - Grantor of the LGPL +prefix - String for starting each output line + + +File: autogen.info, Node: SCM license, Next: SCM license-description, Prev: SCM lgpl, Up: Common Functions + +3.5.17 'license' - an arbitrary license +--------------------------------------- + +Usage: (license lic_name prog_name owner prefix) +Emit a string that contains the named license. This function is now +deprecated. Please *Note SCM license-description::. + + Arguments: +lic_name - file name of the license +prog_name - name of the licensed program or library +owner - Grantor of the License +prefix - String for starting each output line + + +File: autogen.info, Node: SCM license-description, Next: SCM license-full, Prev: SCM license, Up: Common Functions + +3.5.18 'license-description' - Emit a license description +--------------------------------------------------------- + +Usage: (license-description license prog-name prefix [ owner ]) +Emit a string that contains a detailed license description, with +substitutions for program name, copyright holder and a per-line prefix. +This is the text typically used as part of a source file header. For +more details, *Note the license-full command: SCM license-full. + + Arguments: +license - name of license type +prog-name - name of the program under the GPL +prefix - String for starting each output line +owner - Optional - owner of the program + + +File: autogen.info, Node: SCM license-full, Next: SCM license-info, Prev: SCM license-description, Up: Common Functions + +3.5.19 'license-full' - Emit the licensing information and description +---------------------------------------------------------------------- + +Usage: (license-full license prog-name prefix [ owner ] [ years ]) +Emit all the text that 'license-info' and 'license-description' would +emit (*note 'license-info': SCM license-info, and *note +'license-description': SCM license-description.), with all the same +substitutions. + + All of these depend upon the existence of a license file named after +the 'license' argument with a '.lic' suffix. That file should contain +three blocks of text, each separated by two or more consecutive newline +characters (at least one completely blank line). + + The first section describes copyright attribution and the name of the +usage licence. For GNU software, this should be the text that is to be +displayed with the program version. Four text markers can be replaced: +<PFX>, <program>, <years> and <owner>. + + The second section is a short description of the terms of the +license. This is typically the kind of text that gets displayed in the +header of source files. Only the <PFX>, <owner> and <program> markers +are substituted. + + The third section is strictly the name of the license. No marker +substitutions are performed. + + <PFX>Copyright (C) <years> <owner>, all rights reserved. + <PFX> + <PFX>This is free software. It is licensed for use, + <PFX>modification and redistribution under the terms + <PFX>of the GNU General Public License, version 3 or later + <PFX> <http://gnu.org/licenses/gpl.html> + + <PFX><program> is free software: you can redistribute it + <PFX>and/or modify it under the terms of the GNU General + <PFX>Public License as published by the Free Software ... + + the GNU General Public License, version 3 or later + + Arguments: +license - name of license type +prog-name - name of the program under the GPL +prefix - String for starting each output line +owner - Optional - owner of the program +years - Optional - copyright years + + +File: autogen.info, Node: SCM license-info, Next: SCM license-name, Prev: SCM license-full, Up: Common Functions + +3.5.20 'license-info' - Emit the licensing information and copyright years +-------------------------------------------------------------------------- + +Usage: (license-info license prog-name prefix [ owner ] [ years ]) +Emit a string that contains the licensing description, with some +substitutions for program name, copyright holder, a list of years when +the source was modified, and a per-line prefix. This text typically +includes a brief license description and is often printed out when a +program starts running or as part of the '--version' output. For more +details, *Note the license-full command: SCM license-full. + + Arguments: +license - name of license type +prog-name - name of the program under the GPL +prefix - String for starting each output line +owner - Optional - owner of the program +years - Optional - copyright years + + +File: autogen.info, Node: SCM license-name, Next: SCM make-gperf, Prev: SCM license-info, Up: Common Functions + +3.5.21 'license-name' - Emit the name of the license +---------------------------------------------------- + +Usage: (license-name license) +Emit a string that contains the full name of the license. + + Arguments: +license - name of license type + + +File: autogen.info, Node: SCM make-gperf, Next: SCM makefile-script, Prev: SCM license-name, Up: Common Functions + +3.5.22 'make-gperf' - build a perfect hash function program +----------------------------------------------------------- + +Usage: (make-gperf name strings ...) +Build a program to perform perfect hashes of a known list of input +strings. This function produces no output, but prepares a program +named, 'gperf_<name>' for use by the gperf function *Note SCM gperf::. + + This program will be obliterated as AutoGen exits. However, you may +incorporate the generated hashing function into your C program with +commands something like the following: + + [+ (shellf "sed '/^int main(/,$d;/^#line/d' ${gpdir}/%s.c" + name ) +] + + where 'name' matches the name provided to this 'make-perf' function. +'gpdir' is the variable used to store the name of the temporary +directory used to stash all the files. + + Arguments: +name - name of hash list +strings - list of strings to hash + + +File: autogen.info, Node: SCM makefile-script, Next: SCM max, Prev: SCM make-gperf, Up: Common Functions + +3.5.23 'makefile-script' - create makefile script +------------------------------------------------- + +Usage: (makefile-script text) +This function will take ordinary shell script text and reformat it so +that it will work properly inside of a makefile shell script. Not every +shell construct can be supported; the intent is to have most ordinary +scripts work without much, if any, alteration. + + The following transformations are performed on the source text: + + 1. Trailing whitespace on each line is stripped. + + 2. Except for the last line, the string, " ; \\" is appended to the + end of every line that does not end with certain special characters + or keywords. Note that this will mutilate multi-line quoted + strings, but 'make' renders it impossible to use multi-line + constructs anyway. + + 3. If the line ends with a backslash, it is left alone. + + 4. If the line ends with a semi-colon, conjunction operator, pipe + (vertical bar) or one of the keywords "then", "else" or "in", then + a space and a backslash is added, but no semi-colon. + + 5. The dollar sign character is doubled, unless it immediately + precedes an opening parenthesis or the single character make macros + '*', '<', '@', '?' or '%'. Other single character make macros + that do not have enclosing parentheses will fail. For shell usage + of the "$@", "$?" and "$*" macros, you must enclose them with + curly braces, e.g., "${?}". The ksh construct '$(<command>)' will + not work. Though some 'make's accept '${var}' constructs, this + function will assume it is for shell interpretation and double the + dollar character. You must use '$(var)' for all 'make' + substitutions. + + 6. Double dollar signs are replaced by four before the next character + is examined. + + 7. Every line is prefixed with a tab, unless the first line already + starts with a tab. + + 8. The newline character on the last line, if present, is suppressed. + + 9. Blank lines are stripped. + + 10. Lines starting with "@ifdef", "@ifndef", "@else" and "@endif" are + presumed to be autoconf "sed" expression tags. These lines will be + emitted as-is, with no tab prefix and no line splicing backslash. + These lines can then be processed at configure time with + 'AC_CONFIG_FILES' sed expressions, similar to: + + sed "/^@ifdef foo/d;/^@endif foo/d;/^@ifndef foo/,/^@endif foo/d" + +This function is intended to be used approximately as follows: + + $(TARGET) : $(DEPENDENCIES) + <+ (out-push-new) +> + ....mostly arbitrary shell script text.... + <+ (makefile-script (out-pop #t)) +> + + Arguments: +text - the text of the script + + +File: autogen.info, Node: SCM max, Next: SCM min, Prev: SCM makefile-script, Up: Common Functions + +3.5.24 'max' - maximum value in list +------------------------------------ + +Usage: (max list ...) +Return the maximum value in the list + + Arguments: +list - list of values. Strings are converted to numbers + + +File: autogen.info, Node: SCM min, Next: SCM prefix, Prev: SCM max, Up: Common Functions + +3.5.25 'min' - minimum value in list +------------------------------------ + +Usage: (min list ...) +Return the minimum value in the list + + Arguments: +list - list of values. Strings are converted to numbers + + +File: autogen.info, Node: SCM prefix, Next: SCM printf, Prev: SCM min, Up: Common Functions + +3.5.26 'prefix' - prefix lines with a string +-------------------------------------------- + +Usage: (prefix prefix text) +Prefix every line in the second string with the first string. This +includes empty lines. Trailing white space will be removed so if the +prefix is all horizontal white space, then it will be removed from +otherwise blank lines. Also, if the last character is a newline, then +*two* prefixes will be inserted into the result text. + + For example, if the first string is "# " and the second contains: + "two\nlines\n" +The result string will contain: + # two + # lines + # + + The last line will be incomplete: no newline and no space after the +hash character, either. + + Arguments: +prefix - string to insert at start of each line +text - multi-line block of text + + +File: autogen.info, Node: SCM printf, Next: SCM raw-shell-str, Prev: SCM prefix, Up: Common Functions + +3.5.27 'printf' - format to stdout +---------------------------------- + +Usage: (printf format [ format-arg ... ]) +Format a string using arguments from the alist. Write to the standard +out port. The result will NOT appear in your output. Use this to print +information messages to a template user. Use "(sprintf ...)" to add +text to your document. + + Arguments: +format - formatting string +format-arg - Optional - list of arguments to formatting string + + +File: autogen.info, Node: SCM raw-shell-str, Next: SCM shell, Prev: SCM printf, Up: Common Functions + +3.5.28 'raw-shell-str' - single quote shell string +-------------------------------------------------- + +Usage: (raw-shell-str string) +Convert the text of the string into a singly quoted string that a normal +shell will process into the original string. (It will not do macro +expansion later, either.) Contained single quotes become tripled, with +the middle quote escaped with a backslash. Normal shells will +reconstitute the original string. + + *Notice*: some shells will not correctly handle unusual non-printing +characters. This routine works for most reasonably conventional ASCII +strings. + + Arguments: +string - string to transform + + +File: autogen.info, Node: SCM shell, Next: SCM shell-str, Prev: SCM raw-shell-str, Up: Common Functions + +3.5.29 'shell' - invoke a shell script +-------------------------------------- + +Usage: (shell command ...) +Generate a string by writing the value to a server shell and reading the +output back in. The template programmer is responsible for ensuring +that it completes within 10 seconds. If it does not, the server will be +killed, the output tossed and a new server started. + + Please note: This is the same server process used by the '#shell' +definitions directive and backquoted '`' definitions. There may be left +over state from previous shell expressions and the '`' processing in the +declarations. However, a 'cd' to the original directory is always +issued before the new command is issued. + + Also note: When initializing, autogen will set the environment +variable "AGexe" to the full path of the autogen executable. + + Arguments: +command - shell command - the result is from stdout + + +File: autogen.info, Node: SCM shell-str, Next: SCM shellf, Prev: SCM shell, Up: Common Functions + +3.5.30 'shell-str' - double quote shell string +---------------------------------------------- + +Usage: (shell-str string) +Convert the text of the string into a double quoted string that a normal +shell will process into the original string, almost. It will add the +escape character '\\' before two special characters to accomplish this: +the backslash '\\' and double quote '"'. + + *Notice*: some shells will not correctly handle unusual non-printing +characters. This routine works for most reasonably conventional ASCII +strings. + + *WARNING*: +This function omits the extra backslash in front of a backslash, +however, if it is followed by either a backquote or a dollar sign. It +must do this because otherwise it would be impossible to protect the +dollar sign or backquote from shell evaluation. Consequently, it is not +possible to render the strings "\\$" or "\\'". The lesser of two evils. + + All others characters are copied directly into the output. + + The 'sub-shell-str' variation of this routine behaves identically, +except that the extra backslash is omitted in front of '"' instead of +'`'. You have to think about it. I'm open to suggestions. + + Meanwhile, the best way to document is with a detailed output +example. If the backslashes make it through the text processing +correctly, below you will see what happens with three example strings. +The first example string contains a list of quoted 'foo's, the second is +the same with a single backslash before the quote characters and the +last is with two backslash escapes. Below each is the result of the +'raw-shell-str', 'shell-str' and 'sub-shell-str' functions. + + foo[0] ''foo'' 'foo' "foo" `foo` $foo + raw-shell-str -> \'\''foo'\'\'' '\''foo'\'' "foo" `foo` $foo' + shell-str -> "''foo'' 'foo' \"foo\" `foo` $foo" + sub-shell-str -> `''foo'' 'foo' "foo" \`foo\` $foo` + + foo[1] \'bar\' \"bar\" \`bar\` \$bar + raw-shell-str -> '\'\''bar\'\'' \"bar\" \`bar\` \$bar' + shell-str -> "\\'bar\\' \\\"bar\\\" \`bar\` \$bar" + sub-shell-str -> `\\'bar\\' \"bar\" \\\`bar\\\` \$bar` + + foo[2] \\'BAZ\\' \\"BAZ\\" \\`BAZ\\` \\$BAZ + raw-shell-str -> '\\'\''BAZ\\'\'' \\"BAZ\\" \\`BAZ\\` \\$BAZ' + shell-str -> "\\\\'BAZ\\\\' \\\\\"BAZ\\\\\" \\\`BAZ\\\` \\\$BAZ" + sub-shell-str -> `\\\\'BAZ\\\\' \\\"BAZ\\\" \\\\\`BAZ\\\\\` \\\$BAZ` + + There should be four, three, five and three backslashes for the four +examples on the last line, respectively. The next to last line should +have four, five, three and three backslashes. If this was not +accurately reproduced, take a look at the agen5/test/shell.test test. +Notice the backslashes in front of the dollar signs. It goes from zero +to one to three for the "cooked" string examples. + + Arguments: +string - string to transform + + +File: autogen.info, Node: SCM shellf, Next: SCM sprintf, Prev: SCM shell-str, Up: Common Functions + +3.5.31 'shellf' - format a string, run shell +-------------------------------------------- + +Usage: (shellf format [ format-arg ... ]) +Format a string using arguments from the alist, then send the result to +the shell for interpretation. + + Arguments: +format - formatting string +format-arg - Optional - list of arguments to formatting string + + +File: autogen.info, Node: SCM sprintf, Next: SCM string-capitalize, Prev: SCM shellf, Up: Common Functions + +3.5.32 'sprintf' - format a string +---------------------------------- + +Usage: (sprintf format [ format-arg ... ]) +Format a string using arguments from the alist. + + Arguments: +format - formatting string +format-arg - Optional - list of arguments to formatting string + + +File: autogen.info, Node: SCM string-capitalize, Next: SCM string-capitalize!, Prev: SCM sprintf, Up: Common Functions + +3.5.33 'string-capitalize' - capitalize a new string +---------------------------------------------------- + +Usage: (string-capitalize str) +Create a new SCM string containing the same text as the original, only +all the first letter of each word is upper cased and all other letters +are made lower case. + + Arguments: +str - input string + + +File: autogen.info, Node: SCM string-capitalize!, Next: SCM *=*, Prev: SCM string-capitalize, Up: Common Functions + +3.5.34 'string-capitalize!' - capitalize a string +------------------------------------------------- + +Usage: (string-capitalize! str) +capitalize all the words in an SCM string. + + Arguments: +str - input/output string + + +File: autogen.info, Node: SCM *=*, Next: SCM *==*, Prev: SCM string-capitalize!, Up: Common Functions + +3.5.35 'string-contains-eqv?' - caseless substring +-------------------------------------------------- + +Usage: (*=* text match) +string-contains-eqv?: Test to see if a string contains an equivalent +string. 'equivalent' means the strings match, but without regard to +character case and certain characters are considered 'equivalent'. +Viz., '-', '_' and '^' are equivalent. + + Arguments: +text - text to test for pattern +match - pattern/substring to search for + + +File: autogen.info, Node: SCM *==*, Next: SCM string-downcase, Prev: SCM *=*, Up: Common Functions + +3.5.36 'string-contains?' - substring match +------------------------------------------- + +Usage: (*==* text match) +string-contains?: Test to see if a string contains a substring. +"strstr(3)" will find an address. + + Arguments: +text - text to test for pattern +match - pattern/substring to search for + + +File: autogen.info, Node: SCM string-downcase, Next: SCM string-downcase!, Prev: SCM *==*, Up: Common Functions + +3.5.37 'string-downcase' - lower case a new string +-------------------------------------------------- + +Usage: (string-downcase str) +Create a new SCM string containing the same text as the original, only +all the upper case letters are changed to lower case. + + Arguments: +str - input string + + +File: autogen.info, Node: SCM string-downcase!, Next: SCM *~, Prev: SCM string-downcase, Up: Common Functions + +3.5.38 'string-downcase!' - make a string be lower case +------------------------------------------------------- + +Usage: (string-downcase! str) +Change to lower case all the characters in an SCM string. + + Arguments: +str - input/output string + + +File: autogen.info, Node: SCM *~, Next: SCM *~~, Prev: SCM string-downcase!, Up: Common Functions + +3.5.39 'string-end-eqv-match?' - caseless regex ending +------------------------------------------------------ + +Usage: (*~ text match) +string-end-eqv-match?: Test to see if a string ends with a pattern. +Case is not significant. + + Arguments: +text - text to test for pattern +match - pattern/substring to search for + + +File: autogen.info, Node: SCM *~~, Next: SCM *=, Prev: SCM *~, Up: Common Functions + +3.5.40 'string-end-match?' - regex match end +-------------------------------------------- + +Usage: (*~~ text match) +string-end-match?: Test to see if a string ends with a pattern. Case is +significant. + + Arguments: +text - text to test for pattern +match - pattern/substring to search for + + +File: autogen.info, Node: SCM *=, Next: SCM *==, Prev: SCM *~~, Up: Common Functions + +3.5.41 'string-ends-eqv?' - caseless string ending +-------------------------------------------------- + +Usage: (*= text match) +string-ends-eqv?: Test to see if a string ends with an equivalent +string. + + Arguments: +text - text to test for pattern +match - pattern/substring to search for + + +File: autogen.info, Node: SCM *==, Next: SCM ==, Prev: SCM *=, Up: Common Functions + +3.5.42 'string-ends-with?' - string ending +------------------------------------------ + +Usage: (*== text match) +string-ends-with?: Test to see if a string ends with a substring. +strcmp(3) returns zero for comparing the string ends. + + Arguments: +text - text to test for pattern +match - pattern/substring to search for + + +File: autogen.info, Node: SCM ==, Next: SCM ~, Prev: SCM *==, Up: Common Functions + +3.5.43 'string-equals?' - string matching +----------------------------------------- + +Usage: (== text match) +string-equals?: Test to see if two strings exactly match. + + Arguments: +text - text to test for pattern +match - pattern/substring to search for + + +File: autogen.info, Node: SCM ~, Next: SCM =, Prev: SCM ==, Up: Common Functions + +3.5.44 'string-eqv-match?' - caseless regex match +------------------------------------------------- + +Usage: (~ text match) +string-eqv-match?: Test to see if a string fully matches a pattern. +Case is not significant, but any character equivalences must be +expressed in your regular expression. + + Arguments: +text - text to test for pattern +match - pattern/substring to search for + + +File: autogen.info, Node: SCM =, Next: SCM *~*, Prev: SCM ~, Up: Common Functions + +3.5.45 'string-eqv?' - caseless match +------------------------------------- + +Usage: (= text match) +string-eqv?: Test to see if two strings are equivalent. 'equivalent' +means the strings match, but without regard to character case and +certain characters are considered 'equivalent'. Viz., '-', '_' and '^' +are equivalent. If the arguments are not strings, then the result of +the numeric comparison is returned. + + This is an overloaded operation. If the arguments are both numbers, +then the query is passed through to 'scm_num_eq_p()', otherwise the +result depends on the SCMs being strictly equal. + + Arguments: +text - text to test for pattern +match - pattern/substring to search for + + +File: autogen.info, Node: SCM *~*, Next: SCM *~~*, Prev: SCM =, Up: Common Functions + +3.5.46 'string-has-eqv-match?' - caseless regex contains +-------------------------------------------------------- + +Usage: (*~* text match) +string-has-eqv-match?: Test to see if a string contains a pattern. Case +is not significant. + + Arguments: +text - text to test for pattern +match - pattern/substring to search for + + +File: autogen.info, Node: SCM *~~*, Next: SCM ~~, Prev: SCM *~*, Up: Common Functions + +3.5.47 'string-has-match?' - contained regex match +-------------------------------------------------- + +Usage: (*~~* text match) +string-has-match?: Test to see if a string contains a pattern. Case is +significant. + + Arguments: +text - text to test for pattern +match - pattern/substring to search for + + +File: autogen.info, Node: SCM ~~, Next: SCM ~*, Prev: SCM *~~*, Up: Common Functions + +3.5.48 'string-match?' - regex match +------------------------------------ + +Usage: (~~ text match) +string-match?: Test to see if a string fully matches a pattern. Case is +significant. + + Arguments: +text - text to test for pattern +match - pattern/substring to search for + + +File: autogen.info, Node: SCM ~*, Next: SCM ~~*, Prev: SCM ~~, Up: Common Functions + +3.5.49 'string-start-eqv-match?' - caseless regex start +------------------------------------------------------- + +Usage: (~* text match) +string-start-eqv-match?: Test to see if a string starts with a pattern. +Case is not significant. + + Arguments: +text - text to test for pattern +match - pattern/substring to search for + + +File: autogen.info, Node: SCM ~~*, Next: SCM =*, Prev: SCM ~*, Up: Common Functions + +3.5.50 'string-start-match?' - regex match start +------------------------------------------------ + +Usage: (~~* text match) +string-start-match?: Test to see if a string starts with a pattern. +Case is significant. + + Arguments: +text - text to test for pattern +match - pattern/substring to search for + + +File: autogen.info, Node: SCM =*, Next: SCM ==*, Prev: SCM ~~*, Up: Common Functions + +3.5.51 'string-starts-eqv?' - caseless string start +--------------------------------------------------- + +Usage: (=* text match) +string-starts-eqv?: Test to see if a string starts with an equivalent +string. + + Arguments: +text - text to test for pattern +match - pattern/substring to search for + + +File: autogen.info, Node: SCM ==*, Next: SCM string-substitute, Prev: SCM =*, Up: Common Functions + +3.5.52 'string-starts-with?' - string starting +---------------------------------------------- + +Usage: (==* text match) +string-starts-with?: Test to see if a string starts with a substring. + + Arguments: +text - text to test for pattern +match - pattern/substring to search for + + +File: autogen.info, Node: SCM string-substitute, Next: SCM string-table-add, Prev: SCM ==*, Up: Common Functions + +3.5.53 'string-substitute' - multiple global replacements +--------------------------------------------------------- + +Usage: (string-substitute source match repl) +'match' and 'repl' may be either a single string or a list of strings. +Either way, they must have the same structure and number of elements. +For example, to replace all amphersands, less than and greater than +characters, do something like this: + + (string-substitute source + (list "&" "<" ">") + (list "&" "<" ">")) + + Arguments: +source - string to transform +match - substring or substring list to be replaced +repl - replacement strings or substrings + + +File: autogen.info, Node: SCM string-table-add, Next: SCM string-table-add-ref, Prev: SCM string-substitute, Up: Common Functions + +3.5.54 'string-table-add' - Add an entry to a string table +---------------------------------------------------------- + +Usage: (string-table-add st-name str-val) +Check for a duplicate string and, if none, then insert a new string into +the string table. In all cases, returns the character index of the +beginning of the string in the table. + + The returned index can be used in expressions like: + string_array + <returned-value> +that will yield the address of the first byte of the inserted string. +See the 'strtable.test' AutoGen test for a usage example. + + Arguments: +st-name - the name of the array of characters +str-val - the (possibly) new value to add + + +File: autogen.info, Node: SCM string-table-add-ref, Next: SCM string-table-new, Prev: SCM string-table-add, Up: Common Functions + +3.5.55 'string-table-add-ref' - Add an entry to a string table, get reference +----------------------------------------------------------------------------- + +Usage: (string-table-add-ref st-name str-val) +Identical to string-table-add, except the value returned is the string +"st-name" '+' and the index returned by string-table-add. + + Arguments: +st-name - the name of the array of characters +str-val - the (possibly) new value to add + + +File: autogen.info, Node: SCM string-table-new, Next: SCM string-table-size, Prev: SCM string-table-add-ref, Up: Common Functions + +3.5.56 'string-table-new' - create a string table +------------------------------------------------- + +Usage: (string-table-new st-name) +This function will create an array of characters. The companion +functions, (*Note SCM string-table-add::, *Note SCM +string-table-add-ref::, and *note SCM emit-string-table::) will insert +text and emit the populated table. + + With these functions, it should be much easier to construct +structures containing string offsets instead of string pointers. That +can be very useful when transmitting, storing or sharing data with +different address spaces. + +Here is a brief example copied from the strtable.test test: + + [+ (string-table-new "scribble") + (out-push-new) ;; redirect output to temporary + (define ct 1) +][+ + + FOR str IN that was the week that was +][+ + (set! ct (+ ct 1)) + +] + [+ (string-table-add-ref "scribble" (get "str")) +],[+ + ENDFOR +] + [+ (out-suspend "main") + (emit-string-table "scribble") + (ag-fprintf 0 "\nchar const *ap[%d] = {" ct) + (out-resume "main") + (out-pop #t) ;; now dump out the redirected output +] + NULL }; + +Some explanation: + +I added the '(out-push-new)' because the string table text is diverted +into an output stream named, "scribble" and I want to have the string +table emitted before the string table references. The string table +references are also emitted inside the 'FOR' loop. So, when the loop is +done, the current output is suspended under the name, "main" and the +"scribble" table is then emitted into the primary output. +('emit-string-table' inserts its output directly into the current output +stream. It does not need to be the last function in an AutoGen macro +block.) Next I 'ag-fprintf' the array-of-pointer declaration directly +into the current output. Finally I restore the "main" output stream and +'(out-pop #t)'-it into the main output stream. + + Here is the result. Note that duplicate strings are not repeated in +the string table: + + static char const scribble[18] = + "that\0" "was\0" "the\0" "week\0"; + + char const *ap[7] = { + scribble+0, + scribble+5, + scribble+9, + scribble+13, + scribble+0, + scribble+5, + NULL }; + + These functions use the global name space 'stt-*' in addition to the +function names. + + If you utilize this in your programming, it is recommended that you +prevent printf format usage warnings with the GCC option +'-Wno-format-contains-nul' + + Arguments: +st-name - the name of the array of characters + + +File: autogen.info, Node: SCM string-table-size, Next: SCM string->c-name!, Prev: SCM string-table-new, Up: Common Functions + +3.5.57 'string-table-size' - print the current size of a string table +--------------------------------------------------------------------- + +Usage: (string-table-size st-name) +Returns the current byte count of the string table. + + Arguments: +st-name - the name of the array of characters + + +File: autogen.info, Node: SCM string->c-name!, Next: SCM string->camelcase, Prev: SCM string-table-size, Up: Common Functions + +3.5.58 'string->c-name!' - map non-name chars to underscore +----------------------------------------------------------- + +Usage: (string->c-name! str) +Change all the graphic characters that are invalid in a C name token +into underscores. Whitespace characters are ignored. Any other +character type (i.e. non-graphic and non-white) will cause a failure. + + Arguments: +str - input/output string + + +File: autogen.info, Node: SCM string->camelcase, Next: SCM string-tr, Prev: SCM string->c-name!, Up: Common Functions + +3.5.59 'string->camelcase' - make a string be CamelCase +------------------------------------------------------- + +Usage: (string->camelcase str) +Capitalize the first letter of each block of letters and numbers, and +stripping out characters that are not alphanumerics. For example, +"alpha-beta0gamma" becomes "AlphaBeta0gamma". + + Arguments: +str - input/output string + + +File: autogen.info, Node: SCM string-tr, Next: SCM string-tr!, Prev: SCM string->camelcase, Up: Common Functions + +3.5.60 'string-tr' - convert characters with new result +------------------------------------------------------- + +Usage: (string-tr source match translation) +This is identical to 'string-tr!', except that it does not over-write +the previous value. + + Arguments: +source - string to transform +match - characters to be converted +translation - conversion list + + +File: autogen.info, Node: SCM string-tr!, Next: SCM string-upcase, Prev: SCM string-tr, Up: Common Functions + +3.5.61 'string-tr!' - convert characters +---------------------------------------- + +Usage: (string-tr! source match translation) +This is the same as the 'tr(1)' program, except the string to transform +is the first argument. The second and third arguments are used to +construct mapping arrays for the transformation of the first argument. + + It is too bad this little program has so many different and +incompatible implementations! + + Arguments: +source - string to transform +match - characters to be converted +translation - conversion list + + +File: autogen.info, Node: SCM string-upcase, Next: SCM string-upcase!, Prev: SCM string-tr!, Up: Common Functions + +3.5.62 'string-upcase' - upper case a new string +------------------------------------------------ + +Usage: (string-upcase str) +Create a new SCM string containing the same text as the original, only +all the lower case letters are changed to upper case. + + Arguments: +str - input string + + +File: autogen.info, Node: SCM string-upcase!, Next: SCM sub-shell-str, Prev: SCM string-upcase, Up: Common Functions + +3.5.63 'string-upcase!' - make a string be upper case +----------------------------------------------------- + +Usage: (string-upcase! str) +Change to upper case all the characters in an SCM string. + + Arguments: +str - input/output string + + +File: autogen.info, Node: SCM sub-shell-str, Next: SCM sum, Prev: SCM string-upcase!, Up: Common Functions + +3.5.64 'sub-shell-str' - back quoted (sub-)shell string +------------------------------------------------------- + +Usage: (sub-shell-str string) +This function is substantially identical to 'shell-str', except that the +quoting character is '`' and the "leave the escape alone" character is +'"'. + + Arguments: +string - string to transform + + +File: autogen.info, Node: SCM sum, Next: SCM time-string->number, Prev: SCM sub-shell-str, Up: Common Functions + +3.5.65 'sum' - sum of values in list +------------------------------------ + +Usage: (sum list ...) +Compute the sum of the list of expressions. + + Arguments: +list - list of values. Strings are converted to numbers + + +File: autogen.info, Node: SCM time-string->number, Next: SCM version-compare, Prev: SCM sum, Up: Common Functions + +3.5.66 'time-string->number' - duration string to seconds +--------------------------------------------------------- + +Usage: (time-string->number time_spec) +Convert the argument string to a time period in seconds. The string may +use multiple parts consisting of days, hours minutes and seconds. These +are indicated with a suffix of 'd', 'h', 'm' and 's' respectively. +Hours, minutes and seconds may also be represented with 'HH:MM:SS' or, +without hours, as 'MM:SS'. + + Arguments: +time_spec - string to parse + + +File: autogen.info, Node: SCM version-compare, Prev: SCM time-string->number, Up: Common Functions + +3.5.67 'version-compare' - compare two version numbers +------------------------------------------------------ + +Usage: (version-compare op v1 v2) +Converts v1 and v2 strings into 64 bit values and returns the result of +running 'op' on those values. It assumes that the version is a 1 to 4 +part dot-separated series of numbers. Suffixes like, "5pre4" or +"5-pre4" will be interpreted as two numbers. The first number ("5" in +this case) will be decremented and the number after the "pre" will be +added to 0xC000. (Unless your platform is unable to support 64 bit +integer arithmetic. Then it will be added to 0xC0.) Consequently, +these yield true: + (version-compare > "5.8.5" "5.8.5-pre4") + (version-compare > "5.8.5-pre10" "5.8.5-pre4") + + Arguments: +op - comparison operator +v1 - first version +v2 - compared-to version + + +File: autogen.info, Node: native macros, Next: output controls, Prev: Common Functions, Up: Template File + +3.6 AutoGen Native Macros +========================= + +This section describes the various AutoGen natively defined macros. +Unlike the Scheme functions, some of these macros are "block macros" +with a scope that extends through a terminating macro. Block macros +must not overlap. That is to say, a block macro started within the +scope of an encompassing block macro must have its matching end macro +appear before the encompassing block macro is either ended or +subdivided. + + The block macros are these: + +'CASE' + This macro has scope through the 'ESAC' macro. The scope is + subdivided by 'SELECT' macros. You must have at least one 'SELECT' + macro. + +'DEFINE' + This macro has scope through the 'ENDDEF' macro. The defined user + macro can never be a block macro. This macro is extracted from the + template before the template is processed. Consequently, you + cannot select a definition based on context. You can, however, + place them all at the end of the file. + +'FOR' + This macro has scope through the 'ENDFOR' macro. + +'IF' + This macro has scope through the 'ENDIF' macro. The scope may be + subdivided by 'ELIF' and 'ELSE' macros. Obviously, there may be + only one 'ELSE' macro and it must be the last of these + subdivisions. + +'INCLUDE' + This macro has the scope of the included file. It is a block macro + in the sense that the included file must not contain any incomplete + block macros. + +'WHILE' + This macro has scope through the 'ENDWHILE' macro. +* Menu: + +* AGMacro syntax:: AutoGen Macro Syntax +* BREAK:: BREAK - Leave a FOR or WHILE macro +* CASE:: CASE - Select one of several template blocks +* COMMENT:: COMMENT - A block of comment to be ignored +* CONTINUE:: CONTINUE - Skip to end of a FOR or WHILE macro. +* DEBUG:: DEBUG - Print debug message to trace output +* DEFINE:: DEFINE - Define a user AutoGen macro +* ELIF:: ELIF - Alternate Conditional Template Block +* ELSE:: ELSE - Alternate Template Block +* ENDDEF:: ENDDEF - Ends a macro definition. +* ENDFOR:: ENDFOR - Terminates the 'FOR' function template block +* ENDIF:: ENDIF - Terminate the 'IF' Template Block +* ENDWHILE:: ENDWHILE - Terminate the 'WHILE' Template Block +* ESAC:: ESAC - Terminate the 'CASE' Template Block +* EXPR:: EXPR - Evaluate and emit an Expression +* FOR:: FOR - Emit a template block multiple times +* IF:: IF - Conditionally Emit a Template Block +* INCLUDE:: INCLUDE - Read in and emit a template block +* INVOKE:: INVOKE - Invoke a User Defined Macro +* RETURN:: RETURN - Leave an INVOKE-d (DEFINE) macro +* SELECT:: SELECT - Selection block for CASE function +* UNKNOWN:: UNKNOWN - Either a user macro or a value name. +* WHILE:: WHILE - Conditionally loop over a Template Block +* shell command:: Inserting text from a shell script +* guile command:: Inserting text from a scheme script + + +File: autogen.info, Node: AGMacro syntax, Next: BREAK, Up: native macros + +3.6.1 AutoGen Macro Syntax +-------------------------- + +The general syntax is: + + [ { <native-macro-name> | <user-defined-name> } ] [ <arg> ... ] + +The syntax for '<arg>' depends on the particular macro, but is generally +a full expression (*note expression syntax::). Here are the exceptions +to that general rule: + + 1. 'INVOKE' macros, implicit or explicit, must be followed by a list + of name/string value pairs. The string values are simple + expressions, as described above. + + That is, the 'INVOKE' syntax is one of these two: + <user-macro-name> [ <name> [ = <expression> ] ... ] + + INVOKE <name-expression> [ <name> [ = <expression> ] ... ] + + 2. AutoGen FOR macros must be in one of three forms: + + FOR <name> [ <separator-string> ] + + FOR <name> (...Scheme expression list) + + FOR <name> IN <string-entry> [ ... ] + where: + '<name>' + must be a simple name. + '<separator-string>' + is inserted between copies of the enclosed block. Do not try + to use "IN" as your separator string. It won't work. + '<string-entry>' + is an entry in a list of strings. "'<name>'" is assigned each + value from the "'IN'" list before expanding the 'FOR' block. + '(...Scheme expression list)' + is expected to contain one or more of the 'for-from', + 'for-to', 'for-by', and 'for-sep' functions. (*Note FOR::, + and *note AutoGen Functions::) + + The first two forms iterate over the 'FOR' block if '<name>' is + found in the AutoGen values. The last form will create the AutoGen + value named '<name>'. + + 3. AutoGen 'DEFINE' macros must be followed by a simple name. + Anything after that is ignored. Consequently, that "comment space" + may be used to document any named values the macro expects to have + set up as arguments. *Note DEFINE::. + + 4. The AutoGen 'COMMENT', 'ELSE', 'ESAC' and the 'END*' macros take no + arguments and ignore everything after the macro name (e.g. see + *note COMMENT::) + + +File: autogen.info, Node: BREAK, Next: CASE, Prev: AGMacro syntax, Up: native macros + +3.6.2 BREAK - Leave a FOR or WHILE macro +---------------------------------------- + +This will unwind the loop context and resume after ENDFOR/ENDWHILE. Note +that unless this happens to be the last iteration anyway, the +(last-for?) function will never yield "#t". + + +File: autogen.info, Node: CASE, Next: COMMENT, Prev: BREAK, Up: native macros + +3.6.3 CASE - Select one of several template blocks +-------------------------------------------------- + +The arguments are evaluated and converted to a string, if necessary. A +simple name will be interpreted as an AutoGen value name and its value +will be used by the 'SELECT' macros (see the example below and the +expression evaluation function, *note EXPR::). The scope of the macro +is up to the matching 'ESAC' macro. Within the scope of a 'CASE', this +string is matched against case selection macros. There are sixteen +match macros that are derived from four different ways matches may be +performed, plus an "always true", "true if the AutoGen value was found", +and "true if no AutoGen value was found" matches. The codes for the +nineteen match macros are formed as follows: + + 1. Must the match start matching from the beginning of the string? If + not, then the match macro code starts with an asterisk ('*'). + 2. Must the match finish matching at the end of the string? If not, + then the match macro code ends with an asterisk ('*'). + 3. Is the match a pattern match or a string comparison? If a + comparison, use an equal sign ('='). If a pattern match, use a + tilde ('~'). + 4. Is the match case sensitive? If alphabetic case is important, + double the tilde or equal sign. + 5. Do you need a default match when none of the others match? Use a + single asterisk ('*'). + 6. Do you need to distinguish between an empty string value and a + value that was not found? Use the non-existence test ('!E') before + testing a full match against an empty string ('== '''). There is + also an existence test ('+E'), more for symmetry than for practical + use. + +For example: + + [+ CASE <full-expression> +] + [+ ~~* "[Tt]est" +]reg exp must match at start, not at end + [+ == "TeSt" +]a full-string, case sensitive compare + [+ = "TEST" +]a full-string, case insensitive compare + [+ !E +]not exists - matches if no AutoGen value found + [+ == "" +]expression yielded a zero-length string + [+ +E +]exists - matches if there is any value result + [+ * +]always match - no testing + [+ ESAC +] + + '<full-expression>' (*note expression syntax::) may be any +expression, including the use of apply-codes and value-names. If the +expression yields a number, it is converted to a decimal string. + + These case selection codes have also been implemented as Scheme +expression functions using the same codes. They are documented in this +texi doc as "string-*?" predicates (*note Common Functions::). + + +File: autogen.info, Node: COMMENT, Next: CONTINUE, Prev: CASE, Up: native macros + +3.6.4 COMMENT - A block of comment to be ignored +------------------------------------------------ + +This function can be specified by the user, but there will never be a +situation where it will be invoked at emit time. The macro is actually +removed from the internal representation. + + If the native macro name code is '#', then the entire macro function +is treated as a comment and ignored. + + [+ # say what you want, but no '+' before any ']' chars +] + + +File: autogen.info, Node: CONTINUE, Next: DEBUG, Prev: COMMENT, Up: native macros + +3.6.5 CONTINUE - Skip to end of a FOR or WHILE macro. +----------------------------------------------------- + +This will skip the remainder of the loop and start the next. + + +File: autogen.info, Node: DEBUG, Next: DEFINE, Prev: CONTINUE, Up: native macros + +3.6.6 DEBUG - Print debug message to trace output +------------------------------------------------- + +If the tracing level is at "debug-message" or above (*note autogen +trace::), this macro prints a debug message to trace output. This +message is not evaluated. This macro can also be used to set useful +debugger breakpoints. By inserting [+DEBUG n+] into your template, you +can set a debugger breakpoint on the #n case element below (in the +AutoGen source) and step through the processing of interesting parts of +your template. + + To be useful, you have to have access to the source tree where +autogen was built and the template being processed. The definitions are +also helpful, but not crucial. Please contact the author if you think +you might actually want to use this. + + +File: autogen.info, Node: DEFINE, Next: ELIF, Prev: DEBUG, Up: native macros + +3.6.7 DEFINE - Define a user AutoGen macro +------------------------------------------ + +This function will define a new macro. You must provide a name for the +macro. You do not specify any arguments, though the invocation may +specify a set of name/value pairs that are to be active during the +processing of the macro. + + [+ define foo +] + ... macro body with macro functions ... + [+ enddef +] + ... [+ foo bar='raw text' baz=<<text expression>> +] + + Once the macro has been defined, this new macro can be invoked by +specifying the macro name as the first token after the start macro +marker. Alternatively, you may make the invocation explicitly invoke a +defined macro by specifying 'INVOKE' (*note INVOKE::) in the macro +invocation. If you do that, the macro name can be computed with an +expression that gets evaluated every time the INVOKE macro is +encountered. + + Any remaining text in the macro invocation will be used to create new +name/value pairs that only persist for the duration of the processing of +the macro. The expressions are evaluated the same way basic expressions +are evaluated. *Note expression syntax::. + + The resulting definitions are handled much like regular definitions, +except: + + 1. The values may not be compound. That is, they may not contain + nested name/value pairs. + 2. The bindings go away when the macro is complete. + 3. The name/value pairs are separated by whitespace instead of + semi-colons. + 4. Sequences of strings are not concatenated. + + *NB:* The macro is extracted from the template as the template is + scanned. You cannot conditionally define a macro by enclosing it + in an 'IF'/'ENDIF' (*note IF::) macro pair. If you need to + dynamically select the format of a 'DEFINE'd macro, then put the + flavors into separate template files that simply define macros. + 'INCLUDE' (*note INCLUDE::) the appropriate template when you have + computed which you need. + + Due to this, it is acceptable and even a good idea to place all the +'DEFINE' macros at the end of the template. That puts the main body of +the template at the beginning of the file. + + +File: autogen.info, Node: ELIF, Next: ELSE, Prev: DEFINE, Up: native macros + +3.6.8 ELIF - Alternate Conditional Template Block +------------------------------------------------- + +This macro must only appear after an 'IF' function, and before any +associated 'ELSE' or 'ENDIF' functions. It denotes the start of an +alternate template block for the 'IF' function. Its expression argument +is evaluated as are the arguments to 'IF'. For a complete description +*Note IF::. + + +File: autogen.info, Node: ELSE, Next: ENDDEF, Prev: ELIF, Up: native macros + +3.6.9 ELSE - Alternate Template Block +------------------------------------- + +This macro must only appear after an 'IF' function, and before the +associated 'ENDIF' function. It denotes the start of an alternate +template block for the 'IF' function. For a complete description *Note +IF::. + + +File: autogen.info, Node: ENDDEF, Next: ENDFOR, Prev: ELSE, Up: native macros + +3.6.10 ENDDEF - Ends a macro definition. +---------------------------------------- + +This macro ends the 'DEFINE' function template block. For a complete +description *Note DEFINE::. + + +File: autogen.info, Node: ENDFOR, Next: ENDIF, Prev: ENDDEF, Up: native macros + +3.6.11 ENDFOR - Terminates the 'FOR' function template block +------------------------------------------------------------ + +This macro ends the 'FOR' function template block. For a complete +description *Note FOR::. + + +File: autogen.info, Node: ENDIF, Next: ENDWHILE, Prev: ENDFOR, Up: native macros + +3.6.12 ENDIF - Terminate the 'IF' Template Block +------------------------------------------------ + +This macro ends the 'IF' function template block. For a complete +description *Note IF::. + + +File: autogen.info, Node: ENDWHILE, Next: ESAC, Prev: ENDIF, Up: native macros + +3.6.13 ENDWHILE - Terminate the 'WHILE' Template Block +------------------------------------------------------ + +This macro ends the 'WHILE' function template block. For a complete +description *Note WHILE::. + + +File: autogen.info, Node: ESAC, Next: EXPR, Prev: ENDWHILE, Up: native macros + +3.6.14 ESAC - Terminate the 'CASE' Template Block +------------------------------------------------- + +This macro ends the 'CASE' function template block. For a complete +description, *Note CASE::. + + +File: autogen.info, Node: EXPR, Next: FOR, Prev: ESAC, Up: native macros + +3.6.15 EXPR - Evaluate and emit an Expression +--------------------------------------------- + +This macro does not have a name to cause it to be invoked explicitly, +though if a macro starts with one of the apply codes or one of the +simple expression markers, then an expression macro is inferred. The +result of the expression evaluation (*note expression syntax::) is +written to the current output. + + +File: autogen.info, Node: FOR, Next: IF, Prev: EXPR, Up: native macros + +3.6.16 FOR - Emit a template block multiple times +------------------------------------------------- + +This macro has a slight variation on the standard syntax: + FOR <value-name> [ <separator-string> ] + + FOR <value-name> (...Scheme expression list) + + FOR <value-name> IN "string" [ ... ] + + Other than for the last form, the first macro argument must be the +name of an AutoGen value. If there is no value associated with the +name, the 'FOR' template block is skipped entirely. The scope of the +'FOR' macro extends to the corresponding 'ENDFOR' macro. The last form +will create an array of string values named '<value-name>' that only +exists within the context of this 'FOR' loop. With this form, in order +to use a 'separator-string', you must code it into the end of the +template block using the '(last-for?)' predicate function (*note SCM +last-for?::). + + If there are any arguments after the 'value-name', the initial +characters are used to determine the form. If the first character is +either a semi-colon (';') or an opening parenthesis ('('), then it is +presumed to be a Scheme expression containing the FOR macro specific +functions 'for-from', 'for-by', 'for-to', and/or 'for-sep'. *Note +AutoGen Functions::. If it consists of an ''i'' an ''n'' and separated +by white space from more text, then the 'FOR x IN' form is processed. +Otherwise, the remaining text is presumed to be a string for inserting +between each iteration of the loop. This string will be emitted one +time less than the number of iterations of the loop. That is, it is +emitted after each loop, excepting for the last iteration. + + If the from/by/to functions are invoked, they will specify which +copies of the named value are to be processed. If there is no copy of +the named value associated with a particular index, the 'FOR' template +block will be instantiated anyway. The template must use 'found-for?' +(*note SCM found-for?::) or other methods for detecting missing +definitions and emitting default text. In this fashion, you can insert +entries from a sparse or non-zero based array into a dense, zero based +array. + + *NB:* the 'for-from', 'for-to', 'for-by' and 'for-sep' functions are +disabled outside of the context of the 'FOR' macro. Likewise, the +'first-for?', 'last-for?' 'for-index', and 'found-for?' functions are +disabled outside of the range of a 'FOR' block. + + *Also:* the '<value-name>' must be a single level name, not a +compound name (*note naming values::). + + [+FOR var (for-from 0) (for-to <number>) (for-sep ",") +] + ... text with various substitutions ...[+ + ENDFOR var+] + +this will repeat the '... text with various substitutions ...' +<number>+1 times. Each repetition, except for the last, will have a +comma ',' after it. + + [+FOR var ",\n" +] + ... text with various substitutions ...[+ + ENDFOR var +] + +This will do the same thing, but only for the index values of 'var' that +have actually been defined. + + +File: autogen.info, Node: IF, Next: INCLUDE, Prev: FOR, Up: native macros + +3.6.17 IF - Conditionally Emit a Template Block +----------------------------------------------- + +Conditional block. Its arguments are evaluated (*note EXPR::) and if +the result is non-zero or a string with one or more bytes, then the +condition is true and the text from that point until a matched 'ELIF', +'ELSE' or 'ENDIF' is emitted. 'ELIF' introduces a conditional +alternative if the 'IF' clause evaluated FALSE and 'ELSE' introduces an +unconditional alternative. + + [+IF <full-expression> +] + emit things that are for the true condition[+ + + ELIF <full-expression-2> +] + emit things that are true maybe[+ + + ELSE "This may be a comment" +] + emit this if all but else fails[+ + + ENDIF "This may *also* be a comment" +] + +'<full-expression>' may be any expression described in the 'EXPR' +expression function, including the use of apply-codes and value-names. +If the expression yields an empty string, it is interpreted as false. + + +File: autogen.info, Node: INCLUDE, Next: INVOKE, Prev: IF, Up: native macros + +3.6.18 INCLUDE - Read in and emit a template block +-------------------------------------------------- + +The entire contents of the named file is inserted at this point. The +contents of the file are processed for macro expansion. The arguments +are eval-ed, so you may compute the name of the file to be included. +The included file must not contain any incomplete function blocks. +Function blocks are template text beginning with any of the macro +functions 'CASE', 'DEFINE', 'FOR', 'IF' and 'WHILE'; extending through +their respective terminating macro functions. + + +File: autogen.info, Node: INVOKE, Next: RETURN, Prev: INCLUDE, Up: native macros + +3.6.19 INVOKE - Invoke a User Defined Macro +------------------------------------------- + +User defined macros may be invoked explicitly or implicitly. If you +invoke one implicitly, the macro must begin with the name of the defined +macro. Consequently, this may *not* be a computed value. If you +explicitly invoke a user defined macro, the macro begins with the macro +name 'INVOKE' followed by a basic expression that must yield a known +user defined macro. A macro name _must_ be found, or AutoGen will issue +a diagnostic and exit. + + Arguments are passed to the invoked macro by name. The text +following the macro name must consist of a series of names each of which +is followed by an equal sign ('=') and a basic expression that yields a +string. + + The string values may contain template macros that are parsed the +first time the macro is processed and evaluated again every time the +macro is evaluated. + + +File: autogen.info, Node: RETURN, Next: SELECT, Prev: INVOKE, Up: native macros + +3.6.20 RETURN - Leave an INVOKE-d (DEFINE) macro +------------------------------------------------ + +This will unwind looping constructs inside of a DEFINE-d macro and +return to the invocation point. The output files and diversions are +left alone. This means it is unwise to start diversions in a DEFINEd +macro and RETURN from it before you have handled the diversion. Unless +you are careful. Here is some rope for you. Please be careful using +it. + + +File: autogen.info, Node: SELECT, Next: UNKNOWN, Prev: RETURN, Up: native macros + +3.6.21 SELECT - Selection block for CASE function +------------------------------------------------- + +This macro selects a block of text by matching an expression against the +sample text expression evaluated in the 'CASE' macro. *Note CASE::. + + You do not specify a 'SELECT' macro with the word "select". Instead, +you must use one of the 19 match operators described in the 'CASE' macro +description. + + +File: autogen.info, Node: UNKNOWN, Next: WHILE, Prev: SELECT, Up: native macros + +3.6.22 UNKNOWN - Either a user macro or a value name. +----------------------------------------------------- + +The macro text has started with a name not known to AutoGen. If, at run +time, it turns out to be the name of a defined macro, then that macro is +invoked. If it is not, then it is a conditional expression that is +evaluated only if the name is defined at the time the macro is invoked. + + You may not specify 'UNKNOWN' explicitly. + + +File: autogen.info, Node: WHILE, Next: shell command, Prev: UNKNOWN, Up: native macros + +3.6.23 WHILE - Conditionally loop over a Template Block +------------------------------------------------------- + +Conditionally repeated block. Its arguments are evaluated (*note +EXPR::) and as long as the result is non-zero or a string with one or +more bytes, then the condition is true and the text from that point +until a matched 'ENDWHILE' is emitted. + + [+WHILE <full-expression> +] + emit things that are for the true condition[+ + + ENDWHILE +] + +'<full-expression>' may be any expression described in the 'EXPR' +expression function, including the use of apply-codes and value-names. +If the expression yields an empty string, it is interpreted as false. + + +File: autogen.info, Node: shell command, Next: guile command, Prev: WHILE, Up: native macros + +3.6.24 Inserting text from a shell script +----------------------------------------- + +If the text between the start and end macro markers starts with an +opening curly brace (''{'') or is surrounded by back quotes (''`''), +then the text is handed off to the server shell for evaluation. The +output to standard out is inserted into the document. If the text +starts with the curly brace, all the text is passed off as is to the +shell. If surrounded by back quotes, then the string is "cooked" before +being handed off to the shell. + + +File: autogen.info, Node: guile command, Prev: shell command, Up: native macros + +3.6.25 Inserting text from a scheme script +------------------------------------------ + +If the text between the start and end macro markers starts with a +semi-colon or an opening parenthesis, all the text is handed off to the +Guile/scheme processor. If the last result is text or a number, it is +added (as text) to the output document. + + +File: autogen.info, Node: output controls, Prev: native macros, Up: Template File + +3.7 Redirecting Output +====================== + +AutoGen provides a means for redirecting the template output to +different files or, in 'M4' parlance, to various diversions. It is +accomplished by providing a set of Scheme functions named 'out-*' (*note +AutoGen Functions::). + +'out-push-new (*note SCM out-push-new::)' + This allows you to logically "push" output files onto a stack. If + you supply a string name, then a file by that name is created to + hold the output. If you do not supply a name, then the text is + written to a scratch pad and retrieved by passing a '#t' argument + to the 'out-pop' (*note SCM out-pop::) function. + +'out-pop (*note SCM out-pop::)' + This function closes the current output file and resumes output to + the next one in the stack. At least one output must have been + pushed onto the output stack with the 'out-push-new' (*note SCM + out-push-new::) function. If '#t' is passed in as an argument, + then the entire contents of the diversion (or file) is returned. + +'out-suspend (*note SCM out-suspend::)' + This function does not close the current output, but instead sets + it aside for resumption by the given name with 'out-resume'. The + current output must have been pushed on the output queue with + 'out-push-new' (*note SCM out-push-new::). + +'out-resume (*note SCM out-resume::)' + This will put a named file descriptor back onto the top of stack so + that it becomes the current output again. + +'out-switch (*note SCM out-switch::)' + This closes the current output and creates a new file, purging any + preexisting one. This is a shortcut for "pop" followed by "push", + but this can also be done at the base level. + +'out-move (*note SCM out-move::)' + Renames the current output file without closing it. + + There are also several functions for determining the output status. +*Note AutoGen Functions::. + + +File: autogen.info, Node: Augmenting AutoGen, Next: autogen Invocation, Prev: Template File, Up: Top + +4 Augmenting AutoGen Features +***************************** + +AutoGen was designed to be simple to enhance. You can do it by +providing shell commands, Guile/Scheme macros or callout functions that +can be invoked as a Guile macro. Here is how you do these. + +* Menu: + +* shell commands:: Shell Output Commands +* guile macros:: Guile Macros +* guile callouts:: Guile Callout Functions +* AutoGen macros:: AutoGen Macros + + +File: autogen.info, Node: shell commands, Next: guile macros, Up: Augmenting AutoGen + +4.1 Shell Output Commands +========================= + +Shell commands are run inside of a server process. This means that, +unlike 'make', context is kept from one command to the next. +Consequently, you can define a shell function in one place inside of +your template and invoke it in another. You may also store values in +shell variables for later reference. If you load functions from a file +containing shell functions, they will remain until AutoGen exits. + + If your shell script should determine that AutoGen should stop +processing, the recommended method for stopping AutoGen is: + die "some error text" + +That is a shell function added by AutoGen. It will send a SIGTERM to +autogen and exit from the "persistent" shell. + + +File: autogen.info, Node: guile macros, Next: guile callouts, Prev: shell commands, Up: Augmenting AutoGen + +4.2 Guile Macros +================ + +Guile also maintains context from one command to the next. This means +you may define functions and variables in one place and reference them +elsewhere. If your Scheme script should determine that AutoGen should +stop processing, the recommended method for stopping AutoGen is: + (error "some error text") + + +File: autogen.info, Node: guile callouts, Next: AutoGen macros, Prev: guile macros, Up: Augmenting AutoGen + +4.3 Guile Callout Functions +=========================== + +Callout functions must be registered with Guile to work. This can be +accomplished either by putting your routines into a shared library that +contains a 'void scm_init(void)' routine that registers these routines, +or by building them into AutoGen. + + To build them into AutoGen, you must place your routines in the +source directory and name the files 'exp*.c'. You also must have a +stylized comment that 'getdefs' can find that conforms to the following: + + /*=gfunc <function-name> + * + * what: <short one-liner> + * general_use: + * string: <invocation-name-string> + * exparg: <name>, <description> [, ['optional'] [, 'list']] + * doc: A long description telling people how to use + * this function. + =*/ + SCM + ag_scm_<function-name>( SCM arg_name[, ...] ) + { <code> } + +'gfunc' + You must have this exactly thus. + +'<function-name>' + This must follow C syntax for variable names + +'<short one-liner>' + This should be about a half a line long. It is used as a + subsection title in this document. + +'general_use:' + You must supply this unless you are an AutoGen maintainer and are + writing a function that queries or modifies the state of AutoGen. + +'<invocation-name-string>' + Normally, the FUNCTION-NAME string will be transformed into a + reasonable invocation name. However, that is not always true. If + the result does not suit your needs, then supply an alternate + string. + +'exparg:' + You must supply one for each argument to your function. All + optional arguments must be last. The last of the optional + arguments may be a list, if you choose. + +'doc:' + Please say something meaningful. + +'[, ...]' + Do not actually specify an ANSI ellipsis here. You must provide + for all the arguments you specified with EXPARG. + + See the Guile documentation for more details. More information is +also available in a large comment at the beginning of the +'agen5/snarf.tpl' template file. + + +File: autogen.info, Node: AutoGen macros, Prev: guile callouts, Up: Augmenting AutoGen + +4.4 AutoGen Macros +================== + +There are two kinds those you define yourself and AutoGen native. The +user-defined macros may be defined in your templates, *Note DEFINE::. + + As for AutoGen native macros, do not add any. It is easy to do, but +I won't like it. The basic functions needed to accomplish looping over +and selecting blocks of text have proved to be sufficient over a period +of several years. New text transformations can be easily added via any +of the AutoGen extension methods, as discussed above. + + +File: autogen.info, Node: autogen Invocation, Next: Installation, Prev: Augmenting AutoGen, Up: Top + +5 Invoking autogen +****************** + +AutoGen creates text files from templates using external definitions. + + 'AutoGen' is designed for generating program files that contain +repetitive text with varied substitutions. The goal is to simplify the +maintenance of programs that contain large amounts of repetitious text. +This is especially valuable if there are several blocks of such text +that must be kept synchronized. + + One common example is the problem of maintaining the code required +for processing program options. Processing options requires a minimum +of four different constructs be kept in proper order in different places +in your program. You need at least: The flag character in the flag +string, code to process the flag when it is encountered, a global state +variable or two, and a line in the usage text. You will need more +things besides this if you choose to implement long option names, +configuration file processing, environment variables and so on. + + All of this can be done mechanically; with the proper templates and +this program. + + This chapter was generated by *AutoGen*, using the 'agtexi-cmd' +template and the option descriptions for the 'autogen' program. This +software is released under the GNU General Public License, version 3 or +later. + +* Menu: + +* autogen usage:: autogen help/usage ('--help') +* autogen input-select:: input-select options +* autogen out-handling:: out-handling options +* autogen debug-tpl:: debug-tpl options +* autogen processing:: processing options +* autogen dep-track:: dep-track options +* autogen autoopts-opts:: autoopts-opts options +* autogen config:: presetting/configuring autogen +* autogen exit status:: exit status +* autogen Examples:: Examples + + +File: autogen.info, Node: autogen usage, Next: autogen input-select, Up: autogen Invocation + +5.1 autogen help/usage ('--help') +================================= + +This is the automatically generated usage text for autogen. + + The text printed is the same whether selected with the 'help' option +('--help') or the 'more-help' option ('--more-help'). 'more-help' will +print the usage text by passing it through a pager program. 'more-help' +is disabled on platforms without a working 'fork(2)' function. The +'PAGER' environment variable is used to select the program, defaulting +to 'more'. Both will exit with a status code of 0. + + autogen (GNU AutoGen) - The Automated Program Generator - Ver. 5.18.15.001 + Usage: autogen [ -<flag> [<val>] | --<name>[{=| }<val>] ]... [ <def-file> ] + + The following options select definitions, templates and scheme functions + to use: + + Flg Arg Option-Name Description + -L Str templ-dirs Search for templates in DIR + - may appear multiple times + -T Str override-tpl Use TPL-FILE for the template + - may not be preset + Str definitions Read definitions from FILE + - disabled as '--no-definitions' + - enabled by default + - may not be preset + Str shell name or path name of shell to use + -m no no-fmemopen Do not use in-mem streams + Str equate characters considered equivalent + + The following options modify how output is handled: + + Flg Arg Option-Name Description + -b Str base-name Specify NAME as the base name for output + - may not be preset + no source-time set mod times to latest source + - disabled as '--no-source-time' + no writable Allow output files to be writable + - disabled as '--not-writable' + + The following options are often useful while debugging new templates: + + Flg Arg Option-Name Description + Num loop-limit Limit on increment loops + - is scalable with a suffix: k/K/m/M/g/G/t/T + - it must lie in one of the ranges: + -1 exactly, or + 1 to 16777216 + -t Num timeout Limit server shell operations to SECONDS + - it must be in the range: + 0 to 3600 + KWd trace tracing level of detail + Str trace-out tracing output file or filter + --- show-defs This option has been disabled + no used-defines Show the definitions used + - may not be preset + -C no core Leave a core dump on a failure exit + + These options can be used to control what gets processed in the + definitions files and template files: + + Flg Arg Option-Name Description + -s Str skip-suffix Skip the file with this SUFFIX + - prohibits the option 'select-suffix' + - may not be preset + - may appear multiple times + -o Str select-suffix specify this output suffix + - may not be preset + - may appear multiple times + -D Str define name to add to definition list + - may appear multiple times + -U Str undefine definition list removal pattern + - an alternate for 'define' + + This option is used to automate dependency tracking: + + Flg Arg Option-Name Description + -M opt make-dep emit make dependency file + - may not be preset + - may appear multiple times + + help, version, option and error handling: + + Flg Arg Option-Name Description + no no-abort Do not abort on errors + + Version, usage and configuration options: + + Flg Arg Option-Name Description + -R Str reset-option reset an option's state + -v opt version output version information and exit + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + -u no usage abbreviated usage to stdout + -> opt save-opts save the option state to a config file + -< Str load-opts load options from a config file + - disabled as '--no-load-opts' + - may appear multiple times + + Options are specified by doubled hyphens and their name or by a single + hyphen and the flag character. + AutoGen creates text files from templates using external definitions. + + The following option preset mechanisms are supported: + - reading file $HOME + - reading file ./.autogenrc + - examining environment variables named AUTOGEN_* + + The valid "trace" option keywords are: + nothing debug-message server-shell templates block-macros + expressions everything + or an integer from 0 through 6 + AutoGen is a tool designed for generating program files that contain + repetitive text with varied substitutions. + + Please send bug reports to: <autogen-users@lists.sourceforge.net> + + +File: autogen.info, Node: autogen input-select, Next: autogen out-handling, Prev: autogen usage, Up: autogen Invocation + +5.2 input-select options +======================== + +The following options select definitions, templates and scheme functions +to use. + +templ-dirs option (-L). +----------------------- + +This is the "search for templates in 'dir'" option. This option takes a +string argument 'DIR'. + +This option has some usage constraints. It: + * may appear an unlimited number of times. + + Add a directory to the list of directories 'autogen' searches when +opening a template, either as the primary template or an included one. +The last entry has the highest priority in the search list. That is to +say, they are searched in reverse order. + +override-tpl option (-T). +------------------------- + +This is the "use 'tpl-file' for the template" option. This option takes +a string argument 'TPL-FILE'. + +This option has some usage constraints. It: + * may not be preset with environment variables or configuration + (rc/ini) files. + + Definition files specify the standard template that is to be +expanded. This option will override that name and expand a different +template. + +definitions option. +------------------- + +This is the "read definitions from 'file'" option. This option takes a +string argument 'FILE'. + +This option has some usage constraints. It: + * can be disabled with -no-definitions. + * It is enabled by default. + * may not be preset with environment variables or configuration + (rc/ini) files. + + Use this argument to specify the input definitions file with a +command line option. If you do not specify this option, then there must +be a command line argument that specifies the file, even if only to +specify stdin with a hyphen ('-'). Specify, '--no-definitions' when you +wish to process a template without any active AutoGen definitions. + +shell option. +------------- + +This is the "name or path name of shell to use" option. This option +takes a string argument 'shell'. + +This option has some usage constraints. It: + * must be compiled in by defining 'SHELL_ENABLED' during the + compilation. + + By default, when AutoGen is built, the configuration is probed for a +reasonable Bourne-like shell to use for shell script processing. If a +particular template needs an alternate shell, it must be specified with +this option on the command line, with an environment variable ('SHELL') +or in the configuration/initialization file. + +no-fmemopen option (-m). +------------------------ + +This is the "do not use in-mem streams" option. If the local C library +supports "'fopencookie(3GNU)'", or "'funopen(3BSD)'" then AutoGen +prefers to use in-memory stream buffer opens instead of anonymous files. +This may lead to problems if there is a shortage of virtual memory. If, +for a particular application, you run out of memory, then specify this +option. This is unlikely in a modern 64-bit virtual memory environment. + + On platforms without these functions, the option is accepted but +ignored. 'fmemopen(POSIX)' is not adequate because its string buffer is +not reallocatable. 'open_memstream(POSIX)' is also not adequate because +the stream is only opened for output. AutoGen needs a reallocatable +buffer available for both reading and writing. + +equate option. +-------------- + +This is the "characters considered equivalent" option. This option +takes a string argument 'char-list'. This option will alter the list of +characters considered equivalent. The default are the three characters, +"_-^". (The last is conventional on a Tandem/HP-NonStop, and I used to +do a lot of work on Tandems.) + + +File: autogen.info, Node: autogen out-handling, Next: autogen debug-tpl, Prev: autogen input-select, Up: autogen Invocation + +5.3 out-handling options +======================== + +The following options modify how output is handled. + +base-name option (-b). +---------------------- + +This is the "specify 'name' as the base name for output" option. This +option takes a string argument 'NAME'. + +This option has some usage constraints. It: + * may not be preset with environment variables or configuration + (rc/ini) files. + + A template may specify the exact name of the output file. Normally, +it does not. Instead, the name is composed of the base name of the +definitions file with suffixes appended. This option will override the +base name derived from the definitions file name. This is required if +there is no definitions file and advisable if definitions are being read +from stdin. If the definitions are being read from standard in, the +base name defaults to 'stdin'. Any leading directory components in the +name will be silently removed. If you wish the output file to appear in +a particular directory, it is recommended that you "cd" into that +directory first, or use directory names in the format specification for +the output suffix lists, *Note pseudo macro::. + +source-time option. +------------------- + +This is the "set mod times to latest source" option. + +This option has some usage constraints. It: + * can be disabled with -no-source-time. + + If you stamp your output files with the 'DNE' macro output, then your +output files will always be different, even if the content has not +really changed. If you use this option, then the modification time of +the output files will change only if the input files change. This will +help reduce unneeded builds. + +writable option. +---------------- + +This is the "allow output files to be writable" option. + +This option has some usage constraints. It: + * can be disabled with -not-writable. + + This option will leave output files writable. Normally, output files +are read-only. + + +File: autogen.info, Node: autogen debug-tpl, Next: autogen processing, Prev: autogen out-handling, Up: autogen Invocation + +5.4 debug-tpl options +===================== + +The following options are often useful while debugging new templates. +They specify limits that prevent the template from taking overly long or +producing more output than expected. + +loop-limit option. +------------------ + +This is the "limit on increment loops" option. This option takes a +number argument 'lim'. This option prevents runaway loops. For +example, if you accidentally specify, "FOR x (for-from 1) (for-to -1) +(for-by 1)", it will take a long time to finish. If you do have more +than 256 entries in tables, you will need to specify a new limit with +this option. + +timeout option (-t). +-------------------- + +This is the "limit server shell operations to 'seconds'" option. This +option takes a number argument 'SECONDS'. + +This option has some usage constraints. It: + * must be compiled in by defining 'SHELL_ENABLED' during the + compilation. + + AutoGen works with a shell server process. Most normal commands will +complete in less than 10 seconds. If, however, your commands need more +time than this, use this option. + + The valid range is 0 to 3600 seconds (1 hour). Zero will disable the +server time limit. + +trace option. +------------- + +This is the "tracing level of detail" option. This option takes a +keyword argument 'level'. + +This option has some usage constraints. It: + * This option takes a keyword as its argument. The argument sets an + enumeration value that can be tested by comparing the option value + macro (OPT_VALUE_TRACE). The available keywords are: + nothing debug-message server-shell + templates block-macros expressions + everything + + or their numeric equivalent. + + This option will cause AutoGen to display a trace of its template +processing. There are six levels, each level including messages from +the previous levels: + +'nothing' + Does no tracing at all (default) + +'debug-message' + Print messages from the "DEBUG" AutoGen macro (*note DEBUG::). + +'server-shell' + Traces all input and output to the server shell. This includes a + shell "independent" initialization script about 30 lines long. Its + output is discarded and not inserted into any template. + +'templates' + Traces the invocation of 'DEFINE'd macros and 'INCLUDE's + +'block-macros' + Traces all block macros. The above, plus 'IF', 'FOR', 'CASE' and + 'WHILE'. + +'expressions' + Displays the results of expression evaluations. + +'everything' + Displays the invocation of every AutoGen macro, even 'TEXT' macros + (i.e. the text outside of macro quotes). Additionally, if you + rebuild the "expr.ini" file with debugging enabled, then all calls + to AutoGen defined scheme functions will also get logged: + cd ${top_builddir}/agen5 + DEBUG_ENABLED=true bash bootstrap.dir expr.ini + make CFLAGS='-g -DDEBUG_ENABLED=1' + + Be aware that you cannot rebuild this source in this way without + first having installed the 'autogen' executable in your search + path. Because of this, "expr.ini" is in the distributed source + list, and not in the dependencies. + +trace-out option. +----------------- + +This is the "tracing output file or filter" option. This option takes a +string argument 'file'. The output specified may be a file name, a file +that is appended to, or, if the option argument begins with the 'pipe' +operator ('|'), a command that will receive the tracing output as +standard in. For example, '--traceout='| less'' will run the trace +output through the 'less' program. Appending to a file is specified by +preceding the file name with two greater-than characters ('>>'). + +show-defs option. +----------------- + +This is the "show the definition tree" option. + +This option has some usage constraints. It: + * must be compiled in by defining 'DEBUG_ENABLED' during the + compilation. + * may not be preset with environment variables or configuration + (rc/ini) files. + + This will print out the complete definition tree before processing +the template. + +used-defines option. +-------------------- + +This is the "show the definitions used" option. + +This option has some usage constraints. It: + * may not be preset with environment variables or configuration + (rc/ini) files. + + This will print out the names of definition values searched for +during the processing of the template, whether actually found or not. +There may be other referenced definitions in a template in portions of +the template not evaluated. Some of the names listed may be computed +names and others AutoGen macro arguments. This is not a means for +producing a definitive, all-encompassing list of all and only the values +used from a definition file. This is intended as an aid to template +documentation only. + +core option (-C). +----------------- + +This is the "leave a core dump on a failure exit" option. + +This option has some usage constraints. It: + * must be compiled in by defining 'HAVE_SYS_RESOURCE_H' during the + compilation. + + Many systems default to a zero sized core limit. If the system has +the sys/resource.h header and if this option is supplied, then in the +failure exit path, autogen will attempt to set the soft core limit to +whatever the hard core limit is. If that does not work, then an +administrator must raise the hard core size limit. + + +File: autogen.info, Node: autogen processing, Next: autogen dep-track, Prev: autogen debug-tpl, Up: autogen Invocation + +5.5 processing options +====================== + +These options can be used to control what gets processed in the +definitions files and template files. They specify which outputs and +parts of outputs to produce. + +skip-suffix option (-s). +------------------------ + +This is the "skip the file with this 'suffix'" option. This option +takes a string argument 'SUFFIX'. + +This option has some usage constraints. It: + * may appear an unlimited number of times. + * may not be preset with environment variables or configuration + (rc/ini) files. + * must not appear in combination with any of the following options: + select-suffix. + + Occasionally, it may not be desirable to produce all of the output +files specified in the template. (For example, only the '.h' header +file, but not the '.c' program text.) To do this specify +'--skip-suffix=c' on the command line. + +select-suffix option (-o). +-------------------------- + +This is the "specify this output suffix" option. This option takes a +string argument 'SUFFIX'. + +This option has some usage constraints. It: + * may appear an unlimited number of times. + * may not be preset with environment variables or configuration + (rc/ini) files. + + If you wish to override the suffix specifications in the template, +you can use one or more copies of this option. See the suffix +specification in the *note pseudo macro:: section of the info doc. + +define option (-D). +------------------- + +This is the "name to add to definition list" option. This option takes +a string argument 'value'. + +This option has some usage constraints. It: + * may appear an unlimited number of times. + + The AutoGen define names are used for the following purposes: + + 1. Sections of the AutoGen definitions may be enabled or disabled by + using C-style #ifdef and #ifndef directives. + 2. When defining a value for a name, you may specify the index for a + particular value. That index may be a literal value, a define + option or a value #define-d in the definitions themselves. + 3. The name of a file may be prefixed with '$NAME/'. The '$NAME' part + of the name string will be replaced with the define-d value for + 'NAME'. + 4. When AutoGen is finished loading the definitions, the defined + values are exported to the environment with, 'putenv(3)'. These + values can then be used in shell scripts with '${NAME}' references + and in templates with '(getenv "NAME")'. + 5. While processing a template, you may specify an index to retrieve a + specific value. That index may also be a define-d value. + + It is entirely equivalent to place this name in the exported +environment. Internally, that is what AutoGen actually does with this +option. + +undefine option (-U). +--------------------- + +This is the "definition list removal pattern" option. This option takes +a string argument 'name-pat'. + +This option has some usage constraints. It: + * may appear an unlimited number of times. + * may not be preset with environment variables or configuration + (rc/ini) files. + + Similar to 'C', AutoGen uses '#ifdef/#ifndef' preprocessing +directives. This option will cause the matching names to be removed +from the list of defined values. + + +File: autogen.info, Node: autogen dep-track, Next: autogen autoopts-opts, Prev: autogen processing, Up: autogen Invocation + +5.6 dep-track options +===================== + +This option is used to automate dependency tracking. + +make-dep option (-M). +--------------------- + +This is the "emit make dependency file" option. This option takes an +optional string argument 'type'. + +This option has some usage constraints. It: + * may appear an unlimited number of times. + * may not be preset with environment variables or configuration + (rc/ini) files. + + This option behaves fairly closely to the way the '-M' series of +options work with the gcc compiler, except that instead of just emitting +the predecessor dependencies, this also emits the successor dependencies +(output target files). By default, the output dependency information +will be placed in '<base-name>.d', but may also be specified with +'-MF<file>'. The time stamp on this file will be manipulated so that it +will be one second older than the oldest primary output file. + + The target in this dependency file will normally be the dependency +file name, but may also be overridden with '-MT<targ-name>'. AutoGen +will not alter the contents of that file, but it may create it and it +will adjust the modification time to match the start time. + + *NB:* these second letters are part of the option argument, so '-MF +<file>' must have the space character quoted or omitted, and '-M "F +<file>"' is acceptable because the 'F' is part of the option argument. + + '-M' may be followed by any of the letters M, F, P, T, Q, D, or G. +However, only F, Q, T and P are meaningful. All but F have somewhat +different meanings. '-MT<name>' is interpreted as meaning '<name>' is a +sentinel file that will depend on all inputs (templates and definition +files) and all the output files will depend on this sentinel file. It +is suitable for use as a real make target. Q is treated identically to +T, except dollar characters ('$') are doubled. P causes a special clean +(clobber) phoney rule to be inserted into the make file fragment. An +empty rule is always created for building the list of targets. + + This is the recommended usage: + -MFwhatever-you-like.dep -MTyour-sentinel-file -MP + and then in your 'Makefile', make the 'autogen' rule: + -include whatever-you-like.dep + clean_targets += clean-your-sentinel-file + + your-sentinel-file: + autogen -MT$@ -MF$*.d ..... + + local-clean : + rm -f $(clean_targets) + + The modification time on the dependency file is adjusted to be one +second before the earliest time stamp of any other output file. +Consequently, it is suitable for use as the sentinel file testifying to +the fact the program was successfully run. ('-include' is the GNU make +way of specifying "include it if it exists". Your make must support +that feature or your bootstrap process must create the file.) + + All of this may also be specified using the 'DEPENDENCIES_OUTPUT' or +'AUTOGEN_MAKE_DEP' environment variables. If defined, dependency +information will be output. If defined with white space free text that +is something other than 'true', 'false', 'yes', 'no', '0' or '1', then +the string is taken to be an output file name. If it contains a string +of white space characters, the first token is as above and the second +token is taken to be the target (sentinel) file as '-MT' in the +paragraphs above. 'DEPENDENCIES_OUTPUT' will be ignored if there are +multiple sequences of white space characters or if its contents are, +specifically, 'false', 'no' or '0'. + + +File: autogen.info, Node: autogen autoopts-opts, Next: autogen config, Prev: autogen dep-track, Up: autogen Invocation + +5.7 autoopts-opts options +========================= + +help, version, option and error handling. + +no-abort option. +---------------- + +This is the "do not abort on errors" option. By default, 'AutoGen' will +abort on an error leaving behind a core image. That is sometimes +inconvenient. If present on the command line or in the environment, +AutoGen will call 'exit(1)' instead of 'abort()'. + + +File: autogen.info, Node: autogen config, Next: autogen exit status, Prev: autogen autoopts-opts, Up: autogen Invocation + +5.8 presetting/configuring autogen +================================== + +Any option that is not marked as not presettable may be preset by +loading values from configuration ("rc" or "ini") files, and values from +environment variables named 'AUTOGEN' and 'AUTOGEN_<OPTION_NAME>'. +'<OPTION_NAME>' must be one of the options listed above in upper case +and segmented with underscores. The 'AUTOGEN' variable will be +tokenized and parsed like the command line. The remaining variables are +tested for existence and their values are treated like option arguments. + +'libopts' will search in 2 places for configuration files: + * $HOME + * $PWD + The environment variables 'HOME', and 'PWD' are expanded and replaced +when 'autogen' runs. For any of these that are plain files, they are +simply processed. For any that are directories, then a file named +'.autogenrc' is searched for within that directory and processed. + + Configuration files may be in a wide variety of formats. The basic +format is an option name followed by a value (argument) on the same +line. Values may be separated from the option name with a colon, equal +sign or simply white space. Values may be continued across multiple +lines by escaping the newline with a backslash. + + Multiple programs may also share the same initialization file. +Common options are collected at the top, followed by program specific +segments. The segments are separated by lines like: + [AUTOGEN] +or by + <?program autogen> +Do not mix these styles within one configuration file. + + Compound values and carefully constructed string values may also be +specified using XML syntax: + <option-name> + <sub-opt>...<...>...</sub-opt> + </option-name> +yielding an 'option-name.sub-opt' string value of + "...<...>..." + 'AutoOpts' does not track suboptions. You simply note that it is a +hierarchicly valued option. 'AutoOpts' does provide a means for +searching the associated name/value pair list (see: optionFindValue). + + The command line options relating to configuration and/or usage help +are: + +version (-v) +------------ + +Print the program version to standard out, optionally with licensing +information, then exit 0. The optional argument specifies how much +licensing detail to provide. The default is to print just the version. +The licensing information may be selected with an option argument. Only +the first letter of the argument is examined: + +'version' + Only print the version. This is the default. +'copyright' + Name the copyright usage licensing terms. +'verbose' + Print the full copyright usage licensing terms. + +usage (-u) +---------- + +Print abbreviated usage to standard out, then exit 0. + +reset-option (-R) +----------------- + +Resets the specified option to the compiled-in initial state. This will +undo anything that may have been set by configuration files. The option +argument may be either the option flag character or its long name. + + +File: autogen.info, Node: autogen exit status, Next: autogen Examples, Prev: autogen config, Up: autogen Invocation + +5.9 autogen exit status +======================= + +One of the following exit values will be returned: +'0 (EXIT_SUCCESS)' + Successful program execution. +'1 (EXIT_OPTION_ERROR)' + The command options were misconfigured. +'2 (EXIT_BAD_TEMPLATE)' + An error was encountered processing the template. +'3 (EXIT_BAD_DEFINITIONS)' + The definitions could not be deciphered. +'4 (EXIT_LOAD_ERROR)' + An error was encountered during the load phase. +'5 (EXIT_FS_ERROR)' + a file system error stopped the program. +'6 (EXIT_NO_MEM)' + Insufficient memory to operate. +'128 (EXIT_SIGNAL)' + 'autogen' exited due to catching a signal. If your template + includes string formatting, a number argument to a "%s" formatting + element will trigger a segmentation fault. Autogen will catch the + seg fault signal and exit with 'AUTOGEN_EXIT_SIGNAL(5)'. + Alternatively, AutoGen may have been interrupted with a 'kill(2)' + signal. + + Subtract 128 from the actual exit code to detect the signal number. +'66 (EX_NOINPUT)' + A specified configuration file could not be loaded. +'70 (EX_SOFTWARE)' + libopts had an internal operational error. Please report it to + autogen-users@lists.sourceforge.net. Thank you. + + +File: autogen.info, Node: autogen Examples, Prev: autogen exit status, Up: autogen Invocation + +5.10 autogen Examples +===================== + +Here is how the man page is produced: + autogen -Tagman-cmd.tpl -MFman-dep -MTstamp-man opts.def + + This command produced this man page from the AutoGen option +definition file. It overrides the template specified in 'opts.def' +(normally 'options.tpl') and uses 'agman-cmd.tpl'. It also sets the +make file dependency output to 'man-dep' and the sentinel file (time +stamp file) to 'man-stamp'. The base of the file name is derived from +the defined 'prog-name'. + + The texi invocation document is produced via: + autogen -Tagtexi-cmd.tpl -MFtexi-dep -MTtexi-stamp opts.def + + +File: autogen.info, Node: Installation, Next: AutoOpts, Prev: autogen Invocation, Up: Top + +6 Configuring and Installing +**************************** + +* Menu: + +* configuring:: Configuring AutoGen +* AutoGen CGI:: AutoGen as a CGI server +* signal names:: Signal Names +* installing:: Installing AutoGen + + +File: autogen.info, Node: configuring, Next: AutoGen CGI, Up: Installation + +6.1 Configuring AutoGen +======================= + +AutoGen is configured and built using Libtool, Automake and Autoconf. +Consequently, you can install it wherever you wish using the '--prefix' +and other options. To the various configuration options supplied by +these tools, AutoGen adds a few of its own: + +'--disable-shell' + AutoGen is now capable of acting as a CGI forms server, *Note + AutoGen CGI::. As such, it will gather its definitions using + either 'GET' or 'POST' methods. All you need to do is have a + template named 'cgi.tpl' handy or specify a different one with a + command line option. + + However, doing this without disabling the server shell brings + considerable risk. If you were to pass user input to a script that + contained, say, the classic "'`rm -rf /`'", you might have a + problem. This configuration option will cause shell template + commands to simply return the command string as the result. No + mistakes. Much safer. Strongly recommended. The default is to + have server shell scripting enabled. + + Disabling the shell will have some build side effects, too. + + * Many of the make check tests will fail, since they assume a + working server shell. + * The getdefs and columns programs are not built. The options + are distributed as definition files and they cannot be + expanded with a shell-disabled AutoGen. + * Similarly, the documentation cannot be regenerated because the + documentation templates depend on subshell functionality. + +'--enable-debug' + Turning on AutoGen debugging enables very detailed inspection of + the input definitions and monitoring shell script processing. + These options are not particularly useful to anyone not directly + involved in maintaining AutoGen. If you do choose to enable + AutoGen debugging, be aware that the usage page was generated + without these options, so when the build process reaches the + documentation rebuild, there will be a failure. 'cd' into the + 'agen5' build directory, 'make' the 'autogen.texi' file and all + will be well thereafter. + +'--with-regex-header' +'--with-header-path' +'--with-regex-lib' + These three work together to specify how to compile with and link + to a particular POSIX regular expression library. The value for + '--with-regex-header=value' must be the name of the relevant header + file. The AutoGen sources will attempt to include that source with + a '#include <value>' C preprocessing statement. The PATH from the + '--with-header-path=path' will be added to 'CPPFLAGS' as '-Ipath'. + The LIB-SPECS from '--with-regex-lib=lib-specs' will be added to + 'LDFLAGS' without any adornment. + + +File: autogen.info, Node: AutoGen CGI, Next: signal names, Prev: configuring, Up: Installation + +6.2 AutoGen as a CGI server +=========================== + +AutoGen is now capable of acting as a CGI forms server. It behaves as a +CGI server if the definitions input is from stdin and the environment +variable 'REQUEST_METHOD' is defined and set to either "GET" or "POST". +If set to anything else, AutoGen will exit with a failure message. When +set to one of those values, the CGI data will be converted to AutoGen +definitions (*note Definitions File::) and the template named +"'cgi.tpl'" will be processed. + + This works by including the name of the real template to process in +the form data and having the "'cgi.tpl'" template include that template +for processing. I do this for processing the form +<http://autogen.sourceforge.net/conftest.html>. The "'cgi.tpl'" looks +approximately like this: + + <? AutoGen5 Template ?> + <? + IF (not (exist? "template")) ?><? + form-error ?><? + + ELIF (=* (get "template") "/") ?><? + form-error ?><? + + ELIF (define tpl-file (string-append "cgi-tpl/" + (get "template"))) + (access? tpl-file R_OK) ?><? + INCLUDE (. tpl-file) ?><? + + ELIF (set! tpl-file (string-append tpl-file ".tpl")) + (access? tpl-file R_OK) ?><? + INCLUDE (. tpl-file) ?><? + + ELSE ?><? + form-error ?><? + ENDIF ?> + +This forces the template to be found in the "'cgi-tpl/'" directory. +Note also that there is no suffix specified in the pseudo macro (*note +pseudo macro::). That tells AutoGen to emit the output to 'stdout'. + + The output is actually spooled until it is complete so that, in the +case of an error, the output can be discarded and a proper error message +can be written in its stead. + + *Please also note* that it is advisable, _especially_ for network +accessible machines, to configure AutoGen (*note configuring::) with +shell processing disabled ('--disable-shell'). That will make it +impossible for any referenced template to hand data to a subshell for +interpretation. + + +File: autogen.info, Node: signal names, Next: installing, Prev: AutoGen CGI, Up: Installation + +6.3 Signal Names +================ + +When AutoGen is first built, it tries to use 'psignal(3)', +'sys_siglist', 'strsigno(3)' and 'strsignal(3)' from the host operating +system. If your system does not supply these, the AutoGen distribution +will. However, it will use the distributed mapping and this mapping is +unlikely to match what your system uses. This can be fixed. Once you +have installed autogen, the mapping can be rebuilt on the host operating +system. To do so, you must perform the following steps: + + 1. Build and install AutoGen in a place where it will be found in your + search path. + 2. 'cd ${top_srcdir}/compat' + 3. 'autogen strsignal.def' + 4. Verify the results by examining the 'strsignal.h' file produced. + 5. Re-build and re-install AutoGen. + + If you have any problems or peculiarities that cause this process to +fail on your platform, please send me copies of the header files +containing the signal names and numbers, along with the full path names +of these files. I will endeavor to fix it. There is a shell script +inside of 'strsignal.def' that tries to hunt down the information. + + +File: autogen.info, Node: installing, Prev: signal names, Up: Installation + +6.4 Installing AutoGen +====================== + +There are several files that get installed. The number depend whether +or not both shared and archive libraries are to be installed. The +following assumes that everything is installed relative to '$prefix'. +You can, of course, use 'configure' to place these files where you wish. + + *NB* AutoGen does not contain any compiled-in path names. All +support directories are located via option processing, the environment +variable 'HOME' or finding the directory where the executable came from. + + The installed files are: + + 1. The executables in 'bin' (autogen, getdefs and columns). + + 2. The AutoOpts link libraries as 'lib/libopts.*'. + + 3. An include file in 'include/options.h', needed for Automated Option + Processing (see next chapter). + + 4. Several template files and a scheme script in 'share/autogen', + needed for Automated Option Processing (*note AutoOpts::), parsing + definitions written with scheme syntax (*note Dynamic Text::), the + templates for producing documentation for your program (*note + documentation attributes::), autoconf test macros, and AutoFSM. + + 5. Info-style help files as 'info/autogen.info*'. These files + document AutoGen, the option processing library AutoOpts, and + several add-on components. + + 6. The three man pages for the three executables are installed in + man/man1. + + This program, library and supporting files can be installed with +three commands: + + * <src-dir>/configure [ <configure-options> ] + * make + * make install + + However, you may wish to insert 'make check' before the 'make +install' command. + + If you do perform a 'make check' and there are any failures, you will +find the results in '<module>/test/FAILURES'. Needless to say, I would +be interested in seeing the contents of those files and any associated +messages. If you choose to go on and analyze one of these failures, you +will need to invoke the test scripts individually. You may do so by +specifying the test (or list of test) in the TESTS make variable, thus: + + gmake TESTS=test-name.test check + + I specify 'gmake' because most makes will not let you override +internal definitions with command line arguments. 'gmake' does. + + All of the AutoGen tests are written to honor the contents of the +VERBOSE environment variable. Normally, any commentary generated during +a test run is discarded unless the VERBOSE environment variable is set. +So, to see what is happening during the test, you might invoke the +following with bash or ksh: + + VERBOSE=1 gmake TESTS="for.test forcomma.test" check + +Or equivalently with csh: + + env VERBOSE=1 gmake TESTS="for.test forcomma.test" check + + +File: autogen.info, Node: AutoOpts, Next: Add-Ons, Prev: Installation, Up: Top + +7 Automated Option Processing +***************************** + +AutoOpts 42.1 is bundled with AutoGen. It is a tool that virtually +eliminates the hassle of processing options and keeping man pages, info +docs and usage text up to date. This package allows you to specify +several program attributes, thousands of option types and many option +attributes. From this, it then produces all the code necessary to parse +and handle the command line and configuration file options, and the +documentation that should go with your program as well. + + All the features notwithstanding, some applications simply have +well-established command line interfaces. Even still, those programs +may use the configuration file parsing portion of the library. See the +"AutoOpts Features" and "Configuration File Format" sections. + +* Menu: + +* Features:: AutoOpts Features +* Licensing:: AutoOpts Licensing +* Caveats:: Developer and User Notes +* Quick Start:: Quick Start +* Option Definitions:: Option Definitions +* AutoOpts API:: Programmatic Interface +* Multi-Threading:: Multi-Threading +* option descriptor:: Option Descriptor File +* Using AutoOpts:: Using AutoOpts +* Presetting Options:: Configuring your program +* Config File Format:: Configuration File Format +* shell options:: AutoOpts for Shell Scripts +* AutoInfo:: Automated Info Docs +* AutoMan pages:: Automated Man Pages +* getopt_long:: Using getopt(3C) +* i18n:: Internationalizing AutoOpts +* Naming Conflicts:: Naming Conflicts +* All Attribute Names:: All Attribute Names +* Option Define Names:: Option Definition Name Index + + +File: autogen.info, Node: Features, Next: Licensing, Up: AutoOpts + +7.1 AutoOpts Features +===================== + +AutoOpts supports option processing; option state saving; and program +documentation with innumerable features. Here, we list a few obvious +ones and some important ones, but the full list is really defined by all +the attributes defined in the *note Option Definitions:: section. + + 1. POSIX-compliant short (flag) option processing. + + 2. GNU-style long options processing. Long options are recognized + without case sensitivity, and they may be abbreviated. + + 3. Environment variable initializations, *Note environrc::. + + 4. Initialization from configuration files (aka RC or INI files), and + saving the option state back into one, *Note loading rcfile::. + + 5. Config files may be partitioned. One config file may be used by + several programs by partitioning it with lines containing, + '[PROGRAM_NAME]' or '<?program-name>', *Note loading rcfile::. + + 6. Config files may contain AutoOpts directives. '<?auto-options + [[option-text]]>' may be used to set 'AutoOpts' option processing + options. Viz., GNU usage layout versus 'AutoOpts' conventional + layout, and 'misuse-usage' versus 'no-misuse-usage', *Note usage + attributes::. + + 7. Options may be marked as 'dis-abled' with a disablement prefix. + Such options may default to either an enabled or a disabled state. + You may also provide an enablement prefix, too, e.g., + '--allow-mumble' and '--prevent-mumble' (*note Common + Attributes::). + + 8. Verify that required options are present between the minimum and + maximum number of times on the command line. Verify that + conflicting options do not appear together. Verify that options + requiring the presence of other options are, in fact, used in the + presence of other options. See *Note Common Attributes::, and + *Note Option Conflict Attributes::. + + 9. There are several *note automatically supported options: automatic + options. They will have short flags if any options have option + flags and the flags are not suppressed. The associated flag may be + altered or suppressed by specifying no value or an alternate + character for 'xxx-value;' in the option definition file. 'xxx' is + the name of the option below: + + '--help' + '--more-help' + These are always available. '--more-help' will pass the full + usage text through a pager. + '--usage' + This is added to the option list if 'usage-opt' is specified. + It yields the abbreviated usage to 'stdout'. + '--version' + This is added to the option list if 'version = xxx;' is + specified. + '--load-opts' + '--save-opts' + These are added to the option list if 'homerc' is specified. + Mostly. If, 'disable-save' is specified, then '--save-opts' + is disabled. + + 10. Various forms of main procedures can be added to the output, *Note + Generated main::. There are four basic forms: + + a. A program that processes the arguments and writes to standard + out portable shell commands containing the digested options. + + b. A program that will generate portable shell commands to parse + the defined options. The expectation is that this result will + be copied into a shell script and used there. + + c. A 'for-each' main that will invoke a named function once for + either each non-option argument on the command line or, if + there are none, then once for each non-blank, non-comment + input line read from stdin. + + d. A main procedure of your own design. Its code can be supplied + in the option description template or by incorporating another + template. + + 11. There are several methods for handling option arguments. + * nothing (*note OPT_ARG::) option argument strings are globally + available. + * user supplied (*note Option Argument Handling::) + * stack option arguments (*note Option Argument Handling::) + * integer numbers (*note arg-type number::) + * true or false valued (*note arg-type boolean::) + * enumerated list of names (*note arg-type keyword::) + * an enumeration (membership) set (*note arg-type set + membership::) + * a list of name/value pairs (option 'subopts') (*note arg-type + hierarchy::) + * a time duration or a specific time and date + * validated file name (*note arg-type file name::) + * optional option argument (*note arg-optional::) + + 12. The generated usage text can be emitted in either AutoOpts + standard format (maximizing the information about each option), or + GNU-ish normal form. The default form is selected by either + specifying or not specifying the 'gnu-usage' attribute (*note + information attributes::). This can be overridden by the user + himself with the 'AUTOOPTS_USAGE' environment variable. If it + exists and is set to the string 'gnu', it will force GNU-ish style + format; if it is set to the string 'autoopts', it will force + AutoOpts standard format; otherwise, it will have no effect. + + 13. The usage text and many other strings are stored in a single + character array (*note string table functions: SCM + string-table-new.). This reduces fixup costs when loading the + program or library. The downside is that if GCC detects that any + of these strings are used in a printf format, you may get the + warning, 'embedded '\0' in format'. To eliminate the warning, you + must provide GCC with the '-Wno-format-contains-nul' option. + + 14. If you compile with 'ENABLE_NLS' defined and '_()' defined to a + localization function (e.g. 'gettext(3GNU)'), then the option + processing code will be localizable (*note i18n::). Provided also + that you do not define the 'no-xlate' attribute to _anything_ + (*note presentation attributes::). + + You should also ensure that the 'ATTRIBUTE_FORMAT_ARG()' gets + '#define'-ed to something useful. There is an autoconf macro named + 'AG_COMPILE_FORMAT_ARG' in 'ag_macros.m4' that will set it + appropriately for you. If you do not do this, then translated + formatting strings may trigger GCC compiler warnings. + + 15. Provides a callable routine to parse a text string as if it were + from one of the rc/ini/config files, hereafter referred to as a + configuration file. + + 16. By adding a 'doc' and 'arg-name' attributes to each option, + AutoGen will also be able to produce a man page and the 'invoking' + section of a texinfo document. + + 17. Intermingled option processing. AutoOpts options may be + intermingled with command line operands and options processed with + other parsing techniques. This is accomplished by setting the + 'allow-errors' (*note program attributes::) attribute. When + processing reaches a point where 'optionProcess' (*note + libopts-optionProcess::) needs to be called again, the current + option can be set with 'RESTART_OPT(n)' (*note RESTART_OPT::) + before calling 'optionProcess'. + + See: *Note library attributes::. + + 18. Library suppliers can specify command line options that their + client programs will accept. They specify option definitions that + get '#include'-d into the client option definitions and they + specify an "anchor" option that has a callback and must be invoked. + That will give the library access to the option state for their + options. + + 19. library options. An AutoOpt-ed library may export its options for + use in an AutoOpt-ed program. This is done by providing an option + definition file that client programs '#include' into their own + option definitions. See "AutoOpt-ed Library for AutoOpt-ed + Program" (*note lib and program::) for more details. + + +File: autogen.info, Node: Licensing, Next: Caveats, Prev: Features, Up: AutoOpts + +7.2 AutoOpts Licensing +====================== + +When AutoGen is installed, the AutoOpts project is installed with it. +AutoOpts includes various AutoGen templates and a pair of shared +libraries. These libraries may be used under the terms of version 3 of +the GNU Lesser General Public License (LGPL). + + One of these libraries ('libopts') is needed by programs that are +built using AutoOpts generated code. This library is available as a +separate "tear-off" source tarball. It is redistributable for use under +either of two licenses: The above mentioned GNU Lesser General Public +License, and the advertising-clause-free BSD license. Both of these +license terms are incorporated into appropriate COPYING files included +with the 'libopts' source tarball. This source may be incorporated into +your package with the following simple commands: + + rm -rf libopts libopts-* + gunzip -c `autoopts-config libsrc` | \ + tar -xvf - + mv libopts-*.*.* libopts + + View the 'libopts/README' file for further integration information. + + +File: autogen.info, Node: Caveats, Next: Quick Start, Prev: Licensing, Up: AutoOpts + +7.3 Developer and User Notes +============================ + +The formatting of the usage message can be controlled with the use of +the 'AUTOOPTS_USAGE' environment variable. If it contains any of five +possible comma separated values, it will affect 'libopts' behavior. Any +extraneous or conflicting data will cause its value to be ignored. + + If the program attributes 'long-usage' and 'short-usage' have been +specified (*note Usage and Version Info Display: usage attributes.), +these strings are used for displaying full usage and abbreviated usage. +"Full usage" is used when usage is requested, "abbreviated usage" when a +usage error is detected. If these strings are not provided, the usage +text is computed. + + The 'AUTOOPTS_USAGE' environment variable may be set to the comma +and/or white space separated list of the following strings: + +'compute' + Ignore the provision of 'long-usage' and 'short-usage' attributes, + and compute the usage strings. This is useful, for example, if you + wish to regenerate the basic form of these strings and either tweak + them or translate them. The methods used to compute the usage text + are not suitable for translation. + +'gnu' + The format of the usage text will be displayed in GNU-normal form. + The default display for '--version' will be to include a note on + licensing terms. + +'autoopts' + The format of the extended usage will be in AutoOpts' native + layout. The default version display will be one line of text with + the last token the version. 'gnu' and 'autoopts' conflict and may + not be used together. + +'no-misuse-usage' + When an option error is made on the command line, the abbreviated + usage text will be suppressed. An error message and the method for + getting full usage information will be displayed. + +'misuse-usage' + When an option error is made on the command line, the abbreviated + usage text will be shown. 'misuse-usage' and 'no-misuse-usage' + conflict and may not be used together. + + 'misuse-usage' and 'autoopts' are the defaults. These defaults may +be flipped to 'no-misuse-usage' and 'gnu' by specifying 'gnu-usage' and +'no-misuse-usage' program attributes, respectively, in the option +definition file. + +Note for developers: + + The templates used to implement AutoOpts depend heavily upon token +pasting. That mens that if you name an option, 'debug', for example, +the generated header will expect to be able to emit '#define' macros +such as this: + #define DESC(n) (autogenOptions.pOptDesc[INDEX_OPT_## n]) + and expect 'DESC(DEBUG)' to expand correctly into +'(autogenOptions.pOptDesc[INDEX_OPT_DEBUG])'. If 'DEBUG' is '#defined' +to something else, then that something else will be in the above +expansion. + + If you discover you are having strange problems like this, you may +wish to use some variation of the 'guard-option-names' *Note program +attributes::. + + +File: autogen.info, Node: Quick Start, Next: Option Definitions, Prev: Caveats, Up: AutoOpts + +7.4 Quick Start +=============== + +Since it is generally easier to start with a simple example than it is +to look at the options that AutoGen uses itself, here is a very simple +AutoOpts example. You can copy this example out of the Info file and +into a source file to try it. You can then embellish it into what you +really need. For more extensive examples, you can also examine the help +output and option definitions for the commands 'columns', 'getdefs' and +'autogen' itself. + + If you are looking for a more extensive example, you may search the +autogen sources for files named '*opts.def'. 'xml2ag' is ridiculous and +'autogen' is very lengthy, but 'columns' and 'getdefs' are not too +difficult. The 'sharutils' sources are fairly reasonable, too. + +* Menu: + +* quick ao problem:: Example option requirements +* quick ao def:: Example option definitions +* quick ao build:: Build the example options +* quick ao help:: Example option help text +* quick ao usage:: Using the example options +* quick ao docs:: Example option documentation + + +File: autogen.info, Node: quick ao problem, Next: quick ao def, Up: Quick Start + +7.4.1 Example option requirements +--------------------------------- + +For our simple example, assume you have a program named 'check' that +takes two options: + + 1. A list of directories to check over for whatever it is 'check' + does. You want this option available as a POSIX-style flag option + and a GNU long option. You want to allow as many of these as the + user wishes. + 2. An option to show or not show the definition tree being used. Only + one occurrence is to be allowed, specifying one or the other. + + +File: autogen.info, Node: quick ao def, Next: quick ao build, Prev: quick ao problem, Up: Quick Start + +7.4.2 Example option definitions +-------------------------------- + +First, specify your program attributes and its options to AutoOpts, as +with the following example. + + AutoGen Definitions options; + prog-name = check; + prog-title = "Checkout Automated Options"; + long-opts; + gnu-usage; /* GNU style preferred to default */ + + main = { main-type = shell-process; }; + + flag = { + name = check-dirs; + value = L; /* flag style option character */ + arg-type = string; /* option argument indication */ + max = NOLIMIT; /* occurrence limit (none) */ + stack-arg; /* save opt args in a stack */ + descrip = "Checkout directory list"; + doc = 'name of each directory that is to be "checked out".'; + }; + + flag = { + name = show_defs; + descrip = "Show the definition tree"; + disable = dont; /* mark as enable/disable type */ + /* option. Disable as `dont-' */ + doc = 'disable, if you do not want to see the tree.'; + }; + + +File: autogen.info, Node: quick ao build, Next: quick ao help, Prev: quick ao def, Up: Quick Start + +7.4.3 Build the example options +------------------------------- + +This program will produce a program that digests its options and writes +the values as shell script code to stdout. Run the following short +script to produce this program: + base=check + BASE=`echo $base | tr '[a-z-]' '[A-Z_]'` + cflags="-DTEST_${BASE} `autoopts-config cflags`" + ldflags="`autoopts-config ldflags`" + autogen ${base}.def + cc -o ${base} -g ${cflags} ${base}.c ${ldflags} + ./${base} --help + + +File: autogen.info, Node: quick ao help, Next: quick ao usage, Prev: quick ao build, Up: Quick Start + +7.4.4 Example option help text +------------------------------ + +Running the build commands yields: + + + exit 0 + + +File: autogen.info, Node: quick ao usage, Next: quick ao docs, Prev: quick ao help, Up: Quick Start + +7.4.5 Using the example options +------------------------------- + +Normally, however, you would not use the 'main' clause. Instead, the +file would be named something like 'checkopt.def', you would compile +'checkopt.c' the usual way, and link the object with the rest of your +program. + + The options are processed by calling 'optionProcess' (*note +libopts-optionProcess::): + + main( int argc, char** argv ) + { + { + int optct = optionProcess( &checkOptions, argc, argv ); + argc -= optct; + argv += optct; + } + + The options are tested and used as in the following fragment. +'ENABLED_OPT' is used instead of 'HAVE_OPT' for the '--show-defs' option +because it is an enabled/disabled option type: + + if ( ENABLED_OPT( SHOW_DEFS ) + && HAVE_OPT( CHECK_DIRS )) { + int dirct = STACKCT_OPT( CHECK_DIRS ); + char** dirs = STACKLST_OPT( CHECK_DIRS ); + while (dirct-- > 0) { + char* dir = *dirs++; + ... + + +File: autogen.info, Node: quick ao docs, Prev: quick ao usage, Up: Quick Start + +7.4.6 Example option documentation +---------------------------------- + +The 'doc' clauses are used in the flag stanzas for man pages and texinfo +invoking documentation. With the definition file described above, the +two following commands will produce the two documentation files +'check.1' and 'invoke-check.texi'. The latter file will be generated as +a chapter, rather than a section or subsection. + + autogen -Tagman-cmd check.def + autogen -DLEVEL=chapter -Tagtexi-cmd -binvoke-check.texi check.def + +The result of which is left as an exercise for the reader. + + A lot of magic happens to make this happen. The rest of this chapter +will describe the myriad of option attributes supported by AutoOpts. +However, keep in mind that, in general, you won't need much more than +what was described in this "quick start" section. + + +File: autogen.info, Node: Option Definitions, Next: AutoOpts API, Prev: Quick Start, Up: AutoOpts + +7.5 Option Definitions +====================== + +AutoOpts uses an AutoGen definitions file for the definitions of the +program options and overall configuration attributes. The complete list +of program and option attributes is quite extensive, so if you are +reading to understand how to use AutoOpts, I recommend reading the +"Quick Start" section (*note Quick Start::) and paying attention to the +following: + + 1. 'prog-name', 'prog-title', and 'argument', program attributes, + *Note program attributes::. + 2. 'name' and 'descrip' option attributes, *Note Required + Attributes::. + 3. 'value' (flag character) and 'min' (occurrence counts) option + attributes, *Note Common Attributes::. + 4. 'arg-type' from the option argument specification section, *Note + Option Arguments::. + 5. Read the overall how to, *Note Using AutoOpts::. + 6. Highly recommended, but not required, are the several "man" and + "info" documentation attributes, *Note documentation attributes::. + + Keep in mind that the majority are rarely used and can be safely +ignored. However, when you have special option processing requirements, +the flexibility is there. + +* Menu: + +* program attributes:: Program Description Attributes +* library attributes:: Options for Library Code +* information attributes:: Program Information Attributes +* Generated main:: Generating main procedures +* option attributes:: Option Attributes +* Option Arguments:: Option Argument Specification +* Option Argument Handling:: Option Argument Handling +* Internationalizing Options:: Internationalizing Options +* documentation attributes:: Man and Info doc Attributes +* automatic options:: Automatically Supported Options +* standard options:: Library of Standard Options + + +File: autogen.info, Node: program attributes, Next: library attributes, Up: Option Definitions + +7.5.1 Program Description Attributes +------------------------------------ + +The following global definitions are used to define attributes of the +entire program. These generally alter the configuration or global +behavior of the AutoOpts option parser. The first two are required of +every program. The third is required if there are to be any left over +arguments (operands) after option processing. The rest have been +grouped below. Except as noted, there may be only one copy of each of +these definitions: + +'prog-name' + This attribute is required. Variable names derived from this name + are derived using 'string->c_name!' (*note SCM string->c-name!::). + +'prog-title' + This attribute is required and may be any descriptive text. + +'argument' + This attribute is required if your program uses operand arguments. + It specifies the syntax of the arguments that *follow* the options. + It may not be empty, but if it is not supplied, then option + processing must consume all the arguments. If it is supplied and + starts with an open bracket ('['), then there is no requirement on + the presence or absence of command line arguments following the + options. Lastly, if it is supplied and does not start with an open + bracket, then option processing must *not* consume all of the + command line arguments. + +'config-header' + If your build has a configuration header, it must be included + before anything else. Specifying the configuration header file + name with this attribute will cause that to happen. + +* Menu: + +* usage attributes:: Usage and Version Info Display +* config attributes:: Program Configuration +* programming attributes:: Programming Details +* presentation attributes:: User Presentation Attributes + + +File: autogen.info, Node: usage attributes, Next: config attributes, Up: program attributes + +7.5.1.1 Usage and Version Info Display +...................................... + +These will affect the way usage is seen and whether or not version +information gets displayed. + +'full-usage' + If this attribute is provided, it may specify the full length usage + text, or a variable name assignable to a 'char const *' pointer, or + it may be empty. The meanings are determined by the length. + * If not provided, the text will be computed as normal. + * If the length is zero, then the usage text will be derived + from the current settings and inserted as text into the + generated .c file. + * If the length is 1 to 32 bytes, then it is presumed to be a + variable name that either points to or is an array of const + chars. + * If it is longer than that, it is presumed to be the help text + itself. This text will be inserted into the generated .c + file. + + This string should be readily translatable. Provision will be made + to translate it if this is provided, if the source code is compiled + with 'ENABLE_NLS' defined, and 'no-xlate' has not been set to the + value _anything_. The untranslated text will be handed to + 'dgettext("libopts", txt)' and then 'gettext(txt)' for translation, + one paragraph at a time. + + To facilitate the creation and maintenance of this text, you can + force the string to be ignored and recomputed by specifying + AUTOOPTS_USAGE=compute + in the environment and requesting help or usage information. See + *Note Developer and User Notes: Caveats. + +'short-usage' + If this attribute is provided, it is used to specify an abbreviated + version of the usage text. This text is constructed in the same + way as the 'full-usage', described above. + +'gnu-usage' + AutoOpts normaly displays usage text in a format that provides more + information than the standard GNU layout, but that also means it is + not the standard GNU layout. This attribute changes the default to + GNU layout, with the 'AUTOOPTS_USAGE' environment variable used to + request 'autoopts' layout. See *Note Developer and User Notes: + Caveats. + +'usage-opt' + I apologize for too many confusing usages of usage. This attribute + specifies that '--usage' and/or '-u' be supported. The help + (usage) text displayed will be abbreviated when compared to the + default help text. + +'no-misuse-usage' + When there is a command line syntax error, by default AutoOpts will + display the abbreviated usage text, rather than just a one line + "you goofed it, ask for usage" message. You can change the default + behavior for your program by supplying this attribute. The user + may override this choice, again, with the 'AUTOOPTS_USAGE' + environment variable. See *Note Developer and User Notes: Caveats. + +'prog-group' + The version text in the 'getopt.tpl' template will include this + text in parentheses after the program name, when this attribute is + specified. For example: + mumble (stumble) 1.0 + says that the 'mumble' program is version 1.0 and is part of the + 'stumble' group of programs. + +'usage' + If your program has some cleanup work that must be done before + exiting on usage mode issues, or if you have to customize the usage + message in some way, specify this procedure and it will be called + instead of the default 'optionUsage()' function. For example, if a + program is using the curses library and needs to invoke the usage + display, then you must arrange to call 'endwin()' before invoking + the library function 'optionUsage()'. This can be handled by + specifying your own usage function, thus: + void + my_usage(tOptions * opts, int ex) + { + if (curses_window_active) + endwin(); + optionUsage(opts, ex); + } + +'version' + Specifies the program version and activates the VERSION option, + *Note automatic options::. + + +File: autogen.info, Node: config attributes, Next: programming attributes, Prev: usage attributes, Up: program attributes + +7.5.1.2 Program Configuration +............................. + +Programs may be "pre-configured" before normal command line options are +processed (See *note Immediate Action Attributes: Immediate Action.). +How configuration files and environment variables are handled get +specified with these attributes. + +'disable-load' +'disable-save' + Indicates that the command line usage of '--load-opts' and/or + '--save-opts' are disallowed. + +'environrc' + Indicates looking in the environment for values of variables named, + 'PROGRAM_OPTNAME' or 'PROGRAM', where 'PROGRAM' is the upper cased + C-NAME of the program and 'OPTNAME' is the upper cased C-NAME of a + specific option. The contents of the 'PROGRAM' variable, if found, + are tokenized and processed. The contents of 'PROGRAM_OPTNAME' + environment variables are taken as the option argument to the + option nameed '--optname'. + +'homerc' + Specifies that option settings may be loaded from and stored into + configuration files. Each instance of this attribute is either a + directory or a file using a specific path, a path based on an + environment variable or a path relative to installation + directories. The method used depends on the name. If the one + entry is empty, it enables the loading and storing of settings, but + no specific files are searched for. Otherwise, a series of + configuration files are hunted down and, if found, loaded. + + If the first character of the 'homerc' value is not the dollar + character ('$'), then it is presumed to be a path name based on the + current directory. Otherwise, the method depends on the second + character: + + '$' + The path is relative to the directory where the executable was + found. + '@' + The path is relative to the package data directory, e.g. + '/usr/local/share/autogen'. + '[a-zA-Z]' + The path is derived from the named environment variable. + + Use as many as you like. The presence of this attribute activates + the '--save-opts' and '--load-opts' options. However, saving into + a file may be disabled with the 'disable-save'. *Note loading + rcfile::. See the 'optionMakePath(3AGEN)' man page for + excruciating details. + +'rcfile' + Specifies the configuration file name. This is only useful if you + have provided at least one 'homerc' attribute. + default: .<prog-name>rc + +'vendor-opt' + This option implements the '-W' vendor option command line option. + + For POSIX specified utilities, the options are constrained to the + options that are specified by POSIX. Extensions should be handled + with '-W' command line options, the short flag form. Long option + name processing must be disabled. In fact, the 'long-opts' + attribute must not be provided, and some options must be specified + without flag values. + + The '-W long-name' is processed by looking up the long option name + that follows it. It cannot be a short flag because that would + conflict with the POSIX flag name space. It will be processed as + if long options were accepted and '--long-name' were found on the + command line. + + +File: autogen.info, Node: programming attributes, Next: presentation attributes, Prev: config attributes, Up: program attributes + +7.5.1.3 Programming Details +........................... + +These attributes affect some of the ways that the option data are used +and made available to the program. + +'config-header' + The contents of this attribute should be just the name of the + configuration file. A "#include" naming this file will be inserted + at the top of the generated header. + +'exit-name' +'exit-desc' + These values should be defined as indexed values, thus: + exit-name[0] = success; + exit-desc[0] = 'Successful program execution.'; + exit-name[1] = failure; + exit-desc[1] = 'The operation failed or command syntax was not valid.'; + By default, all programs have these effectively defined for them. + They may be overridden by explicitly defining any or all of these + values. Additional names and descriptions may be defined. They + will cause an enumeration to be emitted, like this one for + 'getdefs': + typedef enum { + GETDEFS_EXIT_SUCCESS = 0, + GETDEFS_EXIT_FAILURE = 1 + } getdefs_exit_code_t; + which will be augmented by any 'exit-name' definitions beyond '1'. + + Some of the generated code will exit non-zero if there is an + allocation error. This exit will always be code '1', unless there + is an exit named 'no_mem' or 'nomem'. In that case, that value + will be used. Additionally, if there is such a value, and if + 'die-code' is specified, then a function 'nomem_err(size_t len, + char const * what)' will be emitted as an inline function for + reporting out-of-memory conditions. + +'usage-message' + This attribute will cause two procedures to be added to the code + file: 'usage_message()' and 'vusage_message()', with any applicable + prefix (see 'prefix', below). They are declared in the generated + header, thus: + noreturn extern void vusage_message(char const * fmt, va_list ap); + noreturn extern void usage_message(char const * fmt, ...); + These functions print the message to 'stderr' and invoke the usage + function with the exit code set to '1' ('EXIT_FAILURE'). + +'die-code' + This tells AutoOpts templates to emit code for 'vdie()', 'die()', + 'fserr()', and, possibly the 'nomem_err()' functions. The latter + is emitted if an exit name of 'no-mem' or 'nomem' is specified. If + the 'die-code' is assigned a text value, then that code will be + inserted in the 'vdie' function immediately before it prints the + death rattle message. + + The profiles for these functions are: + noreturn extern void vdie( int exit_code, char const * fmt, va_list); + noreturn extern void die( int exit_code, char const * fmt, ...); + noreturn extern void fserr(int exit_code, char const * op, char const * fname); + noreturn static inline void + nomem_err(size_t sz, char const * what) {...} + +'export' + This string is inserted into the .h interface file. Generally used + for global variables or '#include' directives required by + 'flag-code' text and shared with other program text. Do not + specify your configuration header ('config.h') in this attribute or + the 'include' attribute. Instead, use 'config-header', above. + +'guard-option-names' + AutoOpts generates macros that presume that there are no 'cpp' + macros with the same name as the option name. For example, if you + have an option named, '--debug', then you must not use '#ifdef + DEBUG' in your code. If you specify this attribute, every option + name will be guarded. If the name is '#define'-d, then a warning + will be issued and the name undefined. If you do not specify this + and there is a conflict, you will get strange error messages. + + This attribute may be set to any of four recognized states: + + * Not defined. AutoOpts will behave as described above. + + * Defined, but set to the empty string. Text will be emitted + into the header to undefine ('#undef') any conflicting + preprocessor macros. The code will include compiler warnings + (via '#warning'). Some compilers are not ANSI-C-99 compliant + yet and will error out on those warnings. You may compile + with '-DNO_OPTION_NAME_WARNINGS' to silence or mostly silence + them. + + * Defined and set to the string, 'no-warning'. All of the + needed '#undef's will be emitted, without any conflict + checking '#warning' directives emitted. + + * Defined and set to the string, 'full-enum'. The option + manipulation preprocessor macros will not token paste the + option names to the index enumeration prefix. e.g. you will + need to use 'HAVE_OPT(INDEX_OPT_DEBUG)' instead of + 'HAVE_OPT(DEBUG)'. + +'include' + This string is inserted into the .c file. Generally used for + global variables required only by 'flag-code' program text. + +'no-libopts' + If you are going to handle your option processing with the + 'getopt.tpl' template instead of using libopts, then specify this + attribute. It will suppress mention of '--more-help' in the + generated documentation. ('getopt_long' does not support + '--more-help'.) + +'prefix' + This value is inserted into *all* global names. This will + disambiguate them if more than one set of options are to be + compiled into a single program. + + +File: autogen.info, Node: presentation attributes, Prev: programming attributes, Up: program attributes + +7.5.1.4 User Presentation Attributes +.................................... + +Attributes that affect the user's experience. + +'allow-errors' + The presence of this attribute indicates ignoring any command line + option errors. This may also be turned on and off by invoking the + macros 'ERRSKIP_OPTERR' and 'ERRSTOP_OPTERR' from the generated + interface file. + +'long-opts' + Presence indicates GNU-standard long option processing. Partial + name matches are accepted, if they are at least two characters long + and the partial match is unique. The matching is not case + sensitive, and the underscore, hyphen and carat characters are all + equivalent (they match). + + If any options do not have an option value (flag character) + specified, and least one does specify such a value, then you must + specify 'long-opts'. If none of your options specify an option + value (flag character) and you do not specify 'long-opts', then + command line arguments are processed in "named option mode". This + means that: + + * Every command line argument must be a long option. + * The flag markers '-' and '--' are completely optional. + * The 'argument' program attribute is disallowed. + * One of the options may be specified as the default (as long as + it has a required option argument). + +'no-xlate' + Modifies when or whether option names get translated. If provided, + it must be assigned one of these values: + 'opt-cfg' + to suppress option name translation for configuration file and + and environment variable processing. + 'opt' + to suppress option name translation completely. The usage + text will always be translated if 'ENABLE_NLS' is defined and + you have translations for that text. + 'anything' + Specifies disabling all internationalization support for + option code, completely. + See also the various 'XLAT' interface entries in the AutoOpts + Programmatic Interface section (*note AutoOpts API::). + +'reorder-args' + Normally, POSIX compliant commands do not allow for options to be + interleaved with operands. If this is necessary for historical + reasons, there are two approaches available: + * Allow 'optionProcess' to return the index of the operand like + it normally does and process the operand(s). When an operand + is encountered that starts with a hyphen, then set the + AutoOpts current index with the 'RESTART_OPT' macro (see *note + RESTART_OPT::), and re-invoke 'optionProcess'. This will also + allow you to process the operands in context. + + * Specify this attribute. AutoOpts will re-order the command + arguments so that the operands appear (in the original order) + at the end of the argument list. Differing configuration + state is not possible to detect after all options have been + processed. + +'resettable' + Specifies that the '--reset-option' command line option is to be + supported. This makes it possible to suppress any setting that + might be found in a configuration file or environment variable. + + +File: autogen.info, Node: library attributes, Next: information attributes, Prev: program attributes, Up: Option Definitions + +7.5.2 Options for Library Code +------------------------------ + +Some libraries provide their own code for processing command line +options, and this may be used by programs that utilize AutoOpts. You +may also wish to write a library that gets configured with AutoOpts +options and config files. Such a library may either supply its own +configury routine and process its own options, or it may export its +option descriptions to programs that also use AutoOpts. This section +will describe how to do all of these different things. + +* Menu: + +* lib and program:: AutoOpt-ed Library for AutoOpt-ed Program +* lib called:: AutoOpt-ed Library for Regular Program +* prog calls lib:: AutoOpt-ed Program Calls Regular Library + + +File: autogen.info, Node: lib and program, Next: lib called, Up: library attributes + +7.5.2.1 AutoOpt-ed Library for AutoOpt-ed Program +................................................. + +The library source code must provide an option definition file that +consists of only the attribute 'library' and 'flag' entries. The +'library' attribute does not need any associated value, so it will +generally appeary by itself on a line folowed by a semi-colon. The +first 'flag' entry must contain the following attributes: + +'name' + This name is used in the construction of a global pointer of type + 'tOptDesc const*'. It is always required. +'documentation' + It tells 'AutoOpts' that this option serves no normal purpose. It + will be used to add usage clarity and to locate option descriptors + in the library code. +'descrip' + This is a string that is inserted in the extended usage display + before the options specific to the current library. It is always + required. +'lib-name' + This should match the name of the library. This string is also + used in the construction of the option descriptor pointer name. In + the end, it looks like this: + extern tOptDesc const* <<lib-name>>_<<name>>_optDesc_p; + and is used in the macros generated for the library's '.h' file. + + In order to compile this 'AutoOpts' using library, you must create a +special header that is not used by the client program. This is +accomplished by creating an option definition file that contains +essentially exactly the following: + + AutoGen definitions options; + prog-name = does-not-matter; // but is always required + prog-title = 'also does not matter'; // also required + config-header = 'config.h'; // optional, but common + library; + #include library-options-only.def + +and nothing else. AutoGen will produce only the '.h' file. You may now +compile your library, referencing just this '.h' file. The macros it +creates will utilize a global variable that will be defined by the +'AutoOpts'-using client program. That program will need to have the +following '#include' in its option definition file: + + #include library-options-only.def + +All the right things will magically happen so that the global variables +named <<LIB-NAME>>_<<NAME>>_OPTDESC_P are initialized correctly. For an +example, please see the 'AutoOpts' test script: +'autoopts/test/library.test'. + + +File: autogen.info, Node: lib called, Next: prog calls lib, Prev: lib and program, Up: library attributes + +7.5.2.2 AutoOpt-ed Library for Regular Program +.............................................. + +In this case, your library must provide an option processing function to +a calling program. This is accomplished by setting the 'allow-errors' +global option attribute. Each time your option handling function is +called, you must determine where your scan is to resume and tell the +AutoOpts library by invoking: + + RESTART_OPT(next_arg_index); + +and then invoke 'not_opt_index = optionProcess(...)'. The +'not_opt_index' value can be used to set 'optind', if that is the global +being used to scan the program argument array. + + In this method, do *NOT* utilize the global 'library' attribute. +Your library must specify its options as if it were a complete program. +You may choose to specify an alternate 'usage()' function so that usage +for other parts of the option interface may be displayed as well. See +"Program Information Attributes" (*note information attributes::). + + At the moment, there is no method for calling 'optionUsage()' telling +it to produce just the information about the options and not the program +as a whole. Some later revision after somebody asks. + + +File: autogen.info, Node: prog calls lib, Prev: lib called, Up: library attributes + +7.5.2.3 AutoOpt-ed Program Calls Regular Library +................................................ + +As with providing an 'AutoOpt'-ed library to a non-'AutoOpt'-ed program, +you must write the option description file as if you were writing all +the options for the program, but you should specify the 'allow-errors' +global option attribute and you will likely want an alternate 'usage()' +function (see "Program Information Attributes" *note information +attributes::). In this case, though, when 'optionProcess()' returns, +you need to test to see if there might be library options. If there +might be, then call the library's exported routine for handling command +line options, set the next-option-to-process with the 'RESTART_OPT()' +macro, and recall 'optionProcess()'. Repeat until done. + + +File: autogen.info, Node: information attributes, Next: Generated main, Prev: library attributes, Up: Option Definitions + +7.5.3 Program Information Attributes +------------------------------------ + +These attributes are used to define how and what information is +displayed to the user of the program. + +'copyright' + The 'copyright' is a structured value containing three to five + values. If 'copyright' is used, then the first three are required. + + 1. 'date' - the list of applicable dates for the copyright. + 2. 'owner' - the name of the copyright holder. + 3. 'type' - specifies the type of distribution license. + AutoOpts/AutoGen supports the text of the GNU Public License + ('gpl'), the GNU Lesser General Public License with Library + extensions ('lgpl'), the Modified Free BSD license ('mbsd') + and a few others. Other licenses may be specified, but you + must provide your own license file. The list of license files + provided by AutoOpts may be seen by typing: + ls $(autoopts-config pkgdatadir)/*.lic + 4. 'text' - the text of the copyright notice. This must be + provided if 'type' is set to 'NOTE'. + 5. 'author' - in case the author name is to appear in the + documentation and is different from the copyright owner. + 6. 'eaddr' - email address for receiving praises and complaints. + Typically that of the author or copyright holder. + + An example of this might be: + copyright = { + date = "1992-2015"; + owner = "Bruce Korb"; + eaddr = 'bkorb@gnu.org'; + type = GPL; + }; + +'detail' + This string is added to the usage output when the HELP option is + selected. + +'explain' + Gives additional information whenever the usage routine is invoked. + +'package' + The name of the package the program belongs to. This will appear + parenthetically after the program name in the version and usage + output, e.g.: 'autogen (GNU autogen) - The Automated Program + Generator'. + +'preserve-case' + This attribute will not change anything except appearance. + Normally, the option names are all documented in lower case. + However, if you specify this attribute, then they will display in + the case used in their specification. Command line options will + still be matched without case sensitivity. This is useful for + specifying option names in camel-case. + +'prog-desc *and*' +'opts-ptr' + These define global pointer variables that point to the program + descriptor and the first option descriptor for a library option. + This is intended for use by certain libraries that need command + line and/or initialization file option processing. These + definitions have no effect on the option template output, but are + used for creating a library interface file. Normally, the first + "option" for a library will be a documentation option that cannot + be specified on the command line, but is marked as 'settable'. The + library client program will invoke the 'SET_OPTION' macro which + will invoke a handler function that will finally set these global + variables. + +'usage' + Optionally names the usage procedure, if the library routine + 'optionUsage()' does not work for you. If you specify 'my_usage' + as the value of this attribute, for example, you will use a + procedure by that name for displaying usage. Of course, you will + need to provide that procedure and it must conform to this profile: + void my_usage( tOptions* pOptions, int exitCode ) + +'gnu-usage' + Normally, the default format produced by the 'optionUsage' + procedure is AutoOpts Standard. By specifying this attribute, the + default format will be GNU-ish style. Either default may be + overridden by the user with the 'AUTOOPTS_USAGE' environment + variable. If it is set to 'gnu' or 'autoopts', it will alter the + style appropriately. This attribute will conflict with the 'usage' + attribute. + +'reorder-args' + Some applications traditionally require that the command operands + be intermixed with the command options. In order to handle that, + the arguments must be reordered. If you are writing such an + application, specify this global option. All of the options (and + any associated option arguments) will be brought to the beginning + of the argument list. New applications should not use this + feature, if at all possible. This feature is disabled if + 'POSIXLY_CORRECT' is defined in the environment. + + +File: autogen.info, Node: Generated main, Next: option attributes, Prev: information attributes, Up: Option Definitions + +7.5.4 Generating main procedures +-------------------------------- + +When AutoOpts generates the code to parse the command line options, it +has the ability to produce any of several types of 'main()' procedures. +This is done by specifying a global structured value for 'main'. The +values that it contains are dependent on the value set for the one value +it must have: 'main-type'. + + The recognized values for 'main-type' are 'guile', 'shell-process', +'shell-parser', 'main', 'include', 'invoke', and 'for-each'. + +* Menu: + +* main guile:: guile: main and inner_main procedures +* main shell-process:: shell-process: emit Bourne shell results +* main shell-parser:: shell-parser: emit Bourne shell script +* main main:: main: user supplied main procedure +* main include:: include: code emitted from included template +* main invoke:: invoke: code emitted from AutoGen macro + +The 'for-each' main procedure has a number of attributes that +must be specified: + +* main for-each:: for-each: perform function on each operand +* main-for-each-proc:: procedure to handle each argument +* main-for-each-type:: handler procedure type +* main-for-each-code:: code for handler procedure +* main-for-each-opts:: for-each main procedure options + + +File: autogen.info, Node: main guile, Next: main shell-process, Up: Generated main + +7.5.4.1 guile: main and inner_main procedures +............................................. + +When the 'main-type' is specified to be 'guile', a 'main()' procedure is +generated that calls 'gh_enter()', providing it with a generated +'inner_main()' to invoke. If you must perform certain tasks before +calling 'gh_enter()', you may specify such code in the value for the +'before-guile-boot' attribute. + + The 'inner_main()' procedure itself will process the command line +arguments (by calling 'optionProcess()', *note libopts-optionProcess::), +and then either invoke the code specified with the 'guile-main' +attribute, or else export the parsed options to Guile symbols and invoke +the 'scm_shell()' function from the Guile library. This latter will +render the program nearly identical to the stock 'guile(1)' program. + + +File: autogen.info, Node: main shell-process, Next: main shell-parser, Prev: main guile, Up: Generated main + +7.5.4.2 shell-process: emit Bourne shell results +................................................ + +This will produce a 'main()' procedure that parses the command line +options and emits to 'stdout' Bourne shell commands that puts the option +state into environment variables. This can be used within a shell +script as follows: + + unset OPTION_CT + eval "`opt_parser \"$@\"`" + test ${OPTION_CT} -gt 0 && shift ${OPTION_CT} + + If the option parsing code detects an error or a request for usage or +version, it will emit a command to exit with an appropriate exit code to +'stdout'. This form of 'main' will cause all messages, including +requested usage and version information, to be emitted to 'stderr'. +Otherwise, a numeric value for 'OPTION_CT' is guaranteed to be emitted, +along with assignments for all the options parsed, something along the +lines of the following will be written to 'stdout' for evaluation: + + OPTION_CT=4 + export OPTION_CT + MYPROG_SECOND='first' + export MYPROG_SECOND + MYPROG_ANOTHER=1 # 0x1 + export MYPROG_ANOTHER + +If the arguments are to be reordered, however, then the resulting set of +operands will be emitted and 'OPTION_CT' will be set to zero. For +example, the following would be appended to the above: + + set -- 'operand1' 'operand2' 'operand3' + OPTION_CT=0 + +'OPTION_CT' is set to zero since it is not necessary to shift off any +options. + + +File: autogen.info, Node: main shell-parser, Next: main main, Prev: main shell-process, Up: Generated main + +7.5.4.3 shell-parser: emit Bourne shell script +.............................................. + +This will produce a 'main()' procedure that emits a shell script that +will parse the command line options. That script can be emitted to +'stdout' or inserted or substituted into a pre-existing shell script +file. Improbable markers are used to identify previously inserted +parsing text: + + # # # # # # # # # # -- do not modify this marker -- + +The program is also pretty insistent upon starting its parsing script on +the second line. + + +File: autogen.info, Node: main main, Next: main include, Prev: main shell-parser, Up: Generated main + +7.5.4.4 main: user supplied main procedure +.......................................... + +You must supply a value for the 'main-text' attribute. You may also +supply a value for 'option-code'. If you do, then the 'optionProcess' +invocation will not be emitted into the code. AutoOpts will wrap the +'main-text' inside of: + + int + main( int argc, char** argv ) + { + int res = <<success-exit-code>>; + { // replaced by option-code, if that exists + int ct = optionProcess( &<<prog-name>>Options, argc, argv); + argc -= ct; + argv += ct; + } + <<main-text>> + return res; + } + +so you can most conveniently set the value with a 'here string' (*note +here-string::): + + code = <<- _EndOfMainProc_ + <<your text goes here>> + _EndOfMainProc_; + + +File: autogen.info, Node: main include, Next: main invoke, Prev: main main, Up: Generated main + +7.5.4.5 include: code emitted from included template +.................................................... + +You must write a template to produce your main procedure. You specify +the name of the template with the 'tpl' attribute and it will be +incorporated at the point where AutoOpts is ready to emit the 'main()' +procedure. + + This can be very useful if, in your working environment, you have +many programs with highly similar 'main()' procedures. All you need to +do is parameterize the variations and specify which variant is needed +within the 'main' AutoOpts specification. Since you are coding the +template for this, the attributes needed for this variation would be +dictated by your template. + + Here is an example of an 'include' variation: + + main = { + main-type = include; + tpl = "main-template.tpl"; + }; + + +File: autogen.info, Node: main invoke, Next: main for-each, Prev: main include, Up: Generated main + +7.5.4.6 invoke: code emitted from AutoGen macro +............................................... + +You must write a template to produce your main procedure. That template +must contain a definition for the function specified with the 'func' +attribute to this 'main()' procedure specification. This variation +operates in much the same way as 'include' (*note main include::) +method. + + +File: autogen.info, Node: main for-each, Next: main-for-each-proc, Prev: main invoke, Up: Generated main + +7.5.4.7 for-each: perform function on each operand +.................................................. + +This produces a main procedure that invokes a procedure once for each +operand on the command line (non-option arguments), *OR* once for each +non-blank, non-comment 'stdin' input line. Leading and trailing white +space is trimmed from the input line and comment lines are lines that +are empty or begin with a comment character, defaulting to a hash ('#') +character. + + *NB*: The 'argument' program attribute (*note program attributes::) +must begin with the '[' character, to indicate that there are command +operands, but that they are optional. + +For an example of the produced main procedure, in the 'autoopts/test' +build directory, type the following command and look at 'main.c': + make verbose TESTS=main.test + + +File: autogen.info, Node: main-for-each-proc, Next: main-for-each-type, Prev: main for-each, Up: Generated main + +procedure to handle each argument +................................. + +The 'handler-proc' attribute is required. It is used to name the +procedure to call. That procedure is presumed to be external, but if +you provide the code for it, then the procedure is emitted as a static +procedure in the generated code. + + This procedure should return 0 on success, a cumulative error code on +warning and exit without returning on an unrecoverable error. As the +cumulative warning codes are or-ed together, the codes should be some +sort of bit mask in order to be ultimately decipherable (if you need to +do that). + + If the called procedure needs to cause a fail-exit, it is expected to +call 'exit(3)' directly. If you want to cause a warning exit code, then +this handler function should return a non-zero status. That value will +be *OR*-ed into a result integer for computing the final exit code. +E.g., here is part of the emitted code: + + int res = 0; + if (argc > 0) { + do { + res |= MY_HANDLER( *(argv++) ); + } while (--argc > 0); + } else { ... + + +File: autogen.info, Node: main-for-each-type, Next: main-for-each-code, Prev: main-for-each-proc, Up: Generated main + +handler procedure type +...................... + +If you do not supply the 'handler-type' attribute, your handler +procedure must be the default type. The profile of the procedure must +be: + + int MY_HANDLER(char const * pz_entry); + +However, if you do supply this attribute, you may set the value to any +of four alternate flavors: + +'name-of-file' + This is essentially the same as the default handler type, except + that before your procedure is invoked, the generated code has + verified that the string names an existing file. The profile is + unchanged. + +'file-X' + Before calling your procedure, the file is f-opened according to + the 'X', where 'X' may be any of the legal modes for 'fopen(3C)'. + In this case, the profile for your procedure must be: + + int MY_HANDLER(char const * pz_fname, FILE * entry_fp); + + When processing inputs as file pointer stream files, there are + several ways of treating standard input. It may be an ordinary + input file, or it may contain a list of files to operate on. + + If the file handler type is more specifically set to 'file-r' and a + command line operand consists of a single hyphen, then MY_HANDLER + will be called with 'entry_fp' set to 'stdin' and the 'pz_fname' + set to the translatable string, "standard input". Consequently, in + this case, if the input list is being read from 'stdin', a line + containing a hyphen by itself will be ignored. + +'stdin-input' + This attribute specifies that standard input is a data input file. + By default, 'for-each' main procedures will read standard input for + operands if no operands appear on the command line. If there are + operands after the command line options, then standard input is + typically ignored. It can always be processed as an input data + file, however, if a single bare hyphen is put on the command line. + +'text-of-file' +'some-text-of-file' + Before calling your procedure, the contents of the file are read or + mapped into memory. (Excessively large files may cause problems.) + The 'some-text-of-file' disallows empty files. Both require + regular files. In this case, the profile for your procedure must + be: + + program_exit_code_t + MY_HANDLER(char const * fname, char * file_text, + size_t text_size); + + Note that though the 'file_text' is not 'const', any changes made + to it are not written back to the original file. It is merely a + memory image of the file contents. Also, the memory allocated to + hold the text is 'text_size + 1' bytes long and the final byte is + always 'NUL'. The file contents need not be text, as the data are + read with the 'read(2)' system call. + + 'file_text' is automatically freed, unless you specify a + 'handler-frees' attribute. Then your code must 'free(3)' the text. + + If you select one of these file type handlers, then on access or +usage errors the 'PROGRAM_EXIT_FAILURE' exit code will, by default, be +or-ed into the final exit code. This can be changed by specifying the +global 'file-fail-code' attribute and naming a different value. That +is, something other than 'failure'. You may choose 'success', in which +case file access issues will not affect the exit code and the error +message will not be printed. + + +File: autogen.info, Node: main-for-each-code, Next: main-for-each-opts, Prev: main-for-each-type, Up: Generated main + +code for handler procedure +.......................... + +With the 'MYHANDLER-code' attribute, you provide the code for your +handler procedure in the option definition file. Note that the spelling +of this attribute depends on the name provided with the 'handler-proc' +attribute, so we represent it here with 'MYHANDLER' as a place holder. +As an example, your 'main()' procedure specification might look +something like this: + + main = { + main-type = for-each; + handler-proc = MYHANDLER; + MYHANDLER-code = <<- EndOfMyCode + /* whatever you want to do */ + EndOfMyCode; + }; + +and instead of an emitted external reference, a procedure will be +emitted that looks like this: + + static int + MYHANDLER( char const* pz_entry ) + { + int res = 0; + <<MYHANDLER-code goes here>> + return res; + } + + +File: autogen.info, Node: main-for-each-opts, Prev: main-for-each-code, Up: Generated main + +for-each main procedure options +............................... + +These attributes affect the main procedure and how it processes each +argument or input line. + +'interleaved' + If this attribute is specified, then options and operands may be + interleaved. Arguments or input lines beginning with a hyphen will + cause it to be passed through to an option processing function and + will take effect for the remainder of the operands (or input lines) + processed. + +'main-init' + This is code that gets inserted after the options have been + processed, but before the handler procs get invoked. + +'main-fini' + This is code that gets inserted after all the entries have been + processed, just before returning from 'main()'. + +'comment-char' + When reading operands from standard input, if you wish comment + lines to start with a character other than a hash ('#') character, + then specify one character with this attribute. If string value is + empty, then only blank lines will be considered comments. + + +File: autogen.info, Node: option attributes, Next: Option Arguments, Prev: Generated main, Up: Option Definitions + +7.5.5 Option Attributes +----------------------- + +For each option you wish to specify, you must have a block macro named +'flag' defined. There are two required attributes: 'name' and +'descrip'. If any options do not have a 'value' (traditional flag +character) attribute, then the 'long-opts' program attribute must also +be defined. As a special exception, if no options have a 'value' *and* +'long-opts' is not defined *and* 'argument' is not defined, then all +arguments to the program are named options. In this case, the '-' and +'--' command line option markers are optional. + +* Menu: + +* Required Attributes:: Required Attributes +* Common Attributes:: Common Option Attributes +* Immediate Action:: Immediate Action Attributes +* Option Conflict Attributes:: Option Conflict Attributes + +These option attributes do not fit well with the above categories. + +* opt-attr settable:: Program may set option +* opt-attr no-preset:: Option cannot be pre-configured +* opt-attr equivalence:: Option Equivalence Class +* opt-attr aliases:: Option Aliasing +* opt-attr default option:: Default Option +* opt-attr documentation:: Option Sectioning Comment +* opt-attr translators:: Translator Notes + + +File: autogen.info, Node: Required Attributes, Next: Common Attributes, Up: option attributes + +7.5.5.1 Required Attributes +........................... + +Every option must have exactly one copy of both of these attributes. + +'name' + Long name for the option. Even if you are not accepting long + options and are only accepting flags, it must be provided. + AutoOpts generates private, named storage that requires this name. + This name also causes a '#define'-d name to be emitted. It must + not conflict with any other names you may be using in your program. + + For example, if your option name is, 'debug' or 'munged-up', you + must not use the '#define' names 'DEBUG' (or 'MUNGED_UP') in your + program for non-AutoOpts related purposes. They are now used by + AutoOpts. + + Sometimes (most especially under Windows), you may get a surprise. + For example, 'INTERFACE' is apparently a user space name that one + should be free to use. Windows usurps this name. To solve this, + you must do one of the following: + + 1. Change the name of your option + 2. add the program attribute (*note program attributes::): + + export = '#undef INTERFACE'; + 3. add the program attribute: + + guard-option-names; + +'descrip' + Except for documentation options, a *very* brief description of the + option. About 40 characters on one line, maximum, not counting any + texinfo markups. Texinfo markups are stripped before printing in + the usage text. It appears on the 'usage()' output next to the + option name. + + If, however, the option is a documentation option, it will appear + on one or more lines by itself. It is thus used to visually + separate and comment upon groups of options in the usage text. + diff --git a/doc/autogen.info-2 b/doc/autogen.info-2 new file mode 100644 index 0000000..cf68422 --- /dev/null +++ b/doc/autogen.info-2 @@ -0,0 +1,7358 @@ +This is autogen.info, produced by makeinfo version 6.5 from +autogen.texi. + +This manual is for GNU AutoGen version 5.18, updated August 2018. + + Copyright (C) 1992-2018 by Bruce Korb. + + Permission is granted to copy, distribute and/or modify this + document under the terms of the GNU Free Documentation License, + Version 1.2 or any later version published by the Free Software + Foundation; with no Invariant Sections, no Front-Cover Texts, and + no Back-Cover Texts. +INFO-DIR-SECTION GNU programming tools +START-INFO-DIR-ENTRY +* AutoGen: (autogen). The Automated Program Generator +END-INFO-DIR-ENTRY + + This file documents GNU AutoGen Version 5.18. + + AutoGen copyright (C) 1992-2018 Bruce Korb AutoOpts copyright (C) +1992-2018 Bruce Korb snprintfv copyright (C) 1999-2000 Gary V. Vaughan + + AutoGen is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation, either version 3 of the License, or (at your +option) any later version. + + AutoGen is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +Public License for more details. + + You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. + + +File: autogen.info, Node: Common Attributes, Next: Immediate Action, Prev: Required Attributes, Up: option attributes + +7.5.5.2 Common Option Attributes +................................ + +These option attributes are optional. Any that do appear in the +definition of a flag, may appear only once. + +'value' + The flag character to specify for traditional option flags, e.g., + '-L'. + +'max' + Maximum occurrence count (invalid if DISABLE present). The default + maximum is 1. 'NOLIMIT' can be used for the value, otherwise it + must be a number or a '#define' that evaluates to a number. + +'min' + Minimum occurrence count. If present, then the option *must* + appear on the command line. Do not define it with the value zero + (0). + +'must-set' + If an option must be specified, but it need not be specified on the + command line, then specify this attribute for the option. + +'deprecated' + There are two effects to this attribute: the usage text will not + show the option, and the generated documentation will mark it with: + _NOTE: THIS OPTION IS DEPRECATED_. + +'disable' + Prefix for disabling (inverting sense of) the option. Only useful + if long option names are being processed. When an option has this + attribute, the test 'ENABLED_OPT(OPTNAME)' is false when either of + the following is true: + * The option has not been specified and the 'enable' attribute + has not been specified. + * The option has been specified with this disabling prefix. + To detect that the option has been specified with the disabling + prefix, you must use: + HAVE_OPT(OPTNAME) && ! ENABLED_OPT(OPTNAME) + +'enable' + Long-name prefix for enabling the option (invalid if DISABLE *not* + present). Only useful if long option names are being processed. + +'enabled' + If default is for option being enabled. (Otherwise, the + OPTST_DISABLED bit is set at compile time.) Only useful if the + option can be disabled. + +'ifdef' +'ifndef' +'omitted-usage' + If an option is relevant on certain platforms or when certain + features are enabled or disabled, you can specify the compile time + flag used to indicate when the option should be compiled in or out. + For example, if you have a configurable feature, 'mumble' that is + indicated with the compile time define, 'WITH_MUMBLING', then add: + + ifdef = WITH_MUMBLING; + + Take care when using these. There are several caveats: + + * The case and spelling must match whatever is specified. + * Do not confuse these attributes with the AutoGen directives of + the same names, *Note Directives::. These cause C + preprocessing directives to be inserted into the generated C + text. + * Only one of 'ifdef' and 'ifndef' may apply to any one option. + * The 'VALUE_OPT_' values are '#define'-d. If 'WITH_MUMBLING' + is not defined, then the associated 'VALUE_OPT_' value will + not be '#define'-d either. So, if you have an option named, + 'MUMBLING' that is active only if 'WITH_MUMBLING' is + '#define'-d, then 'VALUE_OPT_MUMBLING' will be '#define'-d iff + 'WITH_MUMBLING' is '#define'-d. Watch those switch + statements. + * If you specify 'omitted-usage', then the option will be + recognized as disabled when it is configured out of the build, + but will yield the message, "This option has been disabled." + You may specify an alternate message by giving 'omitted-usage' + a string value. e.g.: + omitted-usage = 'you cannot do this'; + +'no-command' + This option specifies that the option is not allowed on the command + line. Such an option may not take a 'value' (flag character) + attribute. The program must have the 'homerc' (*note program + attributes::) option set. + + +File: autogen.info, Node: Immediate Action, Next: Option Conflict Attributes, Prev: Common Attributes, Up: option attributes + +7.5.5.3 Immediate Action Attributes +................................... + +Certain options may need to be processed early. For example, in order +to suppress the processing of configuration files, it is necessary to +process the command line option '--no-load-opts' *before* the config +files are processed. To accommodate this, certain options may have +their enabled or disabled forms marked for immediate processing. The +consequence of this is that they are processed ahead of all other +options in the reverse of normal order. + + Normally, the first options processed are the options specified in +the first 'homerc' file, followed by then next 'homerc' file through to +the end of config file processing. Next, environment variables are +processed and finally, the command line options. The later options +override settings processed earlier. That actually gives them higher +priority. Command line immediate action options actually have the +lowest priority of all. They would be used only if they are to have an +effect on the processing of subsequent options. + +'immediate' + Use this option attribute to specify that the enabled form of the + option is to be processed immediately. The 'help' and 'more-help' + options are so specified. They will also call 'exit()' upon + completion, so they *do* have an effect on the processing of the + remaining options :-). + +'immed-disable' + Use this option attribute to specify that the disabled form of the + option is to be processed immediately. The 'load-opts' option is + so specified. The '--no-load-opts' command line option will + suppress the processing of config files and environment variables. + Contrariwise, the '--load-opts' command line option is processed + normally. That means that the options specified in that file will + be processed after all the 'homerc' files and, in fact, after + options that precede it on the command line. + +'also' + If either the 'immediate' or the 'immed-disable' attributes are set + to the string, 'also', then the option will actually be processed + twice: first at the immediate processing phase and again at the + normal time. + + +File: autogen.info, Node: Option Conflict Attributes, Next: opt-attr settable, Prev: Immediate Action, Up: option attributes + +7.5.5.4 Option Conflict Attributes +.................................. + +These attributes may be used as many times as you need. They are used +at the end of the option processing to verify that the context within +which each option is found does not conflict with the presence or +absence of other options. + + This is not a complete cover of all possible conflicts and +requirements, but it simple to implement and covers the more common +situations. + +'flags-must' + one entry for every option that *must* be present when this option + is present + +'flags-cant' + one entry for every option that *cannot* be present when this + option is present + + +File: autogen.info, Node: opt-attr settable, Next: opt-attr no-preset, Prev: Option Conflict Attributes, Up: option attributes + +7.5.5.5 Program may set option +.............................. + +If the option can be set outside of option processing, specify +'settable'. If this attribute is defined, special macros for setting +this particular option will be inserted into the interface file. For +example, 'TEMPL_DIRS' is a settable option for AutoGen, so a macro named +'SET_OPT_TEMPL_DIRS(a)' appears in the interface file. This attribute +interacts with the DOCUMENTATION attribute. + + +File: autogen.info, Node: opt-attr no-preset, Next: opt-attr equivalence, Prev: opt-attr settable, Up: option attributes + +7.5.5.6 Option cannot be pre-configured +....................................... + +If presetting this option is not allowed, specify 'no-preset'. (Thus, +environment variables and values set in configuration files will be +ignored.) + + +File: autogen.info, Node: opt-attr equivalence, Next: opt-attr aliases, Prev: opt-attr no-preset, Up: option attributes + +7.5.5.7 Option Equivalence Class +................................ + +Generally, when several options are mutually exclusive and basically +serve the purpose of selecting one of several processing modes, specify +the 'equivalence' attribute. These options will be considered an +equivalence class. Sometimes, it is just easier to deal with them as +such. All members of the equivalence class must contain the same +equivalenced-to option, including the equivalenced-to option itself. +Thus, it must be a class member. + + For an option equivalence class, there is a single occurrence counter +for the class. It can be referenced with the interface macro, +'COUNT_OPT(BASE_OPTION)', where BASE_OPTION is the equivalenced-to +option name. + + Also, please take careful note: since the options are mapped to the +equivalenced-to option descriptor, any option argument values are mapped +to that descriptor also. Be sure you know which "equivalent option" was +selected before getting an option argument value! + + During the presetting phase of option processing (*note Presetting +Options::), equivalenced options may be specified. However, if +different equivalenced members are specified, only the last instance +will be recognized and the others will be discarded. A conflict error +is indicated only when multiple different members appear on the command +line itself. + + As an example of where equivalenced options might be useful, +'cpio(1)' has three options '-o', '-i', and '-p' that define the +operational mode of the program ('create', 'extract' and 'pass-through', +respectively). They form an equivalence class from which one and only +one member must appear on the command line. If 'cpio' were an +AutoOpt-ed program, then each of these option definitions would contain: + + equivalence = create; + + and the program would be able to determine the operating mode with +code that worked something like this: + + switch (WHICH_IDX_CREATE) { + case INDEX_OPT_CREATE: ... + case INDEX_OPT_EXTRACT: ... + case INDEX_OPT_PASS_THROUGH: ... + default: /* cannot happen */ + } + + +File: autogen.info, Node: opt-attr aliases, Next: opt-attr default option, Prev: opt-attr equivalence, Up: option attributes + +7.5.5.8 Option Aliasing +....................... + +Sometimes, for backwards compatibility or tradition or just plain +convenience, it works better to define one option as a pure alias for +another option. For such situations, provide the following pieces of +information: + flag = { + name = aliasing-option-name; + value = aliasing-flag-char; // optional ! + aliases = aliased-to-option; + }; + Do not provide anything else. The usage text for such an option will +be: + This is an alias for aliased-to-option + + +File: autogen.info, Node: opt-attr default option, Next: opt-attr documentation, Prev: opt-attr aliases, Up: option attributes + +7.5.5.9 Default Option +...................... + +If your program processes its arguments in named option mode (See +'long-opts' in *note program attributes::), then you may select *one* of +your options to be the default option. Do so by using attribute +'default' with one of the options. The option so specified must have an +'arg-type' (*note Option Arguments::) specified, but not the +'arg-optional' (*note arg-optional::) attribute. That is to say, the +option argument must be required. + + If you have done this, then any arguments that do not match an option +name and do not contain an equal sign ('=') will be interpreted as an +option argument to the default option. + + +File: autogen.info, Node: opt-attr documentation, Next: opt-attr translators, Prev: opt-attr default option, Up: option attributes + +7.5.5.10 Option Sectioning Comment +.................................. + +This attribute means the option exists for the purpose of separating +option description text in the usage output and texi documentation. +Without this attribute, every option is a separate node in the texi +docs. With this attribute, the documentation options become texi doc +nodes and the options are collected under them. Choose the name +attribute carefully because it will appear in the texi documentation. + + Libraries may also choose to make it settable so that the library can +determine which command line option is the first one that pertains to +the library. + + If the 'documentation' attribute is present, then all other +attributes are disabled except 'settable', 'call-proc' and 'flag-code'. +'settable' must be and is only specified if 'call-proc', 'extract-code' +or 'flag-code' has been specified. When present, the 'descrip' +attribute will be displayed only when the '--help' option has been +specified. It will be displayed flush to the left hand margin and may +consist of one or more lines of text, filled to 72 columns. + + The name of the option will not be printed in the help text. It +will, however, be printed as section headers in the texi documentation. +If the attribute is given a non-empty value, this text will be +reproduced in the man page and texi doc immediately after the 'descrip' +text. + + +File: autogen.info, Node: opt-attr translators, Prev: opt-attr documentation, Up: option attributes + +7.5.5.11 Translator Notes +......................... + +If you need to give the translators a special note about a particular +option, please use the 'translators' attribute. The attribute text will +be emitted into the generated '.c' text where the option related strings +get defined. To make a general comment about all of the option code, +add comments to an 'include' attribute (*note program attributes::). Do +*not* use this attribute globally, or it will get emitted into every +option definition block. + + +File: autogen.info, Node: Option Arguments, Next: Option Argument Handling, Prev: option attributes, Up: Option Definitions + +7.5.6 Option Argument Specification +----------------------------------- + +Command line options come in three flavors: options that do not take +arguments, those that do and those that may. Without an "arg-type" +attribute, AutoOpts will not process an argument to an option. If +"arg-type" is specified and "arg-optional" is also specified, then the +next command line token will be taken to be an argument, unless it looks +like the name of another option. + + If the argument type is specified to be anything other than +"str[ing]", then AutoOpts will specify a callback procedure to handle +the argument. Some of these procedures will be created and inserted +into the generated '.c' file, and others are already built into the +'libopts' library. Therefore, if you write your own callback procedure +(*note Option Argument Handling::), then you must either not specify an +"arg-type" attribute, or else specify it to be of type "str[ing]". Your +callback function will be able to place its own restrictions on what +that string may contain or represent. + + Option argument handling attributes depend upon the value set for the +'arg-type' attribute. It specifies the type of argument the option will +take. If not present, the option cannot take an argument. If present, +it must be an entry in the following table. The first three letters is +sufficient. + +* Menu: + +* arg-type string:: Arg Type String +* arg-type number:: Arg Type Number +* arg-type boolean:: Arg Type Boolean +* arg-type keyword:: Arg Type Keyword +* arg-type set membership:: Arg Type Set Membership +* arg-type hierarchy:: Arg Type Hierarchical +* arg-type file name:: Arg Type File Name +* arg-type time-duration:: Arg Type Time Duration +* arg-type time-date:: Arg Type Time and Date + +Supporting attributes for particular argument types: + +* arg-keyword:: Keyword list +* arg-optional:: Option Argument Optional +* arg-default:: Default Option Argument Value + + +File: autogen.info, Node: arg-type string, Next: arg-type number, Up: Option Arguments + +7.5.6.1 Arg Type String +....................... + +'arg-type = string;' + + The argument may be any arbitrary string, though your program or +option callback procedure may place additional constraints upon it. + + +File: autogen.info, Node: arg-type number, Next: arg-type boolean, Prev: arg-type string, Up: Option Arguments + +7.5.6.2 Arg Type Number +....................... + +'arg-type = number;' + + The argument must be a correctly formed integer, without any trailing +U's or L's. AutoOpts contains a library procedure to convert the string +to a number. If you specify range checking with 'arg-range' (see +below), then AutoOpts produces a special purpose procedure for this +option. + +'scaled' + 'scaled' marks the option so that suffixes of 'k', 'K', 'm', 'M', + 'g', 'G', 't', and 'T' will multiply the given number by a power of + 1000 or 1024. Lower case letters scale by a power of 1000 and + upper case scale by a power of 1024. + +'arg-range' + 'arg-range' is used to create a callback procedure for validating + the range of the option argument. It must match one of the range + entries. Each 'arg-range' should consist of either an integer by + itself or an integer range. The integer range is specified by one + or two integers separated by the two character sequence, '->'. Be + sure to quote the entire range string. The definitions parser will + not accept the range syntax as a single string token. + + The generated procedure imposes the range constraints as follows: + * A number by itself will match that one value. + * The high end of the range may not be 'INT_MIN', both for + obvious reasons and because that value is used to indicate a + single-valued match. + * An omitted lower value implies a lower bound of INT_MIN. + * An omitted upper value implies a upper bound of INT_MAX. + * The argument value is required. It may not be optional. + * The value must match one of the entries. If it can match more + than one, then you have redundancies, but no harm will come of + it. + + +File: autogen.info, Node: arg-type boolean, Next: arg-type keyword, Prev: arg-type number, Up: Option Arguments + +7.5.6.3 Arg Type Boolean +........................ + +'arg-type = boolean;' + + The argument will be interpreted and always yield either AG_TRUE or +AG_FALSE. False values are the empty string, the number zero, or a +string that starts with 'f', 'F', 'n' or 'N' (representing False or No). +Anything else will be interpreted as True. + + +File: autogen.info, Node: arg-type keyword, Next: arg-type set membership, Prev: arg-type boolean, Up: Option Arguments + +7.5.6.4 Arg Type Keyword +........................ + +'arg-type = keyword;' + + The argument must match a specified list of strings (*note +arg-keyword::). Assuming you have named the option, 'optn-name', the +strings will be converted into an enumeration of type 'te_Optn_Name' +with the values 'OPTN_NAME_KEYWORD'.* If you have *not* specified a +default value, the value 'OPTN_NAME_UNDEFINED' will be inserted with the +value zero. The option will be initialized to that value. You may now +use this in your code as follows: + + te_Optn_Name opt = OPT_VALUE_OPTN_NAME; + switch (opt) { + case OPTN_NAME_UNDEFINED: /* undefined things */ break; + case OPTN_NAME_KEYWORD: /* `keyword' things */ break; + default: /* utterly impossible */ ; + } + + AutoOpts produces a special purpose procedure for this option. You +may not specify an alternate handling procedure. + + If you have need for the string name of the selected keyword, you may +obtain this with the macro, 'OPT_OPTN_NAME_VAL2STR(val)'. The value you +pass would normally be 'OPT_VALUE_OPTN_NAME', but anything with numeric +value that is legal for 'te_Optn_Name' may be passed. Anything out of +range will result in the string, '"*INVALID*"' being returned. The +strings are read only. It may be used as in: + + te_Optn_Name opt = OPT_VALUE_OPTN_NAME; + printf( "you selected the %s keyword\n", + OPT_OPTN_NAME_VAL2STR(opt) ); + + * Note: you may replace the 'OPTN_NAME' enumeration prefix with +another prefix by specifying a 'prefix-enum' attribute. + + Finally, users may specify the argument either by name or by number. +Since the numeric equivalents change by having new entries inserted into +the keyword list, this would not be a recommended practice. However, +either '-1' or '~0' will always be equivalent to specifying the last +keyword. + + +File: autogen.info, Node: arg-type set membership, Next: arg-type hierarchy, Prev: arg-type keyword, Up: Option Arguments + +7.5.6.5 Arg Type Set Membership +............................... + +'arg-type = set;' + + The argument must be a list of names each of which must match the +strings "'all'", "'none'" or one of the keywords (*note arg-keyword::) +specified for this option. 'all' will turn on all membership bits and +'none' will turn them all off. Specifying one of the keywords will set +the corresponding set membership bit on (or off, if negated) . Literal +numbers may also be used and may, thereby, set or clear more than one +bit. + + The membership result starts with the previous (or initialized) +result. To clear previous results, either start the membership string +with 'none +' or with the equals character ('='). To invert (bit flip) +the final result (regardless of whether the previous result is carried +over or not), start the string with a carat character ('^'). If you +wish to invert the result and start without a carried over value, use +one of the following: '=^' or '^none+'. These are equivalent. + + The list of names or numbers must be separated by one of the +following characters: '+-|!,' or whitespace. The comma is equivalent to +whitespace, except that only one may appear between two entries and it +may not appear in conjunction with the OR bar ('|'). The '+|' leading +characters or unadorned name signify adding the next named bit to the +mask, and the '-!' leading characters indicate removing it. + + The number of keywords allowed is constrained by the number of bits +in a pointer, as the bit set is kept in a 'void *' pointer. + + If, for example, you specified 'first' in your list of keywords, then +you can use the following code to test to see if either 'first' or 'all' +was specified: + + uintptr_t opt = OPT_VALUE_OPTN_NAME; + if (opt & OPTN_NAME_FIRST) + /* OPTN_NAME_FIRST bit was set */ ; + + AutoOpts produces a special purpose procedure for this option. To +set multiple bits as the default (initial) value, you must specify an +initial numeric value (which might become inaccurate over time), or else +specify 'arg-default' multiple times. Do not specify a series of names +conjoined with '+' symbols as the value for any of the 'arg-default' +attributes. That works for option parsing, but not for the option code +generation. + + +File: autogen.info, Node: arg-type hierarchy, Next: arg-type file name, Prev: arg-type set membership, Up: Option Arguments + +7.5.6.6 Arg Type Hierarchical +............................. + +'arg-type = hierarchy;' +'arg-type = nested;' + + This denotes an option with a structure-valued argument, a.k.a. +'subopts' in 'getopts' terminology. The argument is parsed and the +values made available to the program via the find and find next calls +(*Note libopts-optionFindValue::, *Note libopts-optionGetValue::, and +*note libopts-optionFindNextValue::). + + tOptionValue * val = optionGetValue(VALUE_OPT_OPTN_NAME, "name"); + while (val != NULL) { + process(val); + val = optionNextValue(VALUE_OPT_OPTN_NAME, val); + if (wrong_name(val, "name")) + break; + } + + +File: autogen.info, Node: arg-type file name, Next: arg-type time-duration, Prev: arg-type hierarchy, Up: Option Arguments + +7.5.6.7 Arg Type File Name +.......................... + +'arg-type = file;' + + This argument type will have some validations on the argument and, +optionally, actually open the file. You must specify several additonal +attributes for the option: + +'file-exists' + If not specified or empty, then the directory portion of the name + is checked. The directory must exist or the argument is rejected + and the usage procedure is invoked. + + Otherwise, both the directory as above and the full name is tested + for existence. If the value begins with the two letters 'no', then + the file must not pre-exist. Otherwise, the file is expected to + exist. + +'open-file' + If not specified or empty, the file is left alone. If the value + begins with the four letters 'desc'[riptor], then 'open(2)' is used + and 'optArg.argFd' is set. Otherwise, the file is opened with + 'fopen' and 'optArg.argFp' is set. + +'file-mode' + If 'open-file' is set and not empty, then you must specify the open + mode. Set the value to the flag bits or mode string as appropriate + for the open type. + + +File: autogen.info, Node: arg-type time-duration, Next: arg-type time-date, Prev: arg-type file name, Up: Option Arguments + +7.5.6.8 Arg Type Time Duration +.............................. + +'arg-type = time-duration;' + + The argument will be converted into a number of seconds. It may be a +multi-part number with different parts being multiplied into a seconds +value and added into the final result. Valid forms are in the table +below. Upper cased letters represent numbers that must be used in the +expressions. + +'[[HH:]MM:]SS' + 'HH' is multiplied by '3600' and 'MM' multiplied by '60' before + they are added to 'SS'. This time specification may not be + followed by any other time specs. 'HH' and 'MM' are both optional, + though 'HH' cannot be specified without 'MM'. + +'DAYS d' + 'DAYS' is multiplied by the number of seconds in a day. This value + may be followed by (and added to) values specified by 'HH:MM:SS' or + the suffixed values below. If present, it must always be first. + +'HRS h' + 'HRS' is multiplied by the number of seconds in an hour. This + value may be followed by (and added to) values specified by 'MM:SS' + or the suffixed values below. + +'MINS m' + 'MINS' is multiplied by the number of seconds in a minute. This + value may be followed by (and added to) a count of seconds. + +'SECS s' + This value can only be the last value in a time specification. The + 's' suffix is optional. + + 5 d 1:10:05 ==> 5 days + 1 hour 10 minutes and 5 seconds + 5 d 1 h 10 m 5 ==> yields: 436205 seconds + 5d1h10m5s ==> same result -- spaces are optional. + + When saved into a config file, the value will be stored as a simple +count of seconds. There are actually more (many) accepted time duration +strings. The full documentation can be found with ISO-8601 +documentation and the more extedded documentation when +'parse_duration()' becomes more widely available. + + +File: autogen.info, Node: arg-type time-date, Next: arg-keyword, Prev: arg-type time-duration, Up: Option Arguments + +7.5.6.9 Arg Type Time and Date +.............................. + +'arg-type = time-date;' + + The argument will be converted into the number of seconds since the +epoch. The conversion rules are very complicated, please see the +'getdate_r(3GNU)' man page. There are some additional restrictions: + + 1. Your project must be compiled with 'PKGDATADIR' defined and naming + a valid directory. + 2. The 'DATEMSK' environment variable will be set to the 'datemsk' + file within that directory. + + If that file is not accessible for any reason, the string will be +parsed as a time duration (*note arg-type time-duration::) instead of a +specific date and time. + + +File: autogen.info, Node: arg-keyword, Next: arg-optional, Prev: arg-type time-date, Up: Option Arguments + +7.5.6.10 Keyword list +..................... + +If the 'arg-type' is 'keyword' (*note arg-type keyword::) or +'set-membership' (*note arg-type set membership::), then you must +specify the list of keywords by a series of 'keyword' entries. The +interface file will contain values for '<OPTN_NAME>_<KEYWORD>' for each +keyword entry. 'keyword' option types will have an enumeration and +'set-membership' option types will have a set of unsigned bits +'#define'-d. + + If the 'arg-type' is specifically 'keyword', you may also add special +handling code with a 'extra-code' attribute. After +'optionEnumerationVal' has converted the input string into an +enumeration, you may insert code to process this enumeration value +('pOptDesc->optArg.argEnum'). + + +File: autogen.info, Node: arg-optional, Next: arg-default, Prev: arg-keyword, Up: Option Arguments + +7.5.6.11 Option Argument Optional +................................. + +The 'arg-optional' attribute indicates that the argument to the option +is optional (need not be specified on the command line). This is only +valid if the ARG-TYPE is 'string' (*note arg-type string::) or 'keyword' +(*note arg-type keyword::). If it is 'keyword', then this attribute may +also specify the default keyword to assume when the argument is not +supplied. If left empty, ARG-DEFAULT (*note arg-default::) or the +zero-valued keyword will be used. + + The syntax rules for identifying the option argument are: + * If the option is specified with a flag character and there is a + character following the flag character, then string following that + flag character is the option argument. + * If the flag character is the last character in an argument, then + the first character of the next argument is examined. If it is a + hyphen, then the option is presumed to not have an argument. + Otherwise, the entire next argument is the argument for the option. + * If the option is specified with a long option name and that name is + ended with an equal sign character ('='), then everything after + that character is the option argument. + * If the long name is ended by the end of the argument, then the + first character of the next argument is examined, just as with the + flag character ending an argument string. + + This is overridden and the options are required if the libopts +library gets configured with '--disable-optional-args'. + + +File: autogen.info, Node: arg-default, Prev: arg-optional, Up: Option Arguments + +7.5.6.12 Default Option Argument Value +...................................... + +This specifies the default option argument value to be used when the +option is not specified or preset. You may specify multiple +'arg-default' values if the argument type is 'set membership'. + + +File: autogen.info, Node: Option Argument Handling, Next: Internationalizing Options, Prev: Option Arguments, Up: Option Definitions + +7.5.7 Option Argument Handling +------------------------------ + +AutoOpts will either specify or automatically generate callback +procedures for options that take specialized arguments. The only option +argument types that are not specialized are plain string arguments and +no argument at all. For options that fall into one of those two +categories, you may specify your own callback function, as specified +below. If you do this and if you specify that options are resettable +(*note automatic options::), then your option handling code *must* look +for the 'OPTST_RESET' bit in the 'fOptState' field of the option +descriptor. + + If the option takes a string argument, then the 'stack-arg' attribute +can be used to specify that the option is to be handled by the 'libopts' +'stackOptArg()' and 'unstackOptArg()' library procedures (see below). +In this case, you may not provide option handling code. + + Finally, 'documentation' options (*note opt-attr documentation::) may +also be marked as 'settable' (*note opt-attr settable::) and have +special callback functions (either 'flag-code', 'extract-code', or +'call-proc'). + +'flag-code' + statements to execute when the option is encountered. This may be + used in conjunction with option argument types that cause AutoOpts + to emit handler code. If you do this, the 'flag-code' with index + zero (0) is emitted into the handler code _before_ the argument is + handled, and the entry with index one (1) is handled afterward. + + The generated procedure will be laid out something like this: + + static void + doOpt<name>(tOptions* pOptions, tOptDesc* pOptDesc) + { + <flag-code[0]> + <AutoOpts defined handler code> + <flag-code[1]> + } + + Only certain fields within the 'tOptions' and 'tOptDesc' structures + may be accessed. *Note Option Processing Data::. When writing + this code, you must be very careful with the 'pOptions' pointer. + The handler code is called with this pointer set to special values + for handling special situations. Your code must handle them. As + an example, look at 'optionEnumerationVal' in 'enum.c'. + +'extract-code' + This is effectively identical to 'flag-code', except that the + source is kept in the output file instead of the definitions file + and you cannot use this in conjunction with options with arguments, + other than string arguments. + + A long comment is used to demarcate the code. You must not modify + that marker. Before regenerating the option code file, the old + file is renamed from MUMBLE.c to MUMBLE.c.save. The template will + be looking there for the text to copy into the new output file. + +'call-proc' + external procedure to call when option is encountered. The calling + sequence must conform to the sequence defined above for the + generated procedure, 'doOpt<name>'. It has the same restrictions + regarding the fields within the structures passed in as arguments. + *Note Option Processing Data::. + +'flag-proc' + Name of another option whose 'flag-code' can be executed when this + option is encountered. + +'stack-arg' + Call a special library routine to stack the option's arguments. + Special macros in the interface file are provided for determining + how many of the options were found ('STACKCT_OPT(NAME)') and to + obtain a pointer to a list of pointers to the argument values + ('STACKLST_OPT(NAME)'). Obviously, for a stackable argument, the + 'max' attribute (*note Common Attributes::) needs to be set higher + than '1'. + + If this stacked argument option has a disablement prefix, then the + entire stack of arguments will be cleared by specifying the option + with that disablement prefix. + +'unstack-arg' + Call a special library routine to remove ('unstack') strings from a + 'stack-arg' option stack. This attribute must name the option that + is to be 'unstacked'. Neither this option nor the stacked argument + option it references may be equivalenced to another option. + + +File: autogen.info, Node: Internationalizing Options, Next: documentation attributes, Prev: Option Argument Handling, Up: Option Definitions + +7.5.8 Internationalizing Options +-------------------------------- + +Normally, AutoOpts produces usage text that is difficult to translate. +It is pieced together on the fly using words and phrases scattered +around here and there, piecing together toe document. This does not +translate well. + + Incorporated into this package are some ways around the problem. +First, you should specify the 'full-usage' and 'short-usage' program +attributes (*note program attributes::). This will enable your +translators to translate the usage text as a whole. + + Your translators will also be able to translate long option names. +The option name translations will then become the names searched for +both on the command line and in configuration files. However, it will +not affect the names of environment variable names used to configure +your program. + + If it is considered desireable to keep configuration files in the 'C' +locale, then several macros are available to suppress or delay the +translations of option names at run time. These are all disabled if +'ENABLE_NLS' is not defined at compile time or if 'no-xlate' has been +set to the value _anything_. These macros *must* be invoked before the +first invocation of 'optionProcess'. + +'OPT_NO_XLAT_CFG_NAMES;' +'OPT_XLAT_CFG_NAMES;' + Disable (or enable) the translations of option names for + configuration files. If you enable translation for config files, + then they will be translated for command line options. + +'OPT_NO_XLAT_OPT_NAMES;' +'OPT_XLAT_OPT_NAMES;' + Disable (or enable) the translations of option names for command + line processing. If you disable the translation for command line + processing, you will also disable it for configuration file + processing. Once translated, the option names will remain + translated. + + +File: autogen.info, Node: documentation attributes, Next: automatic options, Prev: Internationalizing Options, Up: Option Definitions + +7.5.9 Man and Info doc Attributes +--------------------------------- + +AutoOpts includes AutoGen templates for producing abbreviated man pages +and for producing the invoking section of an info document. To take +advantage of these templates, you must add several attributes to your +option definitions. + +* Menu: + +* per option attributes:: Per option documentation attributes +* global option attributes:: Global documentation attributes + + +File: autogen.info, Node: per option attributes, Next: global option attributes, Up: documentation attributes + +7.5.9.1 Per option documentation attributes +........................................... + +These attributes are sub-attributes (sub-stanzas) of the 'flag' stanzas. + +'arg-name' + If an option has an argument, the argument should have a name for + documentation purposes. It will default to 'arg-type', but it will + likely be clearer with something else like, 'file-name' instead of + 'string' (the type). + +'doc' + First, every 'flag' definition _other than_ 'documentation' + definitions, must have a 'doc' attribute defined. If the option + takes an argument, then it will need an 'arg-name' attribute as + well. The 'doc' text should be in plain sentences with minimal + formatting. The Texinfo commands '@code', and '@var' will have its + enclosed text made into *\fB* entries in the man page, and the + '@file' text will be made into *\fI* entries. The 'arg-name' + attribute is used to display the option's argument in the man page. + + Options marked with the 'documentation' attribute are for + documenting the usage text. All other options should have the + 'doc' attribute in order to document the usage of the option in the + generated man pages. + + Since these blocks of text are inserted into all output forms, any + markup text included in these blocks must be massaged for each + output format. By default, it is presumed to be 'texi' format. + + +File: autogen.info, Node: global option attributes, Prev: per option attributes, Up: documentation attributes + +7.5.9.2 Global documentation attributes +....................................... + +'cmd-section' + If your command is a game or a system management command, specify + this attribute with the value '5' or '8', respectively. The + default is a user command (section 1). + +'detail' + This attribute is used to add a very short explanation about what a + program is used for when the 'title' attribute is insufficient. If + there is no 'doc-section' stanza of type 'DESCRIPTION', then this + text is used for the man page DESCRIPTION section, too. + +'addtogroup' + This attribute tells the template that the generated code should be + surrounded with the following doxygen comments: + /** @file <header-or-code-file-name> + * @addtogroup <value-of-addtogroup> + * @{ + */ + and + /** @} */ + +'option-format' + Specify the default markup style for the 'doc' stanzas. By + default, it is 'texi', but 'man' and 'mdoc' may also be selected. + There are nine converter programs that do a partial job of + converting one form of markup into another. 'texi2texi', 'man2man' + and 'mdoc2mdoc' work pretty well. + + You may also post process the document by using 'doc-sub' stanzas, + see below. + +'option-info' + This text will be inserted as a lead-in paragraph in the 'OPTIONS' + section of the generated man page. + +'doc-section' + This is a compound attribute that requires three subattributes: + + ds-format + This describes the format of the associated 'ds-text' section. + 'man', 'mdoc' and 'texi' formats are supported. Regardless of + the chosen format, the formatting tags in the output text will + be converted to 'man' macros for 'man' pages, 'mdoc' macros + for 'mdoc' pages, and 'texi' macros for 'texinfo' pages. + + ds-text + This is the descriptive text, written according to the rules + for 'ds-format' documents. + + ds-type + This describes the section type. Basically, the title of the + section that will be added to all output documentation. There + may be only one 'doc-section' for any given 'ds-type'. If + there are duplicates, the results are undefined (it might + work, it might not). + + There are five categories of 'ds-type' sections. They are + those that the documentation templates would otherwise: + 1. always create itself, ignoring any 'ds-type's by this + name. These are marked, below, as 'ao-only'. + 2. create, if none was provided. These are marked, + 'alternate'. + 3. create, but augment if the 'doc-section' was provided. + These are marked, 'augments'. + 4. do nothing, but inserts them into the output in a + prescribed order. These are marked, 'known' + 5. knows nothing about them. They will be alphabetized and + inserted after the list of leading sections and before + the list of trailing sections. These are not marked + because I don't know their names. + + Some of these are emitted by the documentation templates only + if certain conditions are met. If there are conditions, they + are explained below. If there are no conditions, then you + will always see the named section in the output. + + The output sections will appear in this order: + 'NAME' + 'ao-only'. + 'SYNOPSIS' + 'alternate'. + 'DESCRIPTION' + 'augments'. + 'OPTIONS' + 'ao-only'. + 'OPTION PRESETS' + 'ao-only', if environment presets or configuration file + processing has been specified. + 'unknown' + At this point, the unknown, alphabetized sections are + inserted. + 'IMPLEMENTATION NOTES' + 'known' + 'ENVIRONMENT' + 'augments', if environment presets have been specified. + 'FILES' + 'augments', if configuration file processing has been + specified. + 'EXAMPLES' + 'known' + 'EXIT STATUS' + 'augments'. + 'ERRORS' + 'known' + 'COMPATIBILITY' + 'known' + 'SEE ALSO' + 'known' + 'CONFORMING TO' + 'known' + 'HISTORY' + 'known' + 'AUTHORS' + 'alternate', if the 'copyright' stanza has either an + 'author' or an 'owner' attribute. + 'COPYRIGHT' + 'alternate', if there is a 'copyright' stanza. + 'BUGS' + 'augments', if the 'copyright' stanza has an 'eaddr' + attribute. + 'NOTES' + 'augments'. + + Here is an example of a 'doc-section' for a 'SEE ALSO' type. + + doc-section = { + ds-type = 'SEE ALSO'; // or anything else + ds-format = 'man'; // or texi or mdoc format + ds-text = <<-_EOText_ + text relevant to this section type, + in the chosen format + _EOText_; + }; + +'doc-sub' + This attribute will cause the resulting documentation to be + post-processed. This is normally with 'sed', see 'doc-sub-cmd' + below. This attribute has several sub-attributes: + + 'sub-name' + This is the name of an autogen text definition value, like + 'prog-name' or 'version'. In the 'sub-text' field, + occurrences of this name preceded by two less than characters + and followed by two greater than characters will be replaced + by the text value of the definition, e.g. '<<prog-name>>'. + + 'sub-text' + The text that gets added to the command file for the post + processing program. + + 'sub-type' + If this command only applies to certain types of output, + specify this with a regular expression that will match one of + the valid output format types, e.g. 'man|mdoc' will match + those two kinds, but not 'texi' output. If omitted, it will + always apply. + + For example, if you want to reference the program name in the 'doc' + text for an option common to two programs, put '#PROG#' into the + text. The following will replace all occrrences of '#PROG#' with + the current value for 'prog': + doc-sub = { + sub-name = prog-name; + sub-text = 's/#PROG#/<<prog-name>>/g'; + }; + +'doc-sub-cmd' + A formatting string for constructing the post-processing command. + The first parameter is the name of the file with editing commands + in it, and the second is the file containing the unprocessed + document. The default value is: + sed -f %s %s + + +File: autogen.info, Node: automatic options, Next: standard options, Prev: documentation attributes, Up: Option Definitions + +7.5.10 Automatically Supported Options +-------------------------------------- + +AutoOpts provides automated support for several options. 'help' and +'more-help' are always provided. The others are conditional upon +various global program attributes being defined *Note program +attributes::. + + Below are the option names and default flag values. The flags are +activated if and only if at least one user-defined option also uses a +flag value. The long names are supported as option names if 'long-opts' +has been specified. These option flags may be deleted or changed to +characters of your choosing by specifying 'xxx-value = "y";', where +'xxx' is one of the option names below and 'y' is either empty or the +character of your choice. For example, to change the help flag from '?' +to 'h', specify 'help-value = "h";'; and to require that 'save-opts' be +specified only with its long option name, specify 'save-opts-value = +"";'. + + Additionally, the procedure that prints out the program version may +be replaced by specifying 'version-proc'. This procedure must be +defined to be of external scope (non-static). By default, the AutoOpts +library provides 'optionPrintVersion' and it will be the specified +callback function in the option definition structure. + + With the exception of the 'load-opts' option, none of these +automatically supported options will be recognized in configuration +files or environment variables. + +'help -?' + This option will immediately invoke the 'USAGE()' procedure and + display the usage line, a description of each option with its + description and option usage information. This is followed by the + contents of the definition of the 'detail' text macro. + +'more-help -!' + This option is identical to the 'help' option, except that the + output is passed through a pager program. ('more' by default, or + the program identified by the 'PAGER' environment variable.) + +'usage -u' + This option must be requested by specifying, 'usage-opt' in the + option definition file. It will produce abbreviated help text to + 'stdout' and exit with zero status ('EXIT_SUCCESS'). + +'version -v' + + This will print the program name, title and version. If it is not + followed by anything or is followed by the letter 'v', just the + program name and version will be printed. If followed by the + letter 'c' and a value for 'copyright' and 'owner' have been + provided, then the copyright will be printed, too. If it is + followed by the letter 'n', then the full copyright notice (if + available) will be printed. The 'version' attribute must be + specified in the option definition file. + + Because some target platforms discourage optional arguments to + options, the autoopts library can be compiled with + 'NO_OPTIONAL_OPT_ARGS' defined. Alternatively, the 'version-type' + attribute can be added to the option definitions and it can specify + which flavor is preferred. In either case, an argument to the + '--version' option will then be disallowed. + +'load-opts -<' + This option will load options from the named file. They will be + treated exactly as if they were loaded from the normally found + configuration files, but will not be loaded until the option is + actually processed. This can also be used within another + configuration file, causing them to nest. This is the *only* + automatically supported option that can be activated inside of + config files or with environment variables. + + Specifying the negated form of the option ('--no-load-opts') will + suppress the processing of configuration files and environment + variables. + + This option is activated by specifying one or more 'homerc' + attributes. + +'save-opts ->' + This option will cause the option state to be printed in the + configuration file format when option processing is done but not + yet verified for consistency. The program will terminate + successfully without running when this has completed. Note that + for most shells you will have to quote or escape the flag character + to restrict special meanings to the shell. + + The output file will be the configuration file name (default or + provided by 'rcfile') in the last directory named in a 'homerc' + definition. + + This option may be set from within your program by invoking the + "'SET_OPT_SAVE_OPTS(filename)'" macro (*note SET_OPT_name::). + Invoking this macro will set the file name for saving the option + processing state, but the state will *not* actually be saved. You + must call 'optionSaveFile' to do that (*note + libopts-optionSaveFile::). *CAVEAT:* if, after invoking this + macro, you call 'optionProcess', the option processing state will + be saved to this file and 'optionProcess' will not return. You may + wish to invoke 'CLEAR_OPT( SAVE_OPTS )' (*note CLEAR_OPT::) + beforehand if you do need to reinvoke 'optionProcess'. + + This option is activated by specifying one or more 'homerc' + attributes. + + The method of saving the state may be altered by specifying flags + before the output file name. "Flags" are specified by placing a + list of them before the file name and separating them from the name + with one or two greater-than characters (">"). There are three + flags currently supported: + + 'default' + If an option has a default value (has not been set), then the + default value is inserted as a comment. + + 'usage' + Every option that can be processed from the configuration file + will have a comment that contains the usage string that gets + printed with the '--help' text + + 'update' + Instead of removing the old file and writing a new one, the + output file is kept, but any pre-existing segment labeled with + '<?program prog-name>' is removed. The new program segment is + placed at the end of the file. This flag is implied if the + flags are separated from the file name with doubled + greater-than characters. In other words, 'update,usage > + file-name' and 'usage >> file-name' are identical. + +'reset-option -R' + This option takes the name of an option for the current program and + resets its state such that it is set back to its original, + compile-time initialized value. If the option state is + subsequently stored (via '--save-opts'), the named option will not + appear in that file. + + This option is activated by specifying the 'resettable' attribute. + + *BEWARE*: If the 'resettable' attribute is specified, all option + callbacks *must* look for the 'OPTST_RESET' bit in the 'fOptState' + field of the option descriptor. If set, the 'optCookie' and + 'optArg' fields will be unchanged from their last setting. When + the callback returns, these fields will be set to their original + values. If you use this feature and you have allocated data + hanging off of the cookie, you need to deallocate it. + + +File: autogen.info, Node: standard options, Prev: automatic options, Up: Option Definitions + +7.5.11 Library of Standard Options +---------------------------------- + +AutoOpts has developed a set of standardized options. You may +incorporate these options in your program simply by _first_ adding a +'#define' for the options you want, and then the line, + + #include stdoptions.def + +in your option definitions. The supported options are specified thus: + + #define DEBUG + #define DIRECTORY + #define DRY_RUN + #define INPUT + #define INTERACTIVE + #define OUTPUT + #define WARN + + #define SILENT + #define QUIET + #define BRIEF + #define VERBOSE + + By default, only the long form of the option will be available. To +specify the short (flag) form, suffix these names with '_FLAG'. e.g., + + #define DEBUG_FLAG + + '--silent', '--quiet', '--brief' and '--verbose' are related in that +they all indicate some level of diagnostic output. These options are +all designed to conflict with each other. Instead of four different +options, however, several levels can be incorporated by '#define'-ing +'VERBOSE_ENUM'. In conjunction with 'VERBOSE', it incorporates the +notion of 5 levels in an enumeration: 'silent', 'quiet', 'brief', +'informative' and 'verbose'; with the default being 'brief'. + + Here is an example program that uses the following set of +definitions: + + AutoGen Definitions options; + + prog-name = default-test; + prog-title = 'Default Option Example'; + homerc = '$$/../share/default-test', '$HOME', '.'; + environrc; + long-opts; + gnu-usage; + usage-opt; + version = '1.0'; + main = { + main-type = shell-process; + }; + #define DEBUG_FLAG + #define WARN_FLAG + #define WARN_LEVEL + #define VERBOSE_FLAG + #define VERBOSE_ENUM + #define DRY_RUN_FLAG + #define OUTPUT_FLAG + #define INPUT_FLAG + #define DIRECTORY_FLAG + #define INTERACTIVE_FLAG + #include stdoptions.def + +Running a few simple commands on that definition file: + + autogen default-test.def + copts="-DTEST_DEFAULT_TEST_OPTS `autoopts-config cflags`" + lopts="`autoopts-config ldflags`" + cc -o default-test ${copts} default-test.c ${lopts} + +Yields a program which, when run with '--help', prints out: + + + exit 0 + + +File: autogen.info, Node: AutoOpts API, Next: Multi-Threading, Prev: Option Definitions, Up: AutoOpts + +7.6 Programmatic Interface +========================== + +The user interface for access to the argument information is completely +defined in the generated header file and in the portions of the +distributed file "options.h" that are marked "public". + + In the following macros, text marked <NAME> or NAME is the name of +the option *in upper case* and *segmented with underscores '_'*. The +macros and enumerations defined in the options header (interface) file +are used as follows: + + To see how these '#define' macros are used in a program, the reader +is referred to the several 'opts.h' files included with the AutoGen +sources. + +* Menu: + +* Option Processing Data:: Data for Option Processing +* CLEAR_OPT:: CLEAR_OPT( <NAME> ) - Clear Option Markings +* COUNT_OPT:: COUNT_OPT( <NAME> ) - Definition Count +* DESC:: DESC( <NAME> ) - Option Descriptor +* DISABLE_OPT_name:: DISABLE_OPT_name - Disable an option +* ENABLED_OPT:: ENABLED_OPT( <NAME> ) - Is Option Enabled? +* ERRSKIP_OPTERR:: ERRSKIP_OPTERR - Ignore Option Errors +* ERRSTOP_OPTERR:: ERRSTOP_OPTERR - Stop on Errors +* HAVE_OPT:: HAVE_OPT( <NAME> ) - Have this option? +* ISSEL_OPT:: ISSEL_OPT( <NAME> ) - Is Option Selected? +* ISUNUSED_OPT:: ISUNUSED_OPT( <NAME> ) - Never Specified? +* OPTION_CT:: OPTION_CT - Full Count of Options +* OPT_ARG:: OPT_ARG( <NAME> ) - Option Argument String +* OPT_NO_XLAT_CFG_NAMES:: OPT_NO_XLAT_CFG_NAMES - option name xlation +* OPT_NO_XLAT_OPT_NAMES:: OPT_NO_XLAT_OPT_NAMES - option name xlation +* OPT_VALUE_name:: OPT_VALUE_name - Option Argument Value +* OPT_XLAT_CFG_NAMES:: OPT_XLAT_CFG_NAMES - option name xlation +* OPT_XLAT_OPT_NAMES:: OPT_XLAT_OPT_NAMES - option name xlation +* RESTART_OPT:: RESTART_OPT( n ) - Resume Option Processing +* SET_OPT_name:: SET_OPT_name - Force an option to be set +* STACKCT_OPT:: STACKCT_OPT( <NAME> ) - Stacked Arg Count +* STACKLST_OPT:: STACKLST_OPT( <NAME> ) - Argument Stack +* START_OPT:: START_OPT - Restart Option Processing +* STATE_OPT:: STATE_OPT( <NAME> ) - Option State +* USAGE:: USAGE( exit-code ) - Usage invocation macro +* VALUE_OPT_name:: VALUE_OPT_name - Option Flag Value +* VERSION:: VERSION - Version and Full Version +* WHICH_IDX_name:: WHICH_IDX_name - Which Equivalenced Index +* WHICH_OPT_name:: WHICH_OPT_name - Which Equivalenced Option +* teOptIndex:: teOptIndex - Option Index and Enumeration +* OPTIONS_STRUCT_VERSION:: OPTIONS_STRUCT_VERSION - active version +* libopts procedures:: libopts External Procedures + + +File: autogen.info, Node: Option Processing Data, Next: CLEAR_OPT, Up: AutoOpts API + +7.6.1 Data for Option Processing +-------------------------------- + +This section describes the data that may be accessed from within the +option processing callback routines. The following fields may be used +in the following ways and may be used for read only. The first set is +addressed from the 'tOptDesc*' pointer: + +'optIndex' +'optValue' + These may be used by option procedures to determine which option + they are working on (in case they handle several options). + +'optActualIndex' +'optActualValue' + These may be used by option procedures to determine which option + was used to set the current option. This may be different from the + above if the options are members of an equivalence class. + +'optOccCt' + If AutoOpts is processing command line arguments, then this value + will contain the current occurrence count. During the option + preset phase (reading configuration files and examining environment + variables), the value is zero. + +'fOptState' + The field may be tested for the following bit values (prefix each + name with 'OPTST_', e.g. 'OPTST_INIT'): + + 'INIT' + Initial compiled value. As a bit test, it will always yield + FALSE. + + 'SET' + The option was set via the 'SET_OPT()' macro. + + 'PRESET' + The option was set via a configuration file. + + 'DEFINED' + The option was set via a command line option. + + 'SET_MASK' + This is a mask of flags that show the set state, one of the + above four values. + + 'EQUIVALENCE' + This bit is set when the option was selected by an + equivalenced option. + + 'DISABLED' + This bit is set if the option is to be disabled. (Meaning it + was a long option prefixed by the disablement prefix, or the + option has not been specified yet and initializes as + 'disabled'.) + + As an example of how this might be used, in AutoGen I want to allow + template writers to specify that the template output can be left in + a writable or read-only state. To support this, there is a Guile + function named 'set-writable' (*note SCM set-writable::). Also, I + provide for command options '--writable' and '--not-writable'. I + give precedence to command line and RC file options, thus: + + switch (STATE_OPT( WRITABLE )) { + case OPTST_DEFINED: + case OPTST_PRESET: + fprintf(stderr, zOverrideWarn, pCurTemplate->pzFileName, + pCurMacro->lineNo); + break; + + default: + if (gh_boolean_p( set ) && (set == SCM_BOOL_F)) + CLEAR_OPT( WRITABLE ); + else + SET_OPT_WRITABLE; + } + +'pzLastArg' + Pointer to the latest argument string. BEWARE If the argument type + is numeric, an enumeration or a bit mask, then this will be the + argument *value* and not a pointer to a string. + + The following two fields are addressed from the 'tOptions*' pointer: + +'pzProgName' + Points to a NUL-terminated string containing the current program + name, as retrieved from the argument vector. + +'pzProgPath' + Points to a NUL-terminated string containing the full path of the + current program, as retrieved from the argument vector. (If + available on your system.) + + Note these fields get filled in during the first call to +'optionProcess()'. All other fields are private, for the exclusive use +of AutoOpts code and are subject to change. + + +File: autogen.info, Node: CLEAR_OPT, Next: COUNT_OPT, Prev: Option Processing Data, Up: AutoOpts API + +7.6.2 CLEAR_OPT( <NAME> ) - Clear Option Markings +------------------------------------------------- + +Make as if the option had never been specified. 'HAVE_OPT(<NAME>)' will +yield 'FALSE' after invoking this macro. + + +File: autogen.info, Node: COUNT_OPT, Next: DESC, Prev: CLEAR_OPT, Up: AutoOpts API + +7.6.3 COUNT_OPT( <NAME> ) - Definition Count +-------------------------------------------- + +This macro will tell you how many times the option was specified on the +command line. It does not include counts of preset options. + + if (COUNT_OPT( NAME ) != desired-count) { + make-an-undesirable-message. + } + + +File: autogen.info, Node: DESC, Next: DISABLE_OPT_name, Prev: COUNT_OPT, Up: AutoOpts API + +7.6.4 DESC( <NAME> ) - Option Descriptor +---------------------------------------- + +This macro is used internally by other AutoOpt macros. It is not for +general use. It is used to obtain the option description corresponding +to its *UPPER CASED* option name argument. This is primarily used in +other macro definitions. + + +File: autogen.info, Node: DISABLE_OPT_name, Next: ENABLED_OPT, Prev: DESC, Up: AutoOpts API + +7.6.5 DISABLE_OPT_name - Disable an option +------------------------------------------ + +This macro is emitted if it is both settable and it can be disabled. If +it cannot be disabled, it may always be CLEAR-ed (see above). + + The form of the macro will actually depend on whether the option is +equivalenced to another, and/or has an assigned handler procedure. +Unlike the 'SET_OPT' macro, this macro does not allow an option +argument. + + DISABLE_OPT_NAME; + + +File: autogen.info, Node: ENABLED_OPT, Next: ERRSKIP_OPTERR, Prev: DISABLE_OPT_name, Up: AutoOpts API + +7.6.6 ENABLED_OPT( <NAME> ) - Is Option Enabled? +------------------------------------------------ + +Yields true if the option defaults to disabled and 'ISUNUSED_OPT()' +would yield true. It also yields true if the option has been specified +with a disablement prefix, disablement value or the 'DISABLE_OPT_NAME' +macro was invoked. + + +File: autogen.info, Node: ERRSKIP_OPTERR, Next: ERRSTOP_OPTERR, Prev: ENABLED_OPT, Up: AutoOpts API + +7.6.7 ERRSKIP_OPTERR - Ignore Option Errors +------------------------------------------- + +When it is necessary to continue (return to caller) on option errors, +invoke this option. It is reversible. *Note ERRSTOP_OPTERR::. + + +File: autogen.info, Node: ERRSTOP_OPTERR, Next: HAVE_OPT, Prev: ERRSKIP_OPTERR, Up: AutoOpts API + +7.6.8 ERRSTOP_OPTERR - Stop on Errors +------------------------------------- + +After invoking this macro, if 'optionProcess()' encounters an error, it +will call 'exit(1)' rather than return. This is the default processing +mode. It can be overridden by specifying 'allow-errors' in the +definitions file, or invoking the macro *Note ERRSKIP_OPTERR::. + + +File: autogen.info, Node: HAVE_OPT, Next: ISSEL_OPT, Prev: ERRSTOP_OPTERR, Up: AutoOpts API + +7.6.9 HAVE_OPT( <NAME> ) - Have this option? +-------------------------------------------- + +This macro yields true if the option has been specified in any fashion +at all. It is used thus: + + if (HAVE_OPT( NAME )) { + <do-things-associated-with-opt-name>; + } + + +File: autogen.info, Node: ISSEL_OPT, Next: ISUNUSED_OPT, Prev: HAVE_OPT, Up: AutoOpts API + +7.6.10 ISSEL_OPT( <NAME> ) - Is Option Selected? +------------------------------------------------ + +This macro yields true if the option has been specified either on the +command line or via a SET/DISABLE macro. + + +File: autogen.info, Node: ISUNUSED_OPT, Next: OPTION_CT, Prev: ISSEL_OPT, Up: AutoOpts API + +7.6.11 ISUNUSED_OPT( <NAME> ) - Never Specified? +------------------------------------------------ + +This macro yields true if the option has never been specified, or has +been cleared via the 'CLEAR_OPT()' macro. + + +File: autogen.info, Node: OPTION_CT, Next: OPT_ARG, Prev: ISUNUSED_OPT, Up: AutoOpts API + +7.6.12 OPTION_CT - Full Count of Options +---------------------------------------- + +The full count of all options, both those defined and those generated +automatically by AutoOpts. This is primarily used to initialize the +program option descriptor structure. + + +File: autogen.info, Node: OPT_ARG, Next: OPT_NO_XLAT_CFG_NAMES, Prev: OPTION_CT, Up: AutoOpts API + +7.6.13 OPT_ARG( <NAME> ) - Option Argument String +------------------------------------------------- + +The option argument value as a pointer to string. Note that argument +values that have been specified as numbers are stored as numbers or +keywords. For such options, use instead the 'OPT_VALUE_name' define. +It is used thus: + + if (HAVE_OPT( NAME )) { + char* p = OPT_ARG( NAME ); + <do-things-with-opt-name-argument-string>; + } + + +File: autogen.info, Node: OPT_NO_XLAT_CFG_NAMES, Next: OPT_NO_XLAT_OPT_NAMES, Prev: OPT_ARG, Up: AutoOpts API + +7.6.14 OPT_NO_XLAT_CFG_NAMES - option name xlation +-------------------------------------------------- + +Invoking this macro will disable the translation of option names only +while processing configuration files and environment variables. This +must be invoked before the first call to 'optionProcess'.. You need not +invoke this if your option definition file contains the attribute +assignment, 'no-xlate = opt-cfg;'. + + +File: autogen.info, Node: OPT_NO_XLAT_OPT_NAMES, Next: OPT_VALUE_name, Prev: OPT_NO_XLAT_CFG_NAMES, Up: AutoOpts API + +7.6.15 OPT_NO_XLAT_OPT_NAMES - option name xlation +-------------------------------------------------- + +Invoking this macro will completely disable the translation of option +names. This must be invoked before the first call to 'optionProcess'. +You need not invoke this if your option definition file contains the +attribute assignment, 'no-xlate = opt;'. + + +File: autogen.info, Node: OPT_VALUE_name, Next: OPT_XLAT_CFG_NAMES, Prev: OPT_NO_XLAT_OPT_NAMES, Up: AutoOpts API + +7.6.16 OPT_VALUE_name - Option Argument Value +--------------------------------------------- + +This macro gets emitted only for options that take numeric, keyword or +set membership arguments. The macro yields a word-sized integer +containing the enumeration, bit set or numeric value for the option +argument. + + int opt_val = OPT_VALUE_name; + + +File: autogen.info, Node: OPT_XLAT_CFG_NAMES, Next: OPT_XLAT_OPT_NAMES, Prev: OPT_VALUE_name, Up: AutoOpts API + +7.6.17 OPT_XLAT_CFG_NAMES - option name xlation +----------------------------------------------- + +If 'ENABLE_NLS' is defined and 'no-xlate' has been not set to the value +_anything_, this macro will cause the translation of option names to +happen before starting the processing of configuration files and +environment variables. This will change the recognition of options +within the '$PROGRAMNAME' environment variable, but will not alter the +names used for setting options via '$PROGRAMNAME_name' environment +variables. + + This must be invoked before the first call to 'optionProcess'. You +might need to use this macro if your option definition file contains the +attribute assignment, 'no-xlate = opt;' or 'no-xlate = opt-cfg;', and +you have determined in some way that you wish to override that. + + +File: autogen.info, Node: OPT_XLAT_OPT_NAMES, Next: RESTART_OPT, Prev: OPT_XLAT_CFG_NAMES, Up: AutoOpts API + +7.6.18 OPT_XLAT_OPT_NAMES - option name xlation +----------------------------------------------- + +If 'ENABLE_NLS' is defined and 'no-xlate' has been not set to the value +_anything_, translate the option names before processing the command +line options. Long option names may thus be localized. (If the names +were translated before configuration processing, they will not be +re-translated.) + + This must be invoked before the first call to 'optionProcess'. You +might need to use this macro if your option definition file contains the +attribute assignment, 'no-xlate = opt;' and you have determined in some +way that you wish to override that. + + +File: autogen.info, Node: RESTART_OPT, Next: SET_OPT_name, Prev: OPT_XLAT_OPT_NAMES, Up: AutoOpts API + +7.6.19 RESTART_OPT( n ) - Resume Option Processing +-------------------------------------------------- + +If option processing has stopped (either because of an error or +something was encountered that looked like a program argument), it can +be resumed by providing this macro with the index 'n' of the next option +to process and calling 'optionProcess()' again. + + int main(int argc, char ** argv) { + for (int ai = 0; ai < argc ;) { + restart: + ai = optionProcess(&progOptions, argc, argv); + for (; ai < argc; ai++) { + char * arg = arg[ai]; + if (*arg == '-') { + RESTART_OPT(ai); + goto restart; + } + process(arg); + } + } + } + + If you want a program to operate this way, you might consider +specifying a 'for-each' main function (*note for-each main procedure: +main for-each.) with the 'interleaved' attribute. It will allow you to +process interleaved operands and options from either the command line or +when reading them from standard input. + + +File: autogen.info, Node: SET_OPT_name, Next: STACKCT_OPT, Prev: RESTART_OPT, Up: AutoOpts API + +7.6.20 SET_OPT_name - Force an option to be set +----------------------------------------------- + +This macro gets emitted only when the given option has the 'settable' +attribute specified. + + The form of the macro will actually depend on whether the option is +equivalenced to another, has an option argument and/or has an assigned +handler procedure. If the option has an argument, then this macro will +too. Beware that the argument is not reallocated, so the value must not +be on the stack or deallocated in any other way for as long as the value +might get referenced. + + If you have supplied at least one 'homerc' file (*note program +attributes::), this macro will be emitted for the '--save-opts' option. + + SET_OPT_SAVE_OPTS( "filename" ); + +*Note automatic options::, for a discussion of the implications of using +this particular example. + + +File: autogen.info, Node: STACKCT_OPT, Next: STACKLST_OPT, Prev: SET_OPT_name, Up: AutoOpts API + +7.6.21 STACKCT_OPT( <NAME> ) - Stacked Arg Count +------------------------------------------------ + +When the option handling attribute is specified as 'stack_arg', this +macro may be used to determine how many of them actually got stacked. + + Do not use this on options that have not been stacked or has not been +specified (the 'stack_arg' attribute must have been specified, and +'HAVE_OPT(<NAME>)' must yield TRUE). Otherwise, you will likely seg +fault. + + if (HAVE_OPT( NAME )) { + int ct = STACKCT_OPT( NAME ); + char** pp = STACKLST_OPT( NAME ); + + do { + char* p = *pp++; + do-things-with-p; + } while (--ct > 0); + } + + +File: autogen.info, Node: STACKLST_OPT, Next: START_OPT, Prev: STACKCT_OPT, Up: AutoOpts API + +7.6.22 STACKLST_OPT( <NAME> ) - Argument Stack +---------------------------------------------- + +The address of the list of pointers to the option arguments. The +pointers are ordered by the order in which they were encountered in the +option presets and command line processing. + + Do not use this on options that have not been stacked or has not been +specified (the 'stack_arg' attribute must have been specified, and +'HAVE_OPT(<OPTION>)' must yield TRUE). Otherwise, you will likely seg +fault. + + if (HAVE_OPT( NAME )) { + int ct = STACKCT_OPT( NAME ); + char** pp = STACKLST_OPT( NAME ); + + do { + char* p = *pp++; + do-things-with-p; + } while (--ct > 0); + } + + +File: autogen.info, Node: START_OPT, Next: STATE_OPT, Prev: STACKLST_OPT, Up: AutoOpts API + +7.6.23 START_OPT - Restart Option Processing +-------------------------------------------- + +This is just a shortcut for RESTART_OPT(1) (*Note RESTART_OPT::.) + + +File: autogen.info, Node: STATE_OPT, Next: USAGE, Prev: START_OPT, Up: AutoOpts API + +7.6.24 STATE_OPT( <NAME> ) - Option State +----------------------------------------- + +If you need to know if an option was set because of presetting actions +(configuration file processing or environment variables), versus a +command line entry versus one of the SET/DISABLE macros, then use this +macro. It will yield one of four values: 'OPTST_INIT', 'OPTST_SET', +'OPTST_PRESET' or 'OPTST_DEFINED'. It is used thus: + + switch (STATE_OPT( NAME )) { + case OPTST_INIT: + not-preset, set or on the command line. (unless CLEAR-ed) + + case OPTST_SET: + option set via the SET_OPT_NAME() macro. + + case OPTST_PRESET: + option set via an configuration file or environment variable + + case OPTST_DEFINED: + option set via a command line option. + + default: + cannot happen :) + } + + +File: autogen.info, Node: USAGE, Next: VALUE_OPT_name, Prev: STATE_OPT, Up: AutoOpts API + +7.6.25 USAGE( exit-code ) - Usage invocation macro +-------------------------------------------------- + +This macro invokes the procedure registered to display the usage text. +Normally, this will be 'optionUsage' from the AutoOpts library, but you +may select another procedure by specifying 'usage = "proc_name"' program +attribute. This procedure must take two arguments first, a pointer to +the option descriptor, and second the exit code. The macro supplies the +option descriptor automatically. This routine is expected to call +'exit(3)' with the provided exit code. + + The 'optionUsage' routine also behaves differently depending on the +exit code: + +'EXIT_SUCCESS (the value zero)' + It is assumed that full usage help has been requested. + Consequently, more information is provided than when displaying + usage and exiting with a non-zero exit code. Output will be sent + to 'stdout' and the program will exit with a zero status code. + +'EX_USAGE (64)' + The abbreviated usage will be printed to 'stdout' and the program + will exit with a zero status code. 'EX_USAGE' may or may not be + 64. If your system provides '/usr/include/sysexits.h' that has a + different value, then that value will be used. + +'any other value' + The abbreviated usage will be printed to stderr and the program + will exit with the provided status code. + + +File: autogen.info, Node: VALUE_OPT_name, Next: VERSION, Prev: USAGE, Up: AutoOpts API + +7.6.26 VALUE_OPT_name - Option Flag Value +----------------------------------------- + +This is a #define for the flag character used to specify an option on +the command line. If 'value' was not specified for the option, then it +is a unique number associated with the option. 'option value' refers to +this value, 'option argument' refers to the (optional) argument to the +option. + + switch (WHICH_OPT_OTHER_OPT) { + case VALUE_OPT_NAME: + this-option-was-really-opt-name; + case VALUE_OPT_OTHER_OPT: + this-option-was-really-other-opt; + } + + +File: autogen.info, Node: VERSION, Next: WHICH_IDX_name, Prev: VALUE_OPT_name, Up: AutoOpts API + +7.6.27 VERSION - Version and Full Version +----------------------------------------- + +If the 'version' attribute is defined for the program, then a +stringified version will be #defined as PROGRAM_VERSION and +PROGRAM_FULL_VERSION. PROGRAM_FULL_VERSION is used for printing the +program version in response to the version option. The version option +is automatically supplied in response to this attribute, too. + + You may access PROGRAM_VERSION via 'programOptions.pzFullVersion'. + + +File: autogen.info, Node: WHICH_IDX_name, Next: WHICH_OPT_name, Prev: VERSION, Up: AutoOpts API + +7.6.28 WHICH_IDX_name - Which Equivalenced Index +------------------------------------------------ + +This macro gets emitted only for equivalenced-to options. It is used to +obtain the index for the one of the several equivalence class members +set the equivalenced-to option. + + switch (WHICH_IDX_OTHER_OPT) { + case INDEX_OPT_NAME: + this-option-was-really-opt-name; + case INDEX_OPT_OTHER_OPT: + this-option-was-really-other-opt; + } + + +File: autogen.info, Node: WHICH_OPT_name, Next: teOptIndex, Prev: WHICH_IDX_name, Up: AutoOpts API + +7.6.29 WHICH_OPT_name - Which Equivalenced Option +------------------------------------------------- + +This macro gets emitted only for equivalenced-to options. It is used to +obtain the value code for the one of the several equivalence class +members set the equivalenced-to option. + + switch (WHICH_OPT_OTHER_OPT) { + case VALUE_OPT_NAME: + this-option-was-really-opt-name; + case VALUE_OPT_OTHER_OPT: + this-option-was-really-other-opt; + } + + +File: autogen.info, Node: teOptIndex, Next: OPTIONS_STRUCT_VERSION, Prev: WHICH_OPT_name, Up: AutoOpts API + +7.6.30 teOptIndex - Option Index and Enumeration +------------------------------------------------ + +This enum defines the complete set of options, both user specified and +automatically provided. This can be used, for example, to distinguish +which of the equivalenced options was actually used. + + switch (pOptDesc->optActualIndex) { + case INDEX_OPT_FIRST: + stuff; + case INDEX_OPT_DIFFERENT: + different-stuff; + default: + unknown-things; + } + + +File: autogen.info, Node: OPTIONS_STRUCT_VERSION, Next: libopts procedures, Prev: teOptIndex, Up: AutoOpts API + +7.6.31 OPTIONS_STRUCT_VERSION - active version +---------------------------------------------- + +You will not actually need to reference this value, but you need to be +aware that it is there. It is the first value in the option descriptor +that you pass to 'optionProcess'. It contains a magic number and +version information. Normally, you should be able to work with a more +recent option library than the one you compiled with. However, if the +library is changed incompatibly, then the library will detect the out of +date magic marker, explain the difficulty and exit. You will then need +to rebuild and recompile your option definitions. This has rarely been +necessary. + + +File: autogen.info, Node: libopts procedures, Prev: OPTIONS_STRUCT_VERSION, Up: AutoOpts API + +7.6.32 libopts External Procedures +---------------------------------- + +These are the routines that libopts users may call directly from their +code. There are several other routines that can be called by code +generated by the libopts option templates, but they are not to be called +from any other user code. The 'options.h' header is fairly clear about +this, too. + +* Menu: + +* libopts-ao_string_tokenize:: ao_string_tokenize +* libopts-configFileLoad:: configFileLoad +* libopts-optionFileLoad:: optionFileLoad +* libopts-optionFindNextValue:: optionFindNextValue +* libopts-optionFindValue:: optionFindValue +* libopts-optionFree:: optionFree +* libopts-optionGetValue:: optionGetValue +* libopts-optionLoadLine:: optionLoadLine +* libopts-optionMemberList:: optionMemberList +* libopts-optionNextValue:: optionNextValue +* libopts-optionOnlyUsage:: optionOnlyUsage +* libopts-optionPrintVersion:: optionPrintVersion +* libopts-optionPrintVersionAndReturn:: optionPrintVersionAndReturn +* libopts-optionProcess:: optionProcess +* libopts-optionRestore:: optionRestore +* libopts-optionSaveFile:: optionSaveFile +* libopts-optionSaveState:: optionSaveState +* libopts-optionUnloadNested:: optionUnloadNested +* libopts-optionVersion:: optionVersion +* libopts-strequate:: strequate +* libopts-streqvcmp:: streqvcmp +* libopts-streqvmap:: streqvmap +* libopts-strneqvcmp:: strneqvcmp +* libopts-strtransform:: strtransform + + This subsection was automatically generated by AutoGen using +extracted information and the aginfo3.tpl template. + + +File: autogen.info, Node: libopts-ao_string_tokenize, Next: libopts-configFileLoad, Up: libopts procedures + +7.6.32.1 ao_string_tokenize +........................... + +tokenize an input string + +Usage: + token_list_t * res = ao_string_tokenize( string ); +Where the arguments are: + Name Type Description + --- --- --------- + string 'char const string to be tokenized + *' + returns token_list_t pointer to a structure that lists each + * token + + This function will convert one input string into a list of strings. +The list of strings is derived by separating the input based on white +space separation. However, if the input contains either single or +double quote characters, then the text after that character up to a +matching quote will become the string in the list. + + The returned pointer should be deallocated with 'free(3C)' when are +done using the data. The data are placed in a single block of allocated +memory. Do not deallocate individual token/strings. + + The structure pointed to will contain at least these two fields: +'tkn_ct' + The number of tokens found in the input string. +'tok_list' + An array of 'tkn_ct + 1' pointers to substring tokens, with the + last pointer set to NULL. + + There are two types of quoted strings: single quoted (''') and double +quoted ('"'). Singly quoted strings are fairly raw in that escape +characters ('\\') are simply another character, except when preceding +the following characters: + \\ double backslashes reduce to one + ' incorporates the single quote into the string + \n suppresses both the backslash and newline character + + Double quote strings are formed according to the rules of string +constants in ANSI-C programs. + + NULL is returned and 'errno' will be set to indicate the problem: + * 'EINVAL' - There was an unterminated quoted string. + * 'ENOENT' - The input string was empty. + * 'ENOMEM' - There is not enough memory. + + +File: autogen.info, Node: libopts-configFileLoad, Next: libopts-optionFileLoad, Prev: libopts-ao_string_tokenize, Up: libopts procedures + +7.6.32.2 configFileLoad +....................... + +parse a configuration file + +Usage: + const tOptionValue * res = configFileLoad( fname ); +Where the arguments are: + Name Type Description + --- --- --------- + fname 'char const the file to load + *' + returns const An allocated, compound value structure + tOptionValue + * + + This routine will load a named configuration file and parse the text +as a hierarchically valued option. The option descriptor created from +an option definition file is not used via this interface. The returned +value is "named" with the input file name and is of type +"'OPARG_TYPE_HIERARCHY'". It may be used in calls to +'optionGetValue()', 'optionNextValue()' and 'optionUnloadNested()'. + + If the file cannot be loaded or processed, 'NULL' is returned and +ERRNO is set. It may be set by a call to either 'open(2)' 'mmap(2)' or +other file system calls, or it may be: + * 'ENOENT' - the file was not found. + * 'ENOMSG' - the file was empty. + * 'EINVAL' - the file contents are invalid - not properly formed. + * 'ENOMEM' - not enough memory to allocate the needed structures. + + +File: autogen.info, Node: libopts-optionFileLoad, Next: libopts-optionFindNextValue, Prev: libopts-configFileLoad, Up: libopts procedures + +7.6.32.3 optionFileLoad +....................... + +Load the locatable config files, in order + +Usage: + int res = optionFileLoad( opts, prog ); +Where the arguments are: + Name Type Description + --- --- --------- + opts 'tOptions *' program options descriptor + + prog 'char const program name + *' + returns int 0 -> SUCCESS, -1 -> FAILURE + + This function looks in all the specified directories for a +configuration file ("rc" file or "ini" file) and processes any found +twice. The first time through, they are processed in reverse order +(last file first). At that time, only "immediate action" configurables +are processed. For example, if the last named file specifies not +processing any more configuration files, then no more configuration +files will be processed. Such an option in the *first* named directory +will have no effect. + + Once the immediate action configurables have been handled, then the +directories are handled in normal, forward order. In that way, later +config files can override the settings of earlier config files. + + See the AutoOpts documentation for a thorough discussion of the +config file format. + + Configuration files not found or not decipherable are simply ignored. + + Returns the value, "-1" if the program options descriptor is out of +date or indecipherable. Otherwise, the value "0" will always be +returned. + + +File: autogen.info, Node: libopts-optionFindNextValue, Next: libopts-optionFindValue, Prev: libopts-optionFileLoad, Up: libopts procedures + +7.6.32.4 optionFindNextValue +............................ + +find a hierarcicaly valued option instance + +Usage: + const tOptionValue * res = optionFindNextValue( odesc, pPrevVal, name, value ); +Where the arguments are: + Name Type Description + --- --- --------- + odesc 'const an option with a nested arg type + tOptDesc *' + pPrevVal 'const the last entry + tOptionValue + *' + name 'char const name of value to find + *' + value 'char const the matching value + *' + returns const a compound value structure + tOptionValue + * + + This routine will find the next entry in a nested value option or +configurable. It will search through the list and return the next entry +that matches the criteria. + + The returned result is NULL and errno is set: + * 'EINVAL' - the 'pOptValue' does not point to a valid hierarchical + option value. + * 'ENOENT' - no entry matched the given name. + + +File: autogen.info, Node: libopts-optionFindValue, Next: libopts-optionFree, Prev: libopts-optionFindNextValue, Up: libopts procedures + +7.6.32.5 optionFindValue +........................ + +find a hierarcicaly valued option instance + +Usage: + const tOptionValue * res = optionFindValue( odesc, name, val ); +Where the arguments are: + Name Type Description + --- --- --------- + odesc 'const an option with a nested arg type + tOptDesc *' + name 'char const name of value to find + *' + val 'char const the matching value + *' + returns const a compound value structure + tOptionValue + * + + This routine will find an entry in a nested value option or +configurable. It will search through the list and return a matching +entry. + + The returned result is NULL and errno is set: + * 'EINVAL' - the 'pOptValue' does not point to a valid hierarchical + option value. + * 'ENOENT' - no entry matched the given name. + + +File: autogen.info, Node: libopts-optionFree, Next: libopts-optionGetValue, Prev: libopts-optionFindValue, Up: libopts procedures + +7.6.32.6 optionFree +................... + +free allocated option processing memory + +Usage: + optionFree( pOpts ); +Where the arguments are: + Name Type Description + --- --- --------- + pOpts 'tOptions *' program options descriptor + + AutoOpts sometimes allocates memory and puts pointers to it in the +option state structures. This routine deallocates all such memory. + + As long as memory has not been corrupted, this routine is always +successful. + + +File: autogen.info, Node: libopts-optionGetValue, Next: libopts-optionLoadLine, Prev: libopts-optionFree, Up: libopts procedures + +7.6.32.7 optionGetValue +....................... + +get a specific value from a hierarcical list + +Usage: + const tOptionValue * res = optionGetValue( pOptValue, valueName ); +Where the arguments are: + Name Type Description + --- --- --------- + pOptValue 'const a hierarchcal value + tOptionValue + *' + valueName 'char const name of value to get + *' + returns const a compound value structure + tOptionValue + * + + This routine will find an entry in a nested value option or +configurable. If "valueName" is NULL, then the first entry is returned. +Otherwise, the first entry with a name that exactly matches the argument +will be returned. If there is no matching value, NULL is returned and +errno is set to ENOENT. If the provided option value is not a +hierarchical value, NULL is also returned and errno is set to EINVAL. + + The returned result is NULL and errno is set: + * 'EINVAL' - the 'pOptValue' does not point to a valid hierarchical + option value. + * 'ENOENT' - no entry matched the given name. + + +File: autogen.info, Node: libopts-optionLoadLine, Next: libopts-optionMemberList, Prev: libopts-optionGetValue, Up: libopts procedures + +7.6.32.8 optionLoadLine +....................... + +process a string for an option name and value + +Usage: + optionLoadLine( opts, line ); +Where the arguments are: + Name Type Description + --- --- --------- + opts 'tOptions *' program options descriptor + + line 'char const NUL-terminated text + *' + + This is a client program callable routine for setting options from, +for example, the contents of a file that they read in. Only one option +may appear in the text. It will be treated as a normal (non-preset) +option. + + When passed a pointer to the option struct and a string, it will find +the option named by the first token on the string and set the option +argument to the remainder of the string. The caller must NUL terminate +the string. The caller need not skip over any introductory hyphens. +Any embedded new lines will be included in the option argument. If the +input looks like one or more quoted strings, then the input will be +"cooked". The "cooking" is identical to the string formation used in +AutoGen definition files (*note basic expression::), except that you may +not use backquotes. + + Invalid options are silently ignored. Invalid option arguments will +cause a warning to print, but the function should return. + + +File: autogen.info, Node: libopts-optionMemberList, Next: libopts-optionNextValue, Prev: libopts-optionLoadLine, Up: libopts procedures + +7.6.32.9 optionMemberList +......................... + +Get the list of members of a bit mask set + +Usage: + char * res = optionMemberList( od ); +Where the arguments are: + Name Type Description + --- --- --------- + od 'tOptDesc *' the set membership option description + returns char * the names of the set bits + + This converts the OPT_VALUE_name mask value to a allocated string. +It is the caller's responsibility to free the string. + + +File: autogen.info, Node: libopts-optionNextValue, Next: libopts-optionOnlyUsage, Prev: libopts-optionMemberList, Up: libopts procedures + +7.6.32.10 optionNextValue +......................... + +get the next value from a hierarchical list + +Usage: + const tOptionValue * res = optionNextValue( pOptValue, pOldValue ); +Where the arguments are: + Name Type Description + --- --- --------- + pOptValue 'const a hierarchcal list value + tOptionValue + *' + pOldValue 'const a value from this list + tOptionValue + *' + returns const a compound value structure + tOptionValue + * + + This routine will return the next entry after the entry passed in. +At the end of the list, NULL will be returned. If the entry is not +found on the list, NULL will be returned and "ERRNO" will be set to +EINVAL. The "POLDVALUE" must have been gotten from a prior call to this +routine or to "'opitonGetValue()'". + + The returned result is NULL and errno is set: + * 'EINVAL' - the 'pOptValue' does not point to a valid hierarchical + option value or 'pOldValue' does not point to a member of that + option value. + * 'ENOENT' - the supplied 'pOldValue' pointed to the last entry. + + +File: autogen.info, Node: libopts-optionOnlyUsage, Next: libopts-optionPrintVersion, Prev: libopts-optionNextValue, Up: libopts procedures + +7.6.32.11 optionOnlyUsage +......................... + +Print usage text for just the options + +Usage: + optionOnlyUsage( pOpts, ex_code ); +Where the arguments are: + Name Type Description + --- --- --------- + pOpts 'tOptions *' program options descriptor + + ex_code 'int' exit code for calling exit(3) + + This routine will print only the usage for each option. This +function may be used when the emitted usage must incorporate information +not available to AutoOpts. + + +File: autogen.info, Node: libopts-optionPrintVersion, Next: libopts-optionPrintVersionAndReturn, Prev: libopts-optionOnlyUsage, Up: libopts procedures + +7.6.32.12 optionPrintVersion +............................ + +Print the program version + +Usage: + optionPrintVersion( opts, od ); +Where the arguments are: + Name Type Description + --- --- --------- + opts 'tOptions *' program options descriptor + + od 'tOptDesc *' the descriptor for this arg + + This routine will print the version to stdout. + + +File: autogen.info, Node: libopts-optionPrintVersionAndReturn, Next: libopts-optionProcess, Prev: libopts-optionPrintVersion, Up: libopts procedures + +7.6.32.13 optionPrintVersionAndReturn +..................................... + +Print the program version + +Usage: + optionPrintVersionAndReturn( opts, od ); +Where the arguments are: + Name Type Description + --- --- --------- + opts 'tOptions *' program options descriptor + + od 'tOptDesc *' the descriptor for this arg + + This routine will print the version to stdout and return instead of +exiting. Please see the source for the 'print_ver' funtion for details +on selecting how verbose to be after this function returns. + + +File: autogen.info, Node: libopts-optionProcess, Next: libopts-optionRestore, Prev: libopts-optionPrintVersionAndReturn, Up: libopts procedures + +7.6.32.14 optionProcess +....................... + +this is the main option processing routine + +Usage: + int res = optionProcess( opts, a_ct, a_v ); +Where the arguments are: + Name Type Description + --- --- --------- + opts 'tOptions *' program options descriptor + + a_ct 'int' program arg count + + a_v 'char **' program arg vector + returns int the count of the arguments processed + + This is the main entry point for processing options. It is intended +that this procedure be called once at the beginning of the execution of +a program. Depending on options selected earlier, it is sometimes +necessary to stop and restart option processing, or to select completely +different sets of options. This can be done easily, but you generally +do not want to do this. + + The number of arguments processed always includes the program name. +If one of the arguments is "-", then it is counted and the processing +stops. If an error was encountered and errors are to be tolerated, then +the returned value is the index of the argument causing the error. A +hyphen by itself ("-") will also cause processing to stop and will _not_ +be counted among the processed arguments. A hyphen by itself is treated +as an operand. Encountering an operand stops option processing. + + Errors will cause diagnostics to be printed. 'exit(3)' may or may +not be called. It depends upon whether or not the options were +generated with the "allow-errors" attribute, or if the ERRSKIP_OPTERR or +ERRSTOP_OPTERR macros were invoked. + + +File: autogen.info, Node: libopts-optionRestore, Next: libopts-optionSaveFile, Prev: libopts-optionProcess, Up: libopts procedures + +7.6.32.15 optionRestore +....................... + +restore option state from memory copy + +Usage: + optionRestore( pOpts ); +Where the arguments are: + Name Type Description + --- --- --------- + pOpts 'tOptions *' program options descriptor + + Copy back the option state from saved memory. The allocated memory +is left intact, so this routine can be called repeatedly without having +to call optionSaveState again. If you are restoring a state that was +saved before the first call to optionProcess(3AO), then you may change +the contents of the argc/argv parameters to optionProcess. + + If you have not called 'optionSaveState' before, a diagnostic is +printed to 'stderr' and exit is called. + + +File: autogen.info, Node: libopts-optionSaveFile, Next: libopts-optionSaveState, Prev: libopts-optionRestore, Up: libopts procedures + +7.6.32.16 optionSaveFile +........................ + +saves the option state to a file + +Usage: + optionSaveFile( opts ); +Where the arguments are: + Name Type Description + --- --- --------- + opts 'tOptions *' program options descriptor + + This routine will save the state of option processing to a file. The +name of that file can be specified with the argument to the +'--save-opts' option, or by appending the 'rcfile' attribute to the last +'homerc' attribute. If no 'rcfile' attribute was specified, it will +default to '.programnamerc'. If you wish to specify another file, you +should invoke the 'SET_OPT_SAVE_OPTS(filename)' macro. + + The recommend usage is as follows: + optionProcess(&progOptions, argc, argv); + if (i_want_a_non_standard_place_for_this) + SET_OPT_SAVE_OPTS("myfilename"); + optionSaveFile(&progOptions); + + If no 'homerc' file was specified, this routine will silently return +and do nothing. If the output file cannot be created or updated, a +message will be printed to 'stderr' and the routine will return. + + +File: autogen.info, Node: libopts-optionSaveState, Next: libopts-optionUnloadNested, Prev: libopts-optionSaveFile, Up: libopts procedures + +7.6.32.17 optionSaveState +......................... + +saves the option state to memory + +Usage: + optionSaveState( pOpts ); +Where the arguments are: + Name Type Description + --- --- --------- + pOpts 'tOptions *' program options descriptor + + This routine will allocate enough memory to save the current option +processing state. If this routine has been called before, that memory +will be reused. You may only save one copy of the option state. This +routine may be called before optionProcess(3AO). If you do call it +before the first call to optionProcess, then you may also change the +contents of argc/argv after you call optionRestore(3AO) + + In fact, more strongly put: it is safest to only use this function +before having processed any options. In particular, the saving and +restoring of stacked string arguments and hierarchical values is +disabled. The values are not saved. + + If it fails to allocate the memory, it will print a message to stderr +and exit. Otherwise, it will always succeed. + + +File: autogen.info, Node: libopts-optionUnloadNested, Next: libopts-optionVersion, Prev: libopts-optionSaveState, Up: libopts procedures + +7.6.32.18 optionUnloadNested +............................ + +Deallocate the memory for a nested value + +Usage: + optionUnloadNested( pOptVal ); +Where the arguments are: + Name Type Description + --- --- --------- + pOptVal 'tOptionValue the hierarchical value + const *' + + A nested value needs to be deallocated. The pointer passed in should +have been gotten from a call to 'configFileLoad()' (See *note +libopts-configFileLoad::). + + +File: autogen.info, Node: libopts-optionVersion, Next: libopts-strequate, Prev: libopts-optionUnloadNested, Up: libopts procedures + +7.6.32.19 optionVersion +....................... + +return the compiled AutoOpts version number + +Usage: + char const * res = optionVersion(); +Where the arguments are: + Name Type Description + --- --- --------- + returns char const * the version string in constant memory + + Returns the full version string compiled into the library. The +returned string cannot be modified. + + +File: autogen.info, Node: libopts-strequate, Next: libopts-streqvcmp, Prev: libopts-optionVersion, Up: libopts procedures + +7.6.32.20 strequate +................... + +map a list of characters to the same value + +Usage: + strequate( ch_list ); +Where the arguments are: + Name Type Description + --- --- --------- + ch_list 'char const characters to equivalence + *' + + Each character in the input string get mapped to the first character +in the string. This function name is mapped to option_strequate so as +to not conflict with the POSIX name space. + + none. + + +File: autogen.info, Node: libopts-streqvcmp, Next: libopts-streqvmap, Prev: libopts-strequate, Up: libopts procedures + +7.6.32.21 streqvcmp +................... + +compare two strings with an equivalence mapping + +Usage: + int res = streqvcmp( str1, str2 ); +Where the arguments are: + Name Type Description + --- --- --------- + str1 'char const first string + *' + str2 'char const second string + *' + returns int the difference between two differing + characters + + Using a character mapping, two strings are compared for +"equivalence". Each input character is mapped to a comparison character +and the mapped-to characters are compared for the two NUL terminated +input strings. This function name is mapped to option_streqvcmp so as +to not conflict with the POSIX name space. + + none checked. Caller responsible for seg faults. + + +File: autogen.info, Node: libopts-streqvmap, Next: libopts-strneqvcmp, Prev: libopts-streqvcmp, Up: libopts procedures + +7.6.32.22 streqvmap +................... + +Set the character mappings for the streqv functions + +Usage: + streqvmap( from, to, ct ); +Where the arguments are: + Name Type Description + --- --- --------- + from 'char' Input character + + to 'char' Mapped-to character + + ct 'int' compare length + + Set the character mapping. If the count ('ct') is set to zero, then +the map is cleared by setting all entries in the map to their index +value. Otherwise, the "'From'" character is mapped to the "'To'" +character. If 'ct' is greater than 1, then 'From' and 'To' are +incremented and the process repeated until 'ct' entries have been set. +For example, + streqvmap('a', 'A', 26); +will alter the mapping so that all English lower case letters will map +to upper case. + + This function name is mapped to option_streqvmap so as to not +conflict with the POSIX name space. + + none. + + +File: autogen.info, Node: libopts-strneqvcmp, Next: libopts-strtransform, Prev: libopts-streqvmap, Up: libopts procedures + +7.6.32.23 strneqvcmp +.................... + +compare two strings with an equivalence mapping + +Usage: + int res = strneqvcmp( str1, str2, ct ); +Where the arguments are: + Name Type Description + --- --- --------- + str1 'char const first string + *' + str2 'char const second string + *' + ct 'int' compare length + returns int the difference between two differing + characters + + Using a character mapping, two strings are compared for +"equivalence". Each input character is mapped to a comparison character +and the mapped-to characters are compared for the two NUL terminated +input strings. The comparison is limited to 'ct' bytes. This function +name is mapped to option_strneqvcmp so as to not conflict with the POSIX +name space. + + none checked. Caller responsible for seg faults. + + +File: autogen.info, Node: libopts-strtransform, Prev: libopts-strneqvcmp, Up: libopts procedures + +7.6.32.24 strtransform +...................... + +convert a string into its mapped-to value + +Usage: + strtransform( dest, src ); +Where the arguments are: + Name Type Description + --- --- --------- + dest 'char *' output string + + src 'char const input string + *' + + Each character in the input string is mapped and the mapped-to +character is put into the output. This function name is mapped to +option_strtransform so as to not conflict with the POSIX name space. + + The source and destination may be the same. + + none. + + +File: autogen.info, Node: Multi-Threading, Next: option descriptor, Prev: AutoOpts API, Up: AutoOpts + +7.7 Multi-Threading +=================== + +AutoOpts was designed to configure a program for running. This +generally happens before much real work has been started. Consequently, +it is expected to be run before multi-threaded applications have started +multiple threads. However, this is not always the case. Some +applications may need to reset and reload their running configuration, +and some may use 'SET_OPT_xxx()' macros during processing. If you need +to dynamically change your option configuration in your multi-threaded +application, it is your responsibility to prevent all threads from +accessing the option configuration state, except the one altering the +configuration. + + The various accessor macros ('HAVE_OPT()', etc.) do not modify state +and are safe to use in a multi-threaded application. It is safe as long +as no other thread is concurrently modifying state, of course. + + +File: autogen.info, Node: option descriptor, Next: Using AutoOpts, Prev: Multi-Threading, Up: AutoOpts + +7.8 Option Descriptor File +========================== + +This is the module that is to be compiled and linked with your program. +It contains internal data and procedures subject to change. Basically, +it contains a single global data structure containing all the +information provided in the option definitions, plus a number of static +strings and any callout procedures that are specified or required. You +should never have need for looking at this, except, perhaps, to examine +the code generated for implementing the 'flag-code' construct. + + +File: autogen.info, Node: Using AutoOpts, Next: Presetting Options, Prev: option descriptor, Up: AutoOpts + +7.9 Using AutoOpts +================== + +There are actually several levels of 'using' autoopts. Which you choose +depends upon how you plan to distribute (or not) your application. + +* Menu: + +* local use:: local-only use +* binary not installed:: binary distro, AutoOpts not installed +* binary pre-installed:: binary distro, AutoOpts pre-installed +* source pre-installed:: source distro, AutoOpts pre-installed +* source not installed:: source distro, AutoOpts not installed + + +File: autogen.info, Node: local use, Next: binary not installed, Up: Using AutoOpts + +7.9.1 local-only use +-------------------- + +To use AutoOpts in your application where you do not have to worry about +distribution issues, your issues are simple and few. + + * Create a file 'myopts.def', according to the documentation above. + It is probably easiest to start with the example in *note Quick + Start:: and edit it into the form you need. + + * Run AutoGen to create the option interface file ('myopts.h') and + the option descriptor code ('myopts.c'): + + autogen myopts.def + + * In all your source files where you need to refer to option state, + '#include "myopts.h"'. + * In your main routine, code something along the lines of: + + #define ARGC_MIN some-lower-limit + #define ARGC_MAX some-upper-limit + main( int argc, char** argv ) + { + { + int arg_ct = optionProcess( &myprogOptions, argc, argv ); + argc -= arg_ct; + if ((argc < ARGC_MIN) || (argc > ARGC_MAX)) { + fprintf( stderr, "%s ERROR: remaining args (%d) " + "out of range\n", myprogOptions.pzProgName, + argc ); + + USAGE( EXIT_FAILURE ); + } + argv += arg_ct; + } + if (HAVE_OPT(OPTN_NAME)) + respond_to_optn_name(); + ... + } + + * Compile 'myopts.c' and link your program with the following + additional arguments: + + `autoopts-config cflags ldflags` myopts.c + + +File: autogen.info, Node: binary not installed, Next: binary pre-installed, Prev: local use, Up: Using AutoOpts + +7.9.2 binary distro, AutoOpts not installed +------------------------------------------- + +If you will be distributing (or copying) your project to a system that +does not have AutoOpts installed, you will need to statically link the +AutoOpts library, 'libopts' into your program. Get the link information +with 'static-libs' instead of 'ldflags': + + `autoopts-config static-libs` + + +File: autogen.info, Node: binary pre-installed, Next: source pre-installed, Prev: binary not installed, Up: Using AutoOpts + +7.9.3 binary distro, AutoOpts pre-installed +------------------------------------------- + +If you will be distributing (or copying) your project to a system that +does have AutoOpts (or only 'libopts') installed, you will still need to +ensure that the library is findable at program load time, or you will +still have to statically link. The former can be accomplished by +linking your project with '--rpath' or by setting the 'LD_LIBRARY_PATH' +appropriately. Otherwise, *Note binary not installed::. + + +File: autogen.info, Node: source pre-installed, Next: source not installed, Prev: binary pre-installed, Up: Using AutoOpts + +7.9.4 source distro, AutoOpts pre-installed +------------------------------------------- + +If you will be distributing your project to a system that will build +your product but it may not be pre-installed with AutoOpts, you will +need to do some configuration checking before you start the build. +Assuming you are willing to fail the build if AutoOpts has not been +installed, you will still need to do a little work. + + AutoOpts is distributed with a configuration check M4 script, +'autoopts.m4'. It will add an 'autoconf' macro named, +'AG_PATH_AUTOOPTS'. Add this to your 'configure.ac' script and use the +following substitution values: + +'AUTOGEN' + the name of the autogen executable +'AUTOGEN_TPLIB' + the directory where AutoGen template library is stored +'AUTOOPTS_CFLAGS' + the compile time options needed to find the AutoOpts headers +'AUTOOPTS_LIBS' + the link options required to access the 'libopts' library + + +File: autogen.info, Node: source not installed, Prev: source pre-installed, Up: Using AutoOpts + +7.9.5 source distro, AutoOpts not installed +------------------------------------------- + +If you will be distributing your project to a system that will build +your product but it may not be pre-installed with AutoOpts, you may wish +to incorporate the sources for 'libopts' in your project. To do this, I +recommend reading the tear-off libopts library 'README' that you can +find in the 'pkg/libopts' directory. You can also examine an example +package (blocksort) that incorporates this tear off library in the +autogen distribution directory. There is also a web page that describes +what you need to do: + <http://autogen.sourceforge.net/blocksort.html> + + Alternatively, you can pull the 'libopts' library sources into a +build directory and build it for installation along with your package. +This can be done approximately as follows: + tar -xzvf `autoopts-config libsrc` + cd libopts-* + ./bootstrap + configure + make + make install + That will install the library, but not the headers or anything else. + + +File: autogen.info, Node: Presetting Options, Next: Config File Format, Prev: Using AutoOpts, Up: AutoOpts + +7.10 Configuring your program +============================= + +AutoOpts supports the notion of 'presetting' the value or state of an +option. The values may be obtained either from environment variables or +from configuration files ('rc' or 'ini' files). In order to take +advantage of this, the AutoOpts client program must specify these +features in the option descriptor file (*note program attributes::) with +the 'rcfile' or 'environrc' attributes. + +* Menu: + +* loading rcfile:: configuration file presets +* saving rcfile:: Saving the presets into a configuration file +* sample rcfile:: Creating a sample configuration file +* environrc:: environment variable presets +* config example:: Config file only example + + It is also possible to configure your program without using the +command line option parsing code. This is done by using only the +following four functions from the 'libopts' library: + +'configFileLoad' + (*note libopts-configFileLoad::) will parse the contents of a + config file and return a pointer to a structure representing the + hierarchical value. The values are sorted alphabetically by the + value name and all entries with the same name will retain their + original order. Insertion sort is used. + +'optionGetValue' + (*note libopts-optionGetValue::) will find the first value within + the hierarchy with a name that matches the name passed in. + +'optionNextValue' + (*note libopts-optionNextValue::) will return the next value that + follows the value passed in as an argument. If you wish to get all + the values for a particular name, you must take note when the name + changes. + +'optionUnloadNested' + (*note libopts-optionUnloadNested::). The pointer passed in must + be of type, 'OPARG_TYPE_HIERARCHY' (see the autoopts/options.h + header file). 'configFileLoad' will return a 'tOptionValue' + pointer of that type. This function will release all the + associated memory. 'AutoOpts' generated code uses this function + for its own needs. Client code should only call this function with + pointers gotten from 'configFileLoad'. + + +File: autogen.info, Node: loading rcfile, Next: saving rcfile, Up: Presetting Options + +7.10.1 configuration file presets +--------------------------------- + +Configuration files are enabled by specifying the program attribute +'homerc' (*note program attributes::). Any option not marked with the +'no-preset' attribute may appear in a configuration file. The files +loaded are selected both by the 'homerc' entries and, optionally, via a +command line option. The first component of the 'homerc' entry may be +an environment variable such as '$HOME', or it may also be '$$' (*two* +dollar sign characters) to specify the directory of the executable. For +example: + + homerc = "$$/../share/autogen"; + +will cause the AutoOpts library to look in the normal autogen datadir +relative to the current installation directory for autogen. + + The configuration files are processed in the order they are specified +by the 'homerc' attribute, so that each new file will normally override +the settings of the previous files. This may be overridden by marking +some options for 'immediate action' (*note Immediate Action::). Any +such options are acted upon in *reverse* order. The disabled +'load-opts' ('--no-load-opts') option, for example, is an immediate +action option. Its presence in the last 'homerc' file will prevent the +processing of any prior 'homerc' files because its effect is immediate. + + Configuration file processing can be completely suppressed by +specifying '--no-load-opts' on the command line, or +'PROGRAM_LOAD_OPTS=no' in the environment (if 'environrc' has been +specified). + + See the 'Configuration File Format' section (*note Config File +Format::) for details on the format of the file. + + +File: autogen.info, Node: saving rcfile, Next: sample rcfile, Prev: loading rcfile, Up: Presetting Options + +7.10.2 Saving the presets into a configuration file +--------------------------------------------------- + +When configuration files are enabled for an application, the user is +also provided with an automatically supplied '--save-opts' option. All +of the known option state will be written to either the specified output +file or, if it is not specified, then to the last specified 'homerc' +file. + + +File: autogen.info, Node: sample rcfile, Next: environrc, Prev: saving rcfile, Up: Presetting Options + +7.10.3 Creating a sample configuration file +------------------------------------------- + +AutoOpts is shipped with a template named, 'rc-sample.tpl'. If your +option definition file specifies the 'homerc' attribute, then you may +invoke 'autogen' thus: + + autogen -Trc-sample <your-option-def-file> + + This will, by default, produce a sample file named, +'sample-<prog-name>rc'. It will be named differently if you specify +your configuration (rc) file name with the 'rcfile' attribute. In that +case, the output file will be named, 'sample-<rcfile-name>'. It will +contain all of the program options not marked as 'no-preset'. It will +also include the text from the 'doc' attribute. + +Doing so with getdefs' option definitions yields this sample-getdefsrc +file. I tend to be wordy in my 'doc' attributes: + + # getdefs sample configuration file + ## This source file is copyrighted and licensed under the following terms: + # + # Copyright (C) 1999-2018 Bruce Korb, all rights reserved. + # This is free software. It is licensed for use, modification and + # redistribution under the terms of the GNU General Public License, + # version 3 or later <http://gnu.org/licenses/gpl.html> + # + # getdefs is free software: you can redistribute it and/or modify it + # under the terms of the GNU General Public License as published by the + # Free Software Foundation, either version 3 of the License, or + # (at your option) any later version. + # + # getdefs is distributed in the hope that it will be useful, but + # WITHOUT ANY WARRANTY; without even the implied warranty of + # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + # See the GNU General Public License for more details. + # + # You should have received a copy of the GNU General Public License along + # with this program. If not, see <http://www.gnu.org/licenses/>. + + # defs_to_get -- Regexp to look for after the "/*=" + # + # + # + # + # If you want definitions only from a particular category, or even + # with names matching particular patterns, then specify this regular + # expression for the text that must follow the @code{/*=}. + # Example: + # + #defs_to_get reg-ex + + # subblock -- subblock definition names + # + # + # + # + # This option is used to create shorthand entries for nested definitions. + # For example, with: + # @table @r + # @item using subblock thus + # @code{--subblock=arg=argname,type,null} + # @item and defining an @code{arg} thus + # @code{arg: this, char *} + # @item will then expand to: + # @code{arg = @{ argname = this; type = "char *"; @};} + # @end table + # The "this, char *" string is separated at the commas, with the + # white space removed. You may use characters other than commas by + # starting the value string with a punctuation character other than + # a single or double quote character. You may also omit intermediate + # values by placing the commas next to each other with no intervening + # white space. For example, "+mumble++yes+" will expand to: + # @* + # @code{arg = @{ argname = mumble; null = "yes"; @};}. + # Example: + # + #subblock sub-def + + # listattr -- attribute with list of values + # + # + # + # + # This option is used to create shorthand entries for definitions + # that generally appear several times. That is, they tend to be + # a list of values. For example, with: + # @* + # @code{listattr=foo} defined, the text: + # @* + # @code{foo: this, is, a, multi-list} will then expand to: + # @* + # @code{foo = 'this', 'is', 'a', 'multi-list';} + # @* + # The texts are separated by the commas, with the + # white space removed. You may use characters other than commas by + # starting the value string with a punctuation character other than + # a single or double quote character. + # Example: + # + #listattr def + + # ordering -- Alphabetize or use named file + # + # + # + # + # By default, ordering is alphabetical by the entry name. Use, + # @code{no-ordering} if order is unimportant. Use @code{ordering} + # with no argument to order without case sensitivity. Use + # @code{ordering=<file-name>} if chronological order is important. + # getdefs will maintain the text content of @code{file-name}. + # @code{file-name} need not exist. + # Example: + # + #ordering file-name + + # first_index -- The first index to apply to groups + # + # This configuration value takes an integer number as its argument. + # + # + # By default, the first occurrence of a named definition will have an + # index of zero. Sometimes, that needs to be a reserved value. Provide + # this option to specify a different starting point. + # Example: + # + #first_index 0 + + # filelist -- Insert source file names into defs + # + # + # + # + # Inserts the name of each input file into the output definitions. + # If no argument is supplied, the format will be: + # @example + # infile = '%s'; + # @end example + # If an argument is supplied, that string will be used for the entry + # name instead of @var{infile}. + # Example: + # + #filelist file + + # assign -- Global assignments + # + # + # + # + # The argument to each copy of this option will be inserted into + # the output definitions, with only a semicolon attached. + # Example: + # + #assign ag-def + + # common_assign -- Assignments common to all blocks + # + # + # + # + # The argument to each copy of this option will be inserted into + # each output definition, with only a semicolon attached. + # Example: + # + #common_assign ag-def + + # copy -- File(s) to copy into definitions + # + # + # + # + # The content of each file named by these options will be inserted into + # the output definitions. + # Example: + # + #copy file + + # srcfile -- Insert source file name into each def + # + # + # + # + # Inserts the name of the input file where a definition was found + # into the output definition. + # If no argument is supplied, the format will be: + # @example + # srcfile = '%s'; + # @end example + # If an argument is supplied, that string will be used for the entry + # name instead of @var{srcfile}. + # Example: + # + #srcfile file + + # linenum -- Insert source line number into each def + # + # + # + # + # Inserts the line number in the input file where a definition + # was found into the output definition. + # If no argument is supplied, the format will be: + # @example + # linenum = '%s'; + # @end example + # If an argument is supplied, that string will be used for the entry + # name instead of @var{linenum}. + # Example: + # + #linenum def-name + + # input -- Input file to search for defs + # + # + # + # + # All files that are to be searched for definitions must be named on + # the command line or read from @code{stdin}. If there is only one + # @code{input} option and it is the string, "-", then the input file + # list is read from @code{stdin}. If a command line argument is not + # an option name and does not contain an assignment operator + # (@code{=}), then it defaults to being an input file name. + # At least one input file must be specified. + # Example: + # + #input src-file + + # output -- Output file to open + # + # + # + # + # If you are not sending the output to an AutoGen process, + # you may name an output file instead. + # Example: + # + #output file + + # autogen -- Invoke AutoGen with defs + # + # + # + # + # This is the default output mode. Specifying @code{no-autogen} is + # equivalent to @code{output=-}. If you supply an argument to this + # option, that program will be started as if it were AutoGen and + # its standard in will be set to the output definitions of this program. + # Example: + # + #autogen ag-cmd + + # template -- Template Name + # + # + # + # + # Specifies the template name to be used for generating the final output. + # Example: + # + #template file + + # agarg -- AutoGen Argument + # + # + # + # + # This is a pass-through argument. It allows you to specify any + # arbitrary argument to be passed to AutoGen. + # Example: + # + #agarg ag-opt + + # base_name -- Base name for output file(s) + # + # + # + # + # When output is going to AutoGen, a base name must either be supplied + # or derived. If this option is not supplied, then it is taken from + # the @code{template} option. If that is not provided either, then + # it is set to the base name of the current directory. + # Example: + # + #base_name name + + +File: autogen.info, Node: environrc, Next: config example, Prev: sample rcfile, Up: Presetting Options + +7.10.4 environment variable presets +----------------------------------- + +If the AutoOpts client program specifies 'environrc' in its option +descriptor file, then environment variables will be used for presetting +option state. Variables will be looked for that are named, +'PROGRAM_OPTNAME' and 'PROGRAM'. 'PROGRAM' is the upper cased 'C-name' +of the program, and OPTNAME is the upper cased 'C-name' of a specific +option. (The 'C-name's are the regular names with all special +characters converted to underscores ('_').) + + Option specific environment variables are processed after (and thus +take precedence over) the contents of the 'PROGRAM' environment +variable. The option argument string for these options takes on the +string value gotten from the environment. Consequently, you can only +have one instance of the OPTNAME. + + If a particular option may be disabled, then its disabled state is +indicated by setting the 'PROGRAM_OPTNAME' value to the disablement +prefix. So, for example, if the disablement prefix were 'dont', then +you can disable the 'optname' option by setting the 'PROGRAM_OPTNAME'' +environment variable to 'dont'. *Note Common Attributes::. + + The 'PROGRAM' environment string is tokenized and parsed much like a +command line. Doubly quoted strings have backslash escapes processed +the same way they are processed in C program constant strings. Singly +quoted strings are pretty raw in that backslashes are honored before +other backslashes, apostrophes, newlines and cr/newline pairs. The +options must be introduced with hyphens in the same way as the command +line. + + Note that not all options may be preset. Options that are specified +with the 'no-preset' attribute and the '--help', '--more-help', and +'--save-opts' auto-supported options may not be preset. + + +File: autogen.info, Node: config example, Prev: environrc, Up: Presetting Options + +7.10.5 Config file only example +------------------------------- + +If for some reason it is difficult or unworkable to integrate +configuration file processing with command line option parsing, the +'libopts' (*note libopts procedures::) library can still be used to +process configuration files. Below is a Hello, World! greeting program +that tries to load a configuration file 'hello.conf' to see if it should +use an alternate greeting or to personalize the salutation. + #include <config.h> + #include <sys/types.h> + #include <stdio.h> + #include <pwd.h> + #include <string.h> + #ifdef HAVE_UNISTD_H + #include <unistd.h> + #endif + #include <autoopts/options.h> + int main(int argc, char ** argv) { + char const * greeting = "Hello"; + char const * greeted = "World"; + tOptionValue const * pOV = configFileLoad("hello.conf"); + + if (pOV != NULL) { + const tOptionValue* pGetV = optionGetValue(pOV, "greeting"); + + if ( (pGetV != NULL) + && (pGetV->valType == OPARG_TYPE_STRING)) + greeting = strdup(pGetV->v.strVal); + + pGetV = optionGetValue(pOV, "personalize"); + if (pGetV != NULL) { + struct passwd * pwe = getpwuid(getuid()); + if (pwe != NULL) + greeted = strdup(pwe->pw_gecos); + } + + optionUnloadNested(pOV); /* deallocate config data */ + } + printf("%s, %s!\n", greeting, greeted); + return 0; + } + +With that text in a file named "hello.c", this short script: + + cc -o hello hello.c `autoopts-config cflags ldflags` + ./hello + echo 'greeting Buzz off' > hello.conf + ./hello + echo personalize > hello.conf + ./hello + +will produce the following output: + + Hello, World! + Buzz off, World! + Hello, Bruce Korb,,,! + + +File: autogen.info, Node: Config File Format, Next: shell options, Prev: Presetting Options, Up: AutoOpts + +7.11 Configuration File Format +============================== + +The configuration file is designed to associate names and values, much +like an AutoGen Definition File (*note Definitions File::). +Unfortunately, the file formats are different. Specifically, AutoGen +Definitions provide for simpler methods for the precise control of a +value string and provides for dynamically computed content. +Configuration files have some established traditions in their layout. +So, they are different, even though they do both allow for a single name +to be associated with multiple values and they both allow for +hierarchical values. + +* Menu: + +* config name/string-value:: assigning a string value to a configurable +* config integer-values:: integer values +* config nested-values:: hierarchical values +* config directives:: configuration file directives +* config comments:: comments in the configuration file + + +File: autogen.info, Node: config name/string-value, Next: config integer-values, Up: Config File Format + +7.11.1 assigning a string value to a configurable +------------------------------------------------- + +The basic syntax is a name followed by a value on a single line. They +are separated from each other by either white space, a colon (':') or an +equal sign ('='). The colon or equal sign may optionally be surrounded +by additional white space. If more than one value line is needed, a +backslash ('\') may be used to continue the value. The backslash (but +not the newline) will be erased. Leading and trailing white space is +always stripped from the value. + + Fundamentally, it looks like this: + + name value for that name + name = another \ + multi-line value \ + for that name. + name: a *third* value for name + + If you need more control over the content of the value, you may +enclose the value in XML style brackets: + <name>value </name> +Within these brackets you need not (must not) continue the value data +with backslashes. You may also select the string formation rules to +use, just add the attribute after the name, thus: '<name keep>'. + +'keep' + This mode will keep all text between the brackets and not strip any + white space. +'uncooked' + This mode strips leading and trailing white space, but not do any + quote processing. This is the default and need not be specified. +'cooked' + The text is trimmed of leading and trailing white space and XML + encodings are processed. These encodings are slightly expanded + over the XML specification. They are specified with an ampersand + followed by a value name or numeric value and then a semicolon: + + 'amp' + 'lt' + 'gt' + 'quot' + 'apos' + '#dd' + '#xHH' + + These are all per fairly standad HTML and/or XML encodings. + Additionally: + + 'bs' + The ASCII back space character. + 'ff' + The ASCII form feed character. + 'ht' + The ASCII horizontal (normal) tab character. + 'cr' + The ASCII carriage return character. + 'vt' + The ASCII vertical tab character. + 'bel' + The ASCII alarm bell character. + 'nl' + The ASCII new line character. + 'space' + The ASCII space character. Normally not necessary, but if you + want to preserve leading or trailing space characters, then + use this. + + And here is an example of an XML-styled value: + + <name cooked> + This is&nl;&ht;another multi-line + &ht;string example. + </name> + + The string value associated with 'name' will be exactly the text +enclosed in quotes with the encoded characters 'cooked' as you would +expect (three text lines with the last line not ending with a newline, +but ending with a period). + + +File: autogen.info, Node: config integer-values, Next: config nested-values, Prev: config name/string-value, Up: Config File Format + +7.11.2 integer values +--------------------- + +A name can be specified as having an integer value. To do this, you +must use the XML-ish format and specify a 'type' attribute for the name: + + <name type=integer> 1234 </name> + + Boolean, enumeration and set membership types will be added as time +allows. 'type=string' is also supported, but also is the default. + + +File: autogen.info, Node: config nested-values, Next: config directives, Prev: config integer-values, Up: Config File Format + +7.11.3 hierarchical values +-------------------------- + +In order to specify a hierarchical value, you *must* use XML-styled +formatting, specifying a type that is shorter and easier to spell: + + <structured-name type=nested> + [[....]] + </structured-name> + +The ellipsis may be filled with any legal configuration file name/value +assignments. + + +File: autogen.info, Node: config directives, Next: config comments, Prev: config nested-values, Up: Config File Format + +7.11.4 configuration file directives +------------------------------------ + +The '<?' marker indicates an XML directive. There is only one directive +supported: program sectioning, though two syntaxes are supported. + + If, for example, you have a collection of programs that work closely +together and, likely, have a common set of options, these programs may +use a single, sectioned, configuration file. The file may be sectioned +in either of two ways. The two ways may not be intermixed in a single +configuration file. All text before the first segmentation line is +processed, then only the segment that applies: + +'<?auto-options ...>' + The '...' ellipsis may contain AutoOpts option processing options. + Currently, that consists of one or both of: + + 'gnu' + 'autoopts' + to indicate GNU-standard or AutoOpts-standard layout of usage + and version information, and/or + + 'misuse-usage' + 'no-misuse-usage' + to indicate whether the available options should be listed + when an invalid option appears on the command line. + Anything else will be silently ignored. + +'<?program prog-name>' + The '<?' marker indicates an XML directive. The file is + partitioned by these lines and the options are processed for the + 'prog-name' program only before the first '<?program' directive and + the program section with a matching program name. + +'[PROG_NAME]' + This is basically an alias for '<?program prog-name>', except that + the program name must be upper cased and segmented only with + underscores and it is *not* recognized as a program segment when + updating configuration files with the '--save-opts' option. In + other words, use this only for Windows compatibility. + +Segmentation does not apply if the config file is being parsed with the +'configFileLoad(3AutoOpts)' function. + + +File: autogen.info, Node: config comments, Prev: config directives, Up: Config File Format + +7.11.5 comments in the configuration file +----------------------------------------- + +Comments are lines beginning with a hash mark ('#'), XML-style comments +('<!-- arbitrary text -->'), and unrecognized XML directives. + + # this is a comment + <!-- this is also + a comment --> + <?this is + a bad comment ;-> + + +File: autogen.info, Node: shell options, Next: AutoInfo, Prev: Config File Format, Up: AutoOpts + +7.12 AutoOpts for Shell Scripts +=============================== + +AutoOpts may be used with shell scripts either by automatically creating +a complete program that will process command line options and pass back +the results to the invoking shell by issuing shell variable assignment +commands, or it may be used to generate portable shell code that can be +inserted into your script. + + The functionality of these features, of course, is somewhat +constrained compared with the normal program facilities. Specifically, +you cannot invoke callout procedures with either of these methods. +Additionally, if you generate a shell script to do the parsing: + + 1. You cannot obtain options from configuration files. + 2. You cannot obtain options from environment variables. + 3. You cannot save the option state to an option file. + 4. Option conflict/requirement verification is disabled. + + Both of these methods are enabled by running AutoGen on the +definitions file with the additional main procedure attribute: + + main = { main-type = shell-process; }; +or: + main = { main-type = shell-parser; }; + + If you do not supply a 'proc-to-call', it will default to +'optionPutShell'. That will produce a program that will process the +options and generate shell text for the invoking shell to interpret +(*note binary-parser::). If you supply the name, 'optionParseShell', +then you will have a program that will generate a shell script that can +parse the options (*note script-parser::). If you supply a different +procedure name, you will have to provide that routine and it may do +whatever you like. + +* Menu: + +* binary-parser:: Parsing with an Executable +* script-parser:: Parsing with a Portable Script + + +File: autogen.info, Node: binary-parser, Next: script-parser, Up: shell options + +7.12.1 Parsing with an Executable +--------------------------------- + +The following commands are approximately all that is needed to build a +shell script command line option parser from an option definition file: + + autogen -L <opt-template-dir> test-errors.def + cc -o test-errors -L <opt-lib-dir> -I <opt-include-dir> \ + -DTEST_PROGRAM_OPTS test-errors.c -lopts + + The resulting program can then be used within your shell script as +follows: + + eval `./test-errors "$@"` + if [ -z "${OPTION_CT}" ] ; then exit 1 ; fi + test ${OPTION_CT} -gt 0 && shift ${OPTION_CT} + + Here is the usage output example from AutoOpts error handling tests. +The option definition has argument reordering enabled: + + test_errors - Test AutoOpts for errors + Usage: errors [ -<flag> [<val>] | --<name>[{=| }<val>] ]... arg ... + Flg Arg Option-Name Description + -o no option The option option descrip + -s Str second The second option descrip + - may appear up to 10 times + -i --- ignored we have dumped this + -X no another Another option descrip + - may appear up to 5 times + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + -> opt save-opts save the option state to a config file + -< Str load-opts load options from a config file + - disabled as '--no-load-opts' + - may appear multiple times + + Options are specified by doubled hyphens and their name or by a single + hyphen and the flag character. + Operands and options may be intermixed. They will be reordered. + + The following option preset mechanisms are supported: + - reading file errorsRC + + Using the invocation, + test-errors operand1 -s first operand2 -X -- -s operand3 + you get the following output for your shell script to evaluate: + + OPTION_CT=4 + export OPTION_CT + TEST_ERRORS_SECOND='first' + export TEST_ERRORS_SECOND + TEST_ERRORS_ANOTHER=1 # 0x1 + export TEST_ERRORS_ANOTHER + set -- 'operand1' 'operand2' '-s' 'operand3' + OPTION_CT=0 + + +File: autogen.info, Node: script-parser, Prev: binary-parser, Up: shell options + +7.12.2 Parsing with a Portable Script +------------------------------------- + +If you had used 'test-main = optionParseShell' instead, then you can, at +this point, merely run the program and it will write the parsing script +to standard out. You may also provide this program with command line +options to specify the shell script file to create or edit, and you may +specify the shell program to use on the first shell script line. That +program's usage text would look something like the following and the +script parser itself would be very verbose: + + genshellopt - Generate Shell Option Processing Script - Ver. 1 + Usage: genshellopt [ -<flag> [<val>] | --<name>[{=| }<val>] ]... + Flg Arg Option-Name Description + -o Str script Output Script File + -s Str shell Shell name (follows "#!" magic) + - disabled as '--no-shell' + - enabled by default + -v opt version output version information and exit + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + + Options are specified by doubled hyphens and their name or by a single + hyphen and the flag character. + Note that 'shell' is only useful if the output file does not already exist. + If it does, then the shell name and optional first argument will be + extracted from the script file. + If the script file already exists and contains Automated Option Processing + text, the second line of the file through the ending tag will be replaced + by the newly generated text. The first '#!' line will be regenerated. + + Please send bug reports to: <autogen-users@lists.sourceforge.net> + + = = = = = = = = + + This incarnation of genshell will produce + a shell script to parse the options for getdefs: + + getdefs (GNU AutoGen) - AutoGen Definition Extraction Tool - Ver. 1.5 + Usage: getdefs [ <option-name>[{=| }<val>] ]... + Arg Option-Name Description + Str defs-to-get Regexp to look for after the "/*=" + Str subblock subblock definition names + Str listattr attribute with list of values + opt ordering Alphabetize or use named file + Num first-index The first index to apply to groups + opt filelist Insert source file names into defs + Str assign Global assignments + Str common-assign Assignments common to all blocks + Str copy File(s) to copy into definitions + opt srcfile Insert source file name into each def + opt linenum Insert source line number into each def + Str input Input file to search for defs + Str output Output file to open + opt autogen Invoke AutoGen with defs + Str template Template Name + Str agarg AutoGen Argument + Str base-name Base name for output file(s) + +Resulting in the following script: + #! /bin/sh + # # # # # # # # # # -- do not modify this marker -- + # + # DO NOT EDIT THIS SECTION + OF /u/bkorb/tools/ag/autogen-bld/doc/ag-texi-32340.d/.ag-5GQlKL/genshellopt.sh + # + # From here to the next `-- do not modify this marker --', + # the text has been generated Sunday August 26, 2018 at 10:46:02 AM PDT + # From the GETDEFS option definitions + # + GETDEFS_LONGUSAGE_TEXT='getdefs error: invalid option descriptor for version + getdefs (GNU AutoGen) - AutoGen Definition Extraction Tool - Ver. 1.5 + Usage: getdefs [ <option-name>[{=| }<val>] ]... + + Specify which definitions are of interest and what to say about them: + + Arg Option-Name Description + Str defs-to-get Regexp to look for after the "/*=" + Str subblock subblock definition names + - may appear multiple times + Str listattr attribute with list of values + - may appear multiple times + + specify how to number the definitions: + + Arg Option-Name Description + opt ordering Alphabetize or use named file + - disabled as '\''--no-ordering'\'' + - enabled by default + Num first-index The first index to apply to groups + + Definition insertion options: + + Arg Option-Name Description + opt filelist Insert source file names into defs + Str assign Global assignments + - may appear multiple times + Str common-assign Assignments common to all blocks + - may appear multiple times + Str copy File(s) to copy into definitions + - may appear multiple times + opt srcfile Insert source file name into each def + opt linenum Insert source line number into each def + + specify which files to search for markers: + + Arg Option-Name Description + Str input Input file to search for defs + - may appear multiple times + - default option for unnamed options + + Definition output disposition options:: + + Arg Option-Name Description + Str output Output file to open + - an alternate for '\''autogen'\'' + opt autogen Invoke AutoGen with defs + - disabled as '\''--no-autogen'\'' + - enabled by default + Str template Template Name + Str agarg AutoGen Argument + - prohibits the option '\''output'\'' + - may appear multiple times + Str base-name Base name for output file(s) + - prohibits the option '\''output'\'' + + Version, usage and configuration options: + + Arg Option-Name Description + ' + + GETDEFS_USAGE_TEXT='getdefs (GNU AutoGen) - AutoGen Definition Extraction Tool - Ver. 1.5 + Usage: getdefs [ <option-name>[{=| }<val>] ]... + Arg Option-Name Description + Str defs-to-get Regexp to look for after the "/*=" + Str subblock subblock definition names + Str listattr attribute with list of values + opt ordering Alphabetize or use named file + Num first-index The first index to apply to groups + opt filelist Insert source file names into defs + Str assign Global assignments + Str common-assign Assignments common to all blocks + Str copy File(s) to copy into definitions + opt srcfile Insert source file name into each def + opt linenum Insert source line number into each def + Str input Input file to search for defs + Str output Output file to open + opt autogen Invoke AutoGen with defs + Str template Template Name + Str agarg AutoGen Argument + Str base-name Base name for output file(s) + getdefs error: invalid option descriptor for version' + + + GETDEFS_DEFS_TO_GET=${GETDEFS_DEFS_TO_GET} + GETDEFS_DEFS_TO_GET_set=false + export GETDEFS_DEFS_TO_GET + + if test -z "${GETDEFS_SUBBLOCK}" + then + GETDEFS_SUBBLOCK_CT=0 + export GETDEFS_SUBBLOCK_CT + else + GETDEFS_SUBBLOCK_CT=1 + GETDEFS_SUBBLOCK_1=${GETDEFS_SUBBLOCK} + export GETDEFS_SUBBLOCK_CT GETDEFS_SUBBLOCK_1 + fi + + if test -z "${GETDEFS_LISTATTR}" + then + GETDEFS_LISTATTR_CT=0 + export GETDEFS_LISTATTR_CT + else + GETDEFS_LISTATTR_CT=1 + GETDEFS_LISTATTR_1=${GETDEFS_LISTATTR} + export GETDEFS_LISTATTR_CT GETDEFS_LISTATTR_1 + fi + + GETDEFS_ORDERING=${GETDEFS_ORDERING} + GETDEFS_ORDERING_set=false + export GETDEFS_ORDERING + + GETDEFS_FIRST_INDEX=${GETDEFS_FIRST_INDEX-'0'} + GETDEFS_FIRST_INDEX_set=false + export GETDEFS_FIRST_INDEX + + GETDEFS_FILELIST=${GETDEFS_FILELIST} + GETDEFS_FILELIST_set=false + export GETDEFS_FILELIST + + if test -z "${GETDEFS_ASSIGN}" + then + GETDEFS_ASSIGN_CT=0 + export GETDEFS_ASSIGN_CT + else + GETDEFS_ASSIGN_CT=1 + GETDEFS_ASSIGN_1=${GETDEFS_ASSIGN} + export GETDEFS_ASSIGN_CT GETDEFS_ASSIGN_1 + fi + + if test -z "${GETDEFS_COMMON_ASSIGN}" + then + GETDEFS_COMMON_ASSIGN_CT=0 + export GETDEFS_COMMON_ASSIGN_CT + else + GETDEFS_COMMON_ASSIGN_CT=1 + GETDEFS_COMMON_ASSIGN_1=${GETDEFS_COMMON_ASSIGN} + export GETDEFS_COMMON_ASSIGN_CT GETDEFS_COMMON_ASSIGN_1 + fi + + if test -z "${GETDEFS_COPY}" + then + GETDEFS_COPY_CT=0 + export GETDEFS_COPY_CT + else + GETDEFS_COPY_CT=1 + GETDEFS_COPY_1=${GETDEFS_COPY} + export GETDEFS_COPY_CT GETDEFS_COPY_1 + fi + + GETDEFS_SRCFILE=${GETDEFS_SRCFILE} + GETDEFS_SRCFILE_set=false + export GETDEFS_SRCFILE + + GETDEFS_LINENUM=${GETDEFS_LINENUM} + GETDEFS_LINENUM_set=false + export GETDEFS_LINENUM + + if test -z "${GETDEFS_INPUT}" + then + GETDEFS_INPUT_CT=0 + export GETDEFS_INPUT_CT + else + GETDEFS_INPUT_CT=1 + GETDEFS_INPUT_1=${GETDEFS_INPUT} + export GETDEFS_INPUT_CT GETDEFS_INPUT_1 + fi + + GETDEFS_OUTPUT=${GETDEFS_OUTPUT} + GETDEFS_OUTPUT_set=false + export GETDEFS_OUTPUT + + GETDEFS_AUTOGEN=${GETDEFS_AUTOGEN} + GETDEFS_AUTOGEN_set=false + export GETDEFS_AUTOGEN + + GETDEFS_TEMPLATE=${GETDEFS_TEMPLATE} + GETDEFS_TEMPLATE_set=false + export GETDEFS_TEMPLATE + + if test -z "${GETDEFS_AGARG}" + then + GETDEFS_AGARG_CT=0 + export GETDEFS_AGARG_CT + else + GETDEFS_AGARG_CT=1 + GETDEFS_AGARG_1=${GETDEFS_AGARG} + export GETDEFS_AGARG_CT GETDEFS_AGARG_1 + fi + + GETDEFS_BASE_NAME=${GETDEFS_BASE_NAME} + GETDEFS_BASE_NAME_set=false + export GETDEFS_BASE_NAME + + ARG_COUNT=$# + OPT_ARG=$1 + while [ $# -gt 0 ] + do + OPT_ELEMENT='' + OPT_ARG_VAL='' + OPT_ARG=${1} + OPT_CODE=`echo "X${OPT_ARG}"|sed 's/^X-*//'` + shift + OPT_ARG=$1 + case "${OPT_CODE}" in *=* ) + OPT_ARG_VAL=`echo "${OPT_CODE}"|sed 's/^[^=]*=//'` + OPT_CODE=`echo "${OPT_CODE}"|sed 's/=.*$//'` ;; esac + case "${OPT_CODE}" in + 'de' | \ + 'def' | \ + 'defs' | \ + 'defs-' | \ + 'defs-t' | \ + 'defs-to' | \ + 'defs-to-' | \ + 'defs-to-g' | \ + 'defs-to-ge' | \ + 'defs-to-get' ) + if [ -n "${GETDEFS_DEFS_TO_GET}" ] && ${GETDEFS_DEFS_TO_GET_set} ; then + echo 'Error: duplicate DEFS_TO_GET option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_DEFS_TO_GET_set=true + OPT_NAME='DEFS_TO_GET' + OPT_ARG_NEEDED=YES + ;; + + 'su' | \ + 'sub' | \ + 'subb' | \ + 'subbl' | \ + 'subblo' | \ + 'subbloc' | \ + 'subblock' ) + GETDEFS_SUBBLOCK_CT=`expr ${GETDEFS_SUBBLOCK_CT} + 1` + OPT_ELEMENT="_${GETDEFS_SUBBLOCK_CT}" + OPT_NAME='SUBBLOCK' + OPT_ARG_NEEDED=YES + ;; + + 'li' | \ + 'lis' | \ + 'list' | \ + 'lista' | \ + 'listat' | \ + 'listatt' | \ + 'listattr' ) + GETDEFS_LISTATTR_CT=`expr ${GETDEFS_LISTATTR_CT} + 1` + OPT_ELEMENT="_${GETDEFS_LISTATTR_CT}" + OPT_NAME='LISTATTR' + OPT_ARG_NEEDED=YES + ;; + + 'or' | \ + 'ord' | \ + 'orde' | \ + 'order' | \ + 'orderi' | \ + 'orderin' | \ + 'ordering' ) + if [ -n "${GETDEFS_ORDERING}" ] && ${GETDEFS_ORDERING_set} ; then + echo 'Error: duplicate ORDERING option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_ORDERING_set=true + OPT_NAME='ORDERING' + eval GETDEFS_ORDERING${OPT_ELEMENT}=true + export GETDEFS_ORDERING${OPT_ELEMENT} + OPT_ARG_NEEDED=OK + ;; + + 'no-' | \ + 'no-o' | \ + 'no-or' | \ + 'no-ord' | \ + 'no-orde' | \ + 'no-order' | \ + 'no-orderi' | \ + 'no-orderin' | \ + 'no-ordering' ) + if [ -n "${GETDEFS_ORDERING}" ] && ${GETDEFS_ORDERING_set} ; then + echo 'Error: duplicate ORDERING option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_ORDERING_set=true + GETDEFS_ORDERING='no' + export GETDEFS_ORDERING + OPT_NAME='ORDERING' + OPT_ARG_NEEDED=NO + ;; + + 'fi' | \ + 'fir' | \ + 'firs' | \ + 'first' | \ + 'first-' | \ + 'first-i' | \ + 'first-in' | \ + 'first-ind' | \ + 'first-inde' | \ + 'first-index' ) + if [ -n "${GETDEFS_FIRST_INDEX}" ] && ${GETDEFS_FIRST_INDEX_set} ; then + echo 'Error: duplicate FIRST_INDEX option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_FIRST_INDEX_set=true + OPT_NAME='FIRST_INDEX' + OPT_ARG_NEEDED=YES + ;; + + 'fi' | \ + 'fil' | \ + 'file' | \ + 'filel' | \ + 'fileli' | \ + 'filelis' | \ + 'filelist' ) + if [ -n "${GETDEFS_FILELIST}" ] && ${GETDEFS_FILELIST_set} ; then + echo 'Error: duplicate FILELIST option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_FILELIST_set=true + OPT_NAME='FILELIST' + eval GETDEFS_FILELIST${OPT_ELEMENT}=true + export GETDEFS_FILELIST${OPT_ELEMENT} + OPT_ARG_NEEDED=OK + ;; + + 'as' | \ + 'ass' | \ + 'assi' | \ + 'assig' | \ + 'assign' ) + GETDEFS_ASSIGN_CT=`expr ${GETDEFS_ASSIGN_CT} + 1` + OPT_ELEMENT="_${GETDEFS_ASSIGN_CT}" + OPT_NAME='ASSIGN' + OPT_ARG_NEEDED=YES + ;; + + 'co' | \ + 'com' | \ + 'comm' | \ + 'commo' | \ + 'common' | \ + 'common-' | \ + 'common-a' | \ + 'common-as' | \ + 'common-ass' | \ + 'common-assi' | \ + 'common-assig' | \ + 'common-assign' ) + GETDEFS_COMMON_ASSIGN_CT=`expr ${GETDEFS_COMMON_ASSIGN_CT} + 1` + OPT_ELEMENT="_${GETDEFS_COMMON_ASSIGN_CT}" + OPT_NAME='COMMON_ASSIGN' + OPT_ARG_NEEDED=YES + ;; + + 'co' | \ + 'cop' | \ + 'copy' ) + GETDEFS_COPY_CT=`expr ${GETDEFS_COPY_CT} + 1` + OPT_ELEMENT="_${GETDEFS_COPY_CT}" + OPT_NAME='COPY' + OPT_ARG_NEEDED=YES + ;; + + 'sr' | \ + 'src' | \ + 'srcf' | \ + 'srcfi' | \ + 'srcfil' | \ + 'srcfile' ) + if [ -n "${GETDEFS_SRCFILE}" ] && ${GETDEFS_SRCFILE_set} ; then + echo 'Error: duplicate SRCFILE option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_SRCFILE_set=true + OPT_NAME='SRCFILE' + eval GETDEFS_SRCFILE${OPT_ELEMENT}=true + export GETDEFS_SRCFILE${OPT_ELEMENT} + OPT_ARG_NEEDED=OK + ;; + + 'li' | \ + 'lin' | \ + 'line' | \ + 'linen' | \ + 'linenu' | \ + 'linenum' ) + if [ -n "${GETDEFS_LINENUM}" ] && ${GETDEFS_LINENUM_set} ; then + echo 'Error: duplicate LINENUM option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_LINENUM_set=true + OPT_NAME='LINENUM' + eval GETDEFS_LINENUM${OPT_ELEMENT}=true + export GETDEFS_LINENUM${OPT_ELEMENT} + OPT_ARG_NEEDED=OK + ;; + + 'in' | \ + 'inp' | \ + 'inpu' | \ + 'input' ) + GETDEFS_INPUT_CT=`expr ${GETDEFS_INPUT_CT} + 1` + OPT_ELEMENT="_${GETDEFS_INPUT_CT}" + OPT_NAME='INPUT' + OPT_ARG_NEEDED=YES + ;; + + 'ou' | \ + 'out' | \ + 'outp' | \ + 'outpu' | \ + 'output' ) + if [ -n "${GETDEFS_OUTPUT}" ] && ${GETDEFS_OUTPUT_set} ; then + echo 'Error: duplicate OUTPUT option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_OUTPUT_set=true + OPT_NAME='OUTPUT' + OPT_ARG_NEEDED=YES + ;; + + 'au' | \ + 'aut' | \ + 'auto' | \ + 'autog' | \ + 'autoge' | \ + 'autogen' ) + if [ -n "${GETDEFS_AUTOGEN}" ] && ${GETDEFS_AUTOGEN_set} ; then + echo 'Error: duplicate AUTOGEN option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_AUTOGEN_set=true + OPT_NAME='AUTOGEN' + eval GETDEFS_AUTOGEN${OPT_ELEMENT}=true + export GETDEFS_AUTOGEN${OPT_ELEMENT} + OPT_ARG_NEEDED=OK + ;; + + 'no-' | \ + 'no-a' | \ + 'no-au' | \ + 'no-aut' | \ + 'no-auto' | \ + 'no-autog' | \ + 'no-autoge' | \ + 'no-autogen' ) + if [ -n "${GETDEFS_AUTOGEN}" ] && ${GETDEFS_AUTOGEN_set} ; then + echo 'Error: duplicate AUTOGEN option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_AUTOGEN_set=true + GETDEFS_AUTOGEN='no' + export GETDEFS_AUTOGEN + OPT_NAME='AUTOGEN' + OPT_ARG_NEEDED=NO + ;; + + 'te' | \ + 'tem' | \ + 'temp' | \ + 'templ' | \ + 'templa' | \ + 'templat' | \ + 'template' ) + if [ -n "${GETDEFS_TEMPLATE}" ] && ${GETDEFS_TEMPLATE_set} ; then + echo 'Error: duplicate TEMPLATE option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_TEMPLATE_set=true + OPT_NAME='TEMPLATE' + OPT_ARG_NEEDED=YES + ;; + + 'ag' | \ + 'aga' | \ + 'agar' | \ + 'agarg' ) + GETDEFS_AGARG_CT=`expr ${GETDEFS_AGARG_CT} + 1` + OPT_ELEMENT="_${GETDEFS_AGARG_CT}" + OPT_NAME='AGARG' + OPT_ARG_NEEDED=YES + ;; + + 'ba' | \ + 'bas' | \ + 'base' | \ + 'base-' | \ + 'base-n' | \ + 'base-na' | \ + 'base-nam' | \ + 'base-name' ) + if [ -n "${GETDEFS_BASE_NAME}" ] && ${GETDEFS_BASE_NAME_set} ; then + echo 'Error: duplicate BASE_NAME option' + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + GETDEFS_BASE_NAME_set=true + OPT_NAME='BASE_NAME' + OPT_ARG_NEEDED=YES + ;; + + 've' | \ + 'ver' | \ + 'vers' | \ + 'versi' | \ + 'versio' | \ + 'version' ) + echo "$GETDEFS_LONGUSAGE_TEXT" + exit 0 + ;; + + 'he' | \ + 'hel' | \ + 'help' ) + echo "$GETDEFS_LONGUSAGE_TEXT" + exit 0 + ;; + + 'mo' | \ + 'mor' | \ + 'more' | \ + 'more-' | \ + 'more-h' | \ + 'more-he' | \ + 'more-hel' | \ + 'more-help' ) + echo "$GETDEFS_LONGUSAGE_TEXT" | ${PAGER-more} + exit 0 + ;; + + 'sa' | \ + 'sav' | \ + 'save' | \ + 'save-' | \ + 'save-o' | \ + 'save-op' | \ + 'save-opt' | \ + 'save-opts' ) + echo 'Warning: Cannot save options files' >&2 + OPT_ARG_NEEDED=OK + ;; + + 'lo' | \ + 'loa' | \ + 'load' | \ + 'load-' | \ + 'load-o' | \ + 'load-op' | \ + 'load-opt' | \ + 'load-opts' ) + echo 'Warning: Cannot load options files' >&2 + OPT_ARG_NEEDED=YES + ;; + + 'no-' | \ + 'no-l' | \ + 'no-lo' | \ + 'no-loa' | \ + 'no-load' | \ + 'no-load-' | \ + 'no-load-o' | \ + 'no-load-op' | \ + 'no-load-opt' | \ + 'no-load-opts' ) + echo 'Warning: Cannot suppress the loading of options files' >&2 + OPT_ARG_NEEDED=NO + ;; + + * ) + echo Unknown option: "${OPT_CODE}" >&2 + echo "$GETDEFS_USAGE_TEXT" >&2 + exit 1 + ;; + esac + case "${OPT_ARG_NEEDED}" in + NO ) + OPT_ARG_VAL='' + ;; + YES ) + if [ -z "${OPT_ARG_VAL}" ] + then + if [ $# -eq 0 ] + then + echo No argument provided for ${OPT_NAME} option + echo "$GETDEFS_USAGE_TEXT" + exit 1 + fi >&2 + OPT_ARG_VAL=${OPT_ARG} + shift + OPT_ARG=$1 + fi + ;; + OK ) + if [ -z "${OPT_ARG_VAL}" ] && [ $# -gt 0 ] + then + case "${OPT_ARG}" in -* ) ;; * ) + OPT_ARG_VAL=${OPT_ARG} + shift + OPT_ARG=$1 ;; esac + fi + ;; + esac + if [ -n "${OPT_ARG_VAL}" ] + then + eval GETDEFS_${OPT_NAME}${OPT_ELEMENT}="'${OPT_ARG_VAL}'" + export GETDEFS_${OPT_NAME}${OPT_ELEMENT} + fi + done + OPTION_COUNT=`expr $ARG_COUNT - $#` + OPERAND_COUNT=$# + unset OPT_PROCESS || : + unset OPT_ELEMENT || : + unset OPT_ARG || : + unset OPT_ARG_NEEDED || : + unset OPT_NAME || : + unset OPT_CODE || : + unset OPT_ARG_VAL || : + + # # # # # # # # # # + # + # END OF AUTOMATED OPTION PROCESSING + # + # # # # # # # # # # -- do not modify this marker -- + + env | grep '^GETDEFS_' + + +File: autogen.info, Node: AutoInfo, Next: AutoMan pages, Prev: shell options, Up: AutoOpts + +7.13 Automated Info Docs +======================== + +AutoOpts provides two templates for producing '.texi' documentation. +'agtexi-cmd.tpl' for the invoking section, and 'aginfo3.tpl' for +describing exported library functions and macros. + + For both types of documents, the documentation level is selected by +passing a '-DLEVEL=<level-name>' argument to AutoGen when you build the +document. (See the example invocation below.) + + Two files will be produced, a '.texi' file and a '.menu' file. You +should include the text in the '.menu' file in a '@menu' list, either +with '@include'-ing it or just copying text. The '.texi' file should be +'@include'-ed where the invoking section belongs in your document. + + The '.texi' file will contain an introductory paragraph, a menu and a +subordinate section for the invocation usage and for each documented +option. The introductory paragraph is normally the boiler plate text, +along the lines of: + + This chapter documents the @file{AutoOpts} generated usage text + and option meanings for the @file{your-program} program. + +or: + + These are the publicly exported procedures from the libname library. + Any other functions mentioned in the header file are for the private use + of the library. + +* Menu: + +* command-info:: 'invoking' info docs +* library-info:: library info docs + + +File: autogen.info, Node: command-info, Next: library-info, Up: AutoInfo + +7.13.1 'invoking' info docs +--------------------------- + +Using the option definitions for an AutoOpt client program, the +'agtexi-cmd.tpl' template will produce texinfo text that documents the +invocation of your program. The text emitted is designed to be included +in the full texinfo document for your product. It is not a stand-alone +document. The usage text for the *note autogen usage::, *note getdefs +usage:: and *note columns usage:: programs, are included in this +document and are all generated using this template. + + If your program's option definitions include a 'prog-info-descrip' +section, then that text will replace the boilerplate introductory +paragraph. + +These files are produced by invoking the following command: + + autogen -L ${prefix}/share/autogen -Tagtexi-cmd.tpl \ + -DLEVEL=section your-opts.def + +Where '${prefix}' is the AutoGen installation prefix and 'your-opts.def' +is the name of your product's option definition file. + + +File: autogen.info, Node: library-info, Prev: command-info, Up: AutoInfo + +7.13.2 library info docs +------------------------ + +The 'texinfo' doc for libraries is derived from mostly the same +information as is used for producing man pages *Note man3::. The main +difference is that there is only one output file and the individual +functions are referenced from a 'texi' menu. There is also a small +difference in the global attributes used: + + lib_description A description of the library. This text + appears before the menu. If not provided, + the standard boilerplate version will be + inserted. + see_also The 'SEE ALSO' functionality is not supported + for the 'texinfo' documentation, so any + 'see_also' attribute will be ignored. + +These files are produced by invoking the following commands: + + getdefs linenum srcfile template=aginfo3.tpl output=libexport.def \ + <source-file-list> + + autogen -L ${prefix}/share/autogen -DLEVEL=section libexport.def + +Where '${prefix}' is the AutoGen installation prefix and 'libexport.def' +is some name that suits you. + + An example of this can be seen in this document, *Note libopts +procedures::. + + +File: autogen.info, Node: AutoMan pages, Next: getopt_long, Prev: AutoInfo, Up: AutoOpts + +7.14 Automated Man Pages +======================== + +AutoOpts provides two templates for producing man pages. The command +('man1') pages are derived from the options definition file, and the +library ('man3') pages are derived from stylized comments (*note getdefs +Invocation::). + + Man pages include a date in the footer. By default, this is derived +from the current date. However, this may be overridden with the +'MAN_PAGE_DATE' environment variable. If set and not empty, its +contents will be copied into where the output of 'date '+%d %b %Y'' +would otherwise go. + + Man pages may be formatted as either traditional man pages or using +'mdoc' formatting. The format is selected by selecting the appropriate +template. + +* Menu: + +* man1:: command line man pages +* man3:: library man pages + + +File: autogen.info, Node: man1, Next: man3, Up: AutoMan pages + +7.14.1 command line man pages +----------------------------- + +Man pages for commands are documented using the 'agman-cmd.tpl' and +'agmdoc-cmd.tpl' templates. If the options specify pulling information +from 'RC'/'ini'/'cfg' files, then you may use the 'rc-sample.tpl' +template to produce an example config file for your program. + + Using the option definitions for an AutoOpts client program, the +'agman-cmd.tpl' template will produce an nroff document suitable for use +as a 'man(1)' page document for a command line command. The description +section of the document is either the 'prog-man-descrip' text, if +present, or the 'detail' text. + + Each option in the option definitions file is fully documented in its +usage. This includes all the information documented above for each +option (*note option attributes::), plus the 'doc' attribute is +appended. Since the 'doc' text is presumed to be designed for 'texinfo' +documentation, 'sed' is used to convert some constructs from 'texi' to +'nroff'-for-'man'-pages. Specifically, + + convert @code, @var and @samp into \fB...\fP phrases + convert @file into \fI...\fP phrases + Remove the '@' prefix from curly braces + Indent example regions + Delete the example commands + Replace 'end example' command with ".br" + Replace the '@*' command with ".br" + +This document is produced by invoking the following command: + + autogen -L ${prefix}/share/autogen -Tagman-cmd.tpl options.def + +Where '${prefix}' is the AutoGen installation prefix and 'options.def' +is the name of your product's option definition file. I do not use this +very much, so any feedback or improvements would be greatly appreciated. + + +File: autogen.info, Node: man3, Prev: man1, Up: AutoMan pages + +7.14.2 library man pages +------------------------ + +Man pages for libraries are documented using the 'agman3.tpl' template. + + Two global definitions are required, and then one library man page is +produced for each 'export_func' definition that is found. It is +generally convenient to place these definitions as 'getdefs' comments +(*note getdefs Invocation::) near the procedure definition, but they may +also be a separate AutoGen definitions file (*note Definitions File::). +Each function will be cross referenced with their sister functions in a +'SEE ALSO' section. A global 'see_also' definition will be appended to +this cross referencing text. + +The two global definitions required are: + + library This is the name of your library, without the 'lib' + prefix. The AutoOpts library is named + 'libopts.so...', so the 'library' attribute would + have the value 'opts'. + header Generally, using a library with a compiled program + entails '#include'-ing a header file. Name that + header with this attribute. In the case of AutoOpts, + it is generated and will vary based on the name of + the option definition file. Consequently, + 'your-opts.h' is specified. + +The 'export_func' definition should contain the following attributes: + + name The name of the procedure the library user may call. + what A brief sentence describing what the procedure does. + doc A detailed description of what the procedure does. + It may ramble on for as long as necessary to properly + describe it. + err A short description of how errors are handled. + ret_type The data type returned by the procedure. Omit this + for 'void' procedures. + ret_desc Describe what the returned value is, if needed. + private If specified, the function will *not* be documented. + This is used, for example, to produce external + declarations for functions that are not available for + public use, but are used in the generated text. + arg This is a compound attribute that contains: + arg_type The data type of the argument. + arg_name A short name for it. + arg_desc A brief description. + +As a 'getdefs' comment, this would appear something like this: + + /*=--subblock=arg=arg_type,arg_name,arg_desc =*/ + /*=* + * library: opts + * header: your-opts.h + =*/ + /*=export_func optionProcess + * + * what: this is the main option processing routine + * arg: + tOptions* + pOpts + program options descriptor + + * arg: + int + argc + program arg count + + * arg: + char** + argv + program arg vector + + * ret_type: int + * ret_desc: the count of the arguments processed + * + * doc: This is what it does. + * err: When it can't, it does this. + =*/ + +Note the 'subblock' and 'library' comments. 'subblock' is an embedded +'getdefs' option (*note getdefs subblock::) that tells it how to parse +the 'arg' attribute. The 'library' and 'header' entries are global +definitions that apply to all the documented functions. + + +File: autogen.info, Node: getopt_long, Next: i18n, Prev: AutoMan pages, Up: AutoOpts + +7.15 Using getopt(3C) +===================== + +There is a template named, 'getopt.tpl' that is distributed with +AutoOpts. Using that template instead of 'options.tpl' will produce +completely independent source code that will parse command line options. +It will utilize either the standard 'getopt(3C)' or the GNU +'getopt_long(3GNU)' function to drive the parsing. Which is used is +selected by the presence or absence of the 'long-opts' program +attribute. It will save you from being dependent upon the 'libopts' +library and it produces code ready for internationalization. However, +it also carries with it some limitations on the use of AutoOpts features +and some requirements on the build environment. + + *PLEASE NOTE*: in processing the option definitions to produce the +usage text, it is necessary to compile some generated code in a +temporary directory. That means that all the include directories needed +to compile the code must be full path names and not relative directory +names. "." is a relative directory name. To specify "-I." in the +'CFLAGS' environment variable, you must expand it. For example, use: + CFLAGS=-I`pwd` + +* Menu: + +* getopt limitations:: getopt feature limitations +* getopt building:: getopt build requirements + + +File: autogen.info, Node: getopt limitations, Next: getopt building, Up: getopt_long + +7.15.1 getopt feature limitations +--------------------------------- + +This list of limitations is relative to the full list of AutoOpts +supported features, *Note Features::. + + 1. You cannot automatically take advantage of environment variable + options or automated parsing of configuration files ('rc' or 'ini' + files). Consequently, the resulting code does not support + '--load-opts' or '--save-opts' options automatically. + + 2. You cannot use set membership, enumerated, range checked or stacked + argument type options. In fact, you cannot use anything that + depends upon the 'libopts' library. You are constrained to options + that take 'string' arguments, though you may handle the option + argument with a callback procedure. + + 3. Special disablement and/or enablement prefixes are not recognized. + + 4. Option coordination with external libraries will not work. + + 5. Every option must be 'settable' because the emitted code depends + upon the 'SET_OPT_XXX' macros having been defined. Specify this as + a global (program) attribute. + + 6. You must specify a main procedure attribute (*note Generated + main::). The 'getopt.tpl' template depends upon being able to + compile the traditional .c file into a program and get it to emit + the usage text. + + 7. For the same reason, the traditional option parsing table code must + be emitted before the 'getopt.tpl' template gets expanded. + + 8. The usage text is, therefore, statically defined. + + +File: autogen.info, Node: getopt building, Prev: getopt limitations, Up: getopt_long + +7.15.2 getopt build requirements +-------------------------------- + +You must supply some compile and link options via environment variables. + +'srcdir' + In case the option definition file lives in a different directory. +'CFLAGS' + Any special flags required to compile. The flags from + 'autoopts-config cflags' will be included automatically. Since the + creation of the option parsing code includes creating a program + that prints out help text, if it is necessary to include files from + various directories to compile that program, you will need to + specify those directories with '-Idirpath' text in the 'CFLAGS'. + Some experimentation may be necessary in that case. + + *NOTE*: the '-Idirpath' text is only needed if your option callback + functions include code that require additional '#include' + directives. +'LDFLAGS' + Any special flags required to link. The flags from + 'autoopts-config ldflags' will be included automatically. This is + required only if additional link flags for the help text emission + program might be needed. +'CC' + This is needed only if 'cc' cannot be found in '$PATH' (or it is + not the one you want). + + To use this, set the exported environment variables and specify +'getopt' as the default template in your option definitions file (*note +Identification::). You will have four new files. Assuming your +definitions were in a file named 'myprog-opts.def' and your program name +was specified as 'progname', the resulting files would be created: +'myprog-opts.h', 'myprog-opts.c', 'getopt-progname.h' and +'getopt-progname.c'. You must compile and link both '.c' files into +your program. If there are link failures, then you are using AutoOpts +features that require the 'libopts' library. You must remove these +features, *Note getopt limitations::. + + These generated files depend upon configure defines to work +correctly. Therefore, you must specify a 'config-header' attribute +(*note programming attributes::) and ensure it has '#defines' for either +'HAVE_STDINT_H' or 'HAVE_INTTYPES_H'; either 'HAVE_SYS_LIMITS_H' or +'HAVE_LIMITS_H'; and 'HAVE_SYSEXITS_H', if the 'sysexits.h' header is +available. The required header files for these defines are, +respectively, the '/usr/include' files named: + * stdint.h + * inttypes.h + * sys/limits.h + * limits.h + * sysexits.h + +The following header files must also exist on the build platform: + * sys/types.h + * stdio.h + * string.h + * unistd.h - or, for getopt_long: + * getopt.h + + +File: autogen.info, Node: i18n, Next: Naming Conflicts, Prev: getopt_long, Up: AutoOpts + +7.16 Internationalizing AutoOpts +================================ + +The generated code for AutoOpts will enable and disable the translation +of AutoOpts run time messages. If 'ENABLE_NLS' is defined at compile +time and 'no-xlate' has been not set to the value _anything_, then the +'_()' macro may be used to specify a translation function. If +undefined, it will default to 'gettext(3GNU)'. This define will also +enable a callback function that 'optionProcess' invokes at the beginning +of option processing. The AutoOpts 'libopts' library will always check +for this _compiled with NLS_ flag, so 'libopts' does not need to be +specially compiled. The strings returned by the translation function +will be 'strdup(3)-ed' and kept. They will not be re-translated, even +if the locale changes, but they will also not be dependent upon reused +or unmappable memory. + + You should also ensure that the 'ATTRIBUTE_FORMAT_ARG()' gets +'#define'-ed to something useful. There is an autoconf macro named +'AG_COMPILE_FORMAT_ARG' in 'ag_macros.m4' that will set it appropriately +for you. If you do not do this, then translated formatting strings may +trigger GCC compiler warnings. + + To internationalize option processing, you should first +internationalize your program. Then, the option processing strings can +be added to your translation text by processing the AutoOpts-generated +'my-opts.c' file and adding the distributed 'po/usage-txt.pot' file. +(Also by extracting the strings yourself from the 'usage-txt.h' file.) +When you call 'optionProcess', all of the user visible AutoOpts strings +will be passed through the localization procedure established with the +'_()' preprocessing macro. + + All of this is _dis_-abled if you specify the global attribute +'no-xlate' to _anything_. + + +File: autogen.info, Node: Naming Conflicts, Next: All Attribute Names, Prev: i18n, Up: AutoOpts + +7.17 Naming Conflicts +===================== + +AutoOpts generates a header file that contains many C preprocessing +macros and several external names. For the most part, they begin with +either 'opt_' or 'option', or else they end with '_opt'. If this +happens to conflict with other macros you are using, or if you are +compiling multiple option sets in the same compilation unit, the +conflicts can be avoided. You may specify an external name 'prefix' +(*note program attributes::) for all of the names generated for each set +of option definitions. + + Among these macros, several take an option name as a macro argument. +Sometimes, this will inconveniently conflict. For example, if you +specify an option named, 'debug', the emitted code will presume that +'DEBUG' is not a preprocessing name. Or also, if you are building on a +Windows platform, you may find that MicroSoft has usurped a number of +user space names in its header files. Consequently, you will get a +preprocessing error if you use, for example, 'HAVE_OPT(DEBUG)' or +'HAVE_OPT(INTERNAL)' (*note HAVE_OPT::) in your code. You may trigger +an obvious warning for such conflicts by specifying the +'guard-option-names' attribute (*note program attributes::). That +emitted code will also '#undef'-ine the conflicting name. + + +File: autogen.info, Node: All Attribute Names, Next: Option Define Names, Prev: Naming Conflicts, Up: AutoOpts + +7.18 All Attribute Names +======================== + +This is the list of all the option attributes used in the various option +processing templates. There are several flavors of attributes, and +these are not distinguished here. + + * Valid, current attributes that you are encouraged to use. + * Internally generated attributes that you cannot use at all. I need + to prefix these with a distinguished prefix. e.g. 'ao-' + * Valid attributes, but are deprecated. Alternates should be + documented. + + This list is derived by running many example option definitions +through the option generation and man page templates and noting which +attributes are actually used. There may be a few that are used but not +exercised in my testing. If so, I need to ferret those out and test +them, too. + + addtogroup aliases allow_errors arg_default + arg_name arg_optional arg_range arg_type + argument author call_proc cmd_section + comment_char concept config_header copyright + date default deprecated descrip + detail die_code disable disable_load + disable_save doc doc_section doc_sub + doc_sub_cmd documentation ds_format ds_text + ds_type eaddr enable enabled + environrc equivalence exit_desc exit_name + explain export extract_code field + file_fail_code flag flag_code flag_proc + flags_cant flags_must full_usage gnu_usage + guard_option_names handler_proc handler_type help_type + help_value home_rc homerc ifdef + ifndef immed_disable immediate include + interleaved keyword lib_name library + load_opts_value long_opts main_fini main_init + main_type max min more_help_value + must_set name no_command no_libopts + no_misuse_usage no_preset no_xlate omit_texi + omitted_usage open_file opt_state option_format + option_info owner package prefix + prefix_enum preserve_case prog_descrip prog_info_descrip + prog_man_descrip prog_name prog_title rcfile + reorder_args reset_value resettable save_opts_value + scaled set_desc set_index settable + short_usage stack_arg stdin_input sub_name + sub_text sub_type test_main translators + type unshar_file_code unstack_arg usage + usage_message usage_opt usage_value value + vendor_opt version version_proc version_value + + +File: autogen.info, Node: Option Define Names, Prev: All Attribute Names, Up: AutoOpts + +7.19 Option Definition Name Index +================================= + +�[index�] +* Menu: + +* addtogroup: global option attributes. + (line 18) +* allow-errors: presentation attributes. + (line 9) +* arg-default: arg-default. (line 6) +* arg-name: per option attributes. + (line 9) +* arg-optional: arg-optional. (line 6) +* arg-range: arg-type number. (line 21) +* arg-type: Option Arguments. (line 24) +* argument: program attributes. (line 22) +* author: information attributes. + (line 25) +* before-guile-boot: main guile. (line 9) +* call-proc: Option Argument Handling. + (line 62) +* cmd-section: global option attributes. + (line 7) +* comment-char: main-for-each-opts. (line 25) +* config-header: program attributes. (line 33) +* config-header <1>: programming attributes. + (line 10) +* copyright: information attributes. + (line 10) +* date: information attributes. + (line 13) +* default: opt-attr default option. + (line 6) +* deprecated: Common Attributes. (line 28) +* descrip: Required Attributes. (line 34) +* detail: information attributes. + (line 39) +* detail <1>: global option attributes. + (line 12) +* die-code: programming attributes. + (line 51) +* disable: Common Attributes. (line 33) +* disable-load: config attributes. (line 13) +* disable-save: config attributes. (line 13) +* doc: per option attributes. + (line 15) +* doc-section: global option attributes. + (line 42) +* doc-sub: global option attributes. + (line 141) +* doc-sub-cmd: global option attributes. + (line 173) +* documentation: lib and program. (line 16) +* documentation <1>: opt-attr documentation. + (line 17) +* eaddr: information attributes. + (line 27) +* enable: Common Attributes. (line 45) +* enabled: Common Attributes. (line 49) +* environrc: config attributes. (line 17) +* equivalence: opt-attr equivalence. + (line 6) +* exit-desc: programming attributes. + (line 16) +* exit-name: programming attributes. + (line 16) +* explain: information attributes. + (line 43) +* export: programming attributes. + (line 66) +* extra-code: arg-keyword. (line 15) +* extract-code: Option Argument Handling. + (line 51) +* file-exists: arg-type file name. (line 13) +* file-mode: arg-type file name. (line 29) +* flag-code: Option Argument Handling. + (line 27) +* flag-proc: Option Argument Handling. + (line 69) +* full-usage: usage attributes. (line 10) +* gnu-usage: usage attributes. (line 43) +* gnu-usage <1>: information attributes. + (line 82) +* guard-option-names: programming attributes. + (line 73) +* guile-main: main guile. (line 14) +* handler-frees: main-for-each-type. (line 66) +* handler-proc: main-for-each-proc. (line 6) +* handler-type: main-for-each-type. (line 6) +* help-value: automatic options. (line 18) +* homerc: config attributes. (line 26) +* ifdef: Common Attributes. (line 56) +* ifndef: Common Attributes. (line 56) +* immed-disable: Immediate Action. (line 31) +* immediate: Immediate Action. (line 24) +* include: programming attributes. + (line 104) +* interleaved: main-for-each-opts. (line 10) +* keyword: arg-keyword. (line 6) +* lib-name: lib and program. (line 24) +* library: lib and program. (line 7) +* load-opts-value: automatic options. (line 15) +* long-opts: presentation attributes. + (line 15) +* main: Generated main. (line 8) +* main-fini: main-for-each-opts. (line 21) +* main-init: main-for-each-opts. (line 17) +* main-type: Generated main. (line 12) +* max: Common Attributes. (line 14) +* min: Common Attributes. (line 19) +* more-help-value: automatic options. (line 15) +* must-set: Common Attributes. (line 24) +* MYHANDLER-code: main-for-each-code. (line 6) +* name: Required Attributes. (line 9) +* no-command: Common Attributes. (line 87) +* no-libopts: programming attributes. + (line 108) +* no-misuse-usage: usage attributes. (line 57) +* no-preset: opt-attr no-preset. (line 6) +* no-xlate: presentation attributes. + (line 35) +* omitted-usage: Common Attributes. (line 56) +* open-file: arg-type file name. (line 23) +* option-code: main main. (line 7) +* option-format: global option attributes. + (line 28) +* option-info: global option attributes. + (line 38) +* opts-ptr: information attributes. + (line 61) +* owner: information attributes. + (line 14) +* package: information attributes. + (line 46) +* prefix: programming attributes. + (line 115) +* prefix-enum: arg-type keyword. (line 38) +* preserve-case: information attributes. + (line 52) +* prog-desc: information attributes. + (line 61) +* prog-group: usage attributes. (line 65) +* prog-name: program attributes. (line 15) +* prog-title: program attributes. (line 19) +* rcfile: config attributes. (line 56) +* reorder-args: presentation attributes. + (line 51) +* reorder-args <1>: information attributes. + (line 91) +* reset-value: automatic options. (line 15) +* resettable: presentation attributes. + (line 68) +* save-opts-value: automatic options. (line 19) +* scaled: arg-type number. (line 15) +* settable: opt-attr settable. (line 6) +* short-usage: usage attributes. (line 38) +* stack-arg: Option Argument Handling. + (line 73) +* text: information attributes. + (line 23) +* translators: opt-attr translators. + (line 6) +* type: information attributes. + (line 15) +* unstack-arg: Option Argument Handling. + (line 86) +* usage: usage attributes. (line 73) +* usage <1>: information attributes. + (line 74) +* usage-message: programming attributes. + (line 41) +* usage-opt: Features. (line 56) +* usage-opt <1>: usage attributes. (line 51) +* usage-value: automatic options. (line 15) +* value: Common Attributes. (line 10) +* vendor-opt: config attributes. (line 61) +* version: usage attributes. (line 90) +* version-proc: automatic options. (line 23) +* version-value: automatic options. (line 15) + + +File: autogen.info, Node: Add-Ons, Next: Future, Prev: AutoOpts, Up: Top + +8 Add-on packages for AutoGen +***************************** + +This chapter includes several programs that either work closely with +AutoGen (extracting definitions or providing special formatting +functions), or leverage off of AutoGen technology. There is also a +formatting library that helps make AutoGen possible. + + AutoOpts ought to appear in this list as well, but since it is the +primary reason why many people would even look into AutoGen at all, I +decided to leave it in the list of chapters. + +* Menu: + +* AutoFSM:: Automated Finite State Machine. +* AutoXDR:: Combined RPC Marshalling. +* AutoEvents:: Automated Event Management. +* Bit Maps:: Bit Maps and Enumerations. +* columns Invocation:: Invoking columns. +* getdefs Invocation:: Invoking getdefs. +* xml2ag Invocation:: Invoking xml2ag. +* snprintfv:: The extensible format printing library. + + +File: autogen.info, Node: AutoFSM, Next: AutoXDR, Up: Add-Ons + +8.1 Automated Finite State Machine +================================== + +The templates to generate a finite state machine in C or C++ is included +with AutoGen. The documentation is not. The documentation is in HTML +format for viewing (http://www.gnu.org/software/autogen/autofsm.html), +or you can download FSM (http://download.sourceforge.net/autogen/). + + +File: autogen.info, Node: AutoXDR, Next: AutoEvents, Prev: AutoFSM, Up: Add-Ons + +8.2 Combined RPC Marshalling +============================ + +The templates and NFSv4 definitions are not included with AutoGen in any +way. The folks that designed NFSv4 noticed that much time and bandwidth +was wasted sending queries and responses when many of them could be +bundled. The protocol bundles the data, but there is no support for it +in rpcgen. That means you have to write your own code to do that. +Until now. Download this and you will have a large, complex example of +how to use 'AutoXDR' for generating the marshaling and unmarshaling of +combined RPC calls. There is a brief example on the web +(http://www.gnu.org/software/autogen/xdr/index.html), but you should +download AutoXDR (http://download.sourceforge.net/autogen/). + + +File: autogen.info, Node: AutoEvents, Next: Bit Maps, Prev: AutoXDR, Up: Add-Ons + +8.3 Automated Event Management +============================== + +Large software development projects invariably have a need to manage the +distribution and display of state information and state changes. In +other words, they need to manage their software events. Generally, each +such project invents its own way of accomplishing this and then +struggles to get all of its components to play the same way. It is a +difficult process and not always completely successful. This project +helps with that. + + AutoEvents completely separates the tasks of supplying the data +needed for a particular event from the methods used to manage the +distribution and display of that event. Consequently, the programmer +writing the code no longer has to worry about that part of the problem. +Likewise the persons responsible for designing the event management and +distribution no longer have to worry about getting programmers to write +conforming code. + + This is a work in progress. See my web page +(http://www.gnu.org/software/autogen/autoevents.html) on the subject, if +you are interested. I have some useful things put together, but it is +not ready to call a product. + + +File: autogen.info, Node: Bit Maps, Next: columns Invocation, Prev: AutoEvents, Up: Add-Ons + +8.4 Bit Maps and Enumerations +============================= + +AutoGen provides two templates for managing enumerations and bit maps +(flag words). They produce an enumeration of the enum or '#define's for +the bit maps, plus conversion functions for converting a string into one +of these values or converting one of these values into a human readable +string. Finally, for enumerations, you may specify one or more sets of +dispatching functions that will be selected by identifying a keyword +prefix of a string (*note the dispatch attribute in Strings to Enums and +Back: enum-code.). + + There is a separate project that produces a GDB add-on that will add +these capabilities into GDB for bit masks. (GDB does just fine with +enumerations.) + +* Menu: + +* enums:: Enumerations +* enum-code:: Strings to Enums and Back +* masks:: Bit Maps and Masks + + +File: autogen.info, Node: enums, Next: enum-code, Up: Bit Maps + +8.4.1 Enumerations +------------------ + +'str2enum.tpl' + + Produce an enumeration for a list of input "cmd"s (names). +Optionally, produce functions to: + + * convert a string to an enumeration + * convert an enumeration value into a string + * invoke a function based on the first token name found in a string + + The header file produced will contain the enumeration and +declarations for the optional procedures. The code ('.c') file will +contain these optional procedures, but can be omitted if the 'no-code' +attribute is specified. + + The following attributes are recognized with the 'str2enum' template: + +'cmd' + You must provide a series of these attributes: they specify the + list of names used in the enumeration. Specific values for the + names may be specified by specifying a numeric index for these + attributes. e.g. 'cmd[5] = mumble;' will cause + FOO_CMD_MUMBLE = 5 + to be inserted into the enumeration. Do not specify a value of + "invalid", unless you specify the 'invalid-name' attribute. (In + that case, do not specify a 'cmd' value that matches the + 'invalid-name' value.) + +'prefix' + This specifies the first segment of each enumeration name. If not + specified, the first segment of the enumeration definition file + name will be used. e.g. 'foo-bar.def' will default to a 'FOO' + prefix. + +'type' + Normally, there is a second constant segment following the prefix. + If not specified, it will be 'CMD', so if both 'prefix' and 'type' + were to default from 'foo-bar.def', you will have enumeration + values prefixed with 'FOO_CMD_'. If specified as the empty string, + there will be no "type" component to the name and the default + constant prefix will thus be 'FOO_'. + +'base-name' + This specifies the base name of the output files, enumeration type + and the translation functions. The default is to use the + 'basename(3)' of the definition file. e.g. 'foo-bar.def' results + in a 'base-name' of 'foo-bar'. + +'invalid-val' + The default invalid value is zero. Sometimes, it is useful for + zero to be valid. If so, you can specify ~0 or the empty string to + be invalid. The empty string will cause the enumeration count + (maximum value plus 1) to be the invalid value. + +'invalid-name' + By default, the invalid value is emitted into the enumeration as + 'FOO_INVALID_CMD'. Specifying this attribute will replace + 'INVALID' with whatever you place in this attribute. + +'add-on-text' + Additional text to insert into the code or header file. + + 'ao-file' + Which file to insert the text into. There are four choices, + only two of which are relevant for the 'str2enum' template: + "enum-header", "enum-code", "mask-header" or "mask-code". + + 'ao-text' + The text to insert. + + +File: autogen.info, Node: enum-code, Next: masks, Prev: enums, Up: Bit Maps + +8.4.2 Strings to Enums and Back +------------------------------- + +A continuation of the attributes for the 'str2enum.tpl' template. + +'no-code' + Do not emit any string to enumeration or enumeration to string code + at all. If this is specified, the remainder of the attributes have + no effect. + +'no-name' + Do not emit the enumeration to name function. + +'no-case' + When looking up a string, the case of the input string is ignored. + +'alias' + A single punctuation character can be interpreted as a command. + The first character of this attribute is the aliased character and + the remainder the aliased-to command. e.g. "#comment" makes '#' + an alias for the 'comment' command. "#comment" must still be + listed in the 'cmd' attributes. + +'length' + Specify how lengths are to be handled. Under the covers, + 'gperf(1)' is used to map a string to an enumeration value. The + code it produces requires the string length to be passed in. You + may pass in the length yourself, or the generated code may figure + it out, or you may ask for that length to be returned back after + being figured out. + + You have four choices with the 'length' attribute: + + * Do not specify it. You will need to provide the length. + * Specify "provided". You will need to provide the length. + * Specify "returned". You must pass a pointer to a size_t + object. If the name is found, the length will be put there. + * Specify an empty string. The generated code will compute the + length and that computed length will not be returned. The + length parameter may be omitted. If the input strings contain + only enumeration names, then this would be sufficient. + * Specifying anything else is undefined. + +'partial' + Normally, a name must fully match to be found successfully. This + attribute causes the generated code to look for partial matches if + the full match 'gperf' function fails. Partial matches must be at + least two characters long. + +'undef-str' + by default, the display string for an undefined value is "* + UNDEFINED *". Use this to change that. + +'equate' + A series of punctuation characters considered equivalent. + Typically, "-_" but sometimes (Tandem) "-_^". Do not use '#' in + the list of characters. + +'dispatch' + A lookup procedure will call a dispatch function for the procedure + named after the keyword identified at the start of a string. Other + than as specially noted below, for every named "cmd", must have a + handling function, plus another function to handle errors, with + "invalid" (or the 'invalid-name' value) as the 'cmd' name. + Multiple 'dispatch' definitions will produce multiple dispatching + functions, each with (potentially) unique argument lists and return + types. + + You may also use 'add-on-text' to "#define" one function to + another, thus allowing one function to handle multiple keywords or + commands. The 'd-nam' and 'd-ret' attributes are required. The + 'd-arg', 'd-omit' and 'd-only' attributes are optional: + + 'd-nam' + This must be a printf format string with one formatting + element: '%s'. The '%s' will be replaced by each 'cmd' name. + The '%s' will be stripped and the result will be combined with + the base name to construct the dispatch procedure name. + + 'd-ret' + The return type of the dispatched function, even if "void". + + 'd-arg' + If there are additional arguments that are to be passed + through to the dispatched function, specify this as though it + were part of the procedure header. (It will be glued into the + dispatching function as is and sedded into what is needed for + the dispatched function.) + + 'd-omit' + Instead of providing handling functions for all of the 'cmd' + names, the invalid function will be called for omitted command + codes. + + 'd-only' + You need only provide functions for the names listed by + 'd-only', plus the "invalid" name. All other command values + will trigger calls to the invalid handling function. Note + that the invalid call can distinguish from a command that + could not be found by examining the value of its first ('id') + argument. + + The handler functions will have the command enumeration as its + first first argument, a pointer to a constant string that will be + the character after the parsed command (keyword) name, plus any + 'd-arg' arguments that follow that. + + As an example, a file 'samp-chk.def' containing this: + AutoGen Definitions str2enum; + cmd = one, two; invalid-name = oops; + dispatch = { d-nam = 'hdl_%s_cmd'; d-ret = void; }; + will produce a header containing: + typedef enum { + SAMP_OOPS_CMD = 0, + SAMP_CMD_ONE = 1, + SAMP_CMD_TWO = 2, + SAMP_COUNT_CMD + } samp_chk_enum_t; + + extern samp_chk_enum_t + find_samp_chk_cmd(char const * str, size_t len); + + typedef void(samp_chk_handler_t)( + samp_chk_enum_t id, char const * str); + + samp_chk_handler_t + hdl_oops_cmd, hdl_one_cmd, hdl_two_cmd; + + extern void + disp_samp_chk(char * str, size_t len); + + extern char const * + samp_chk_name(samp_chk_enum_t id); + + * 'find_samp_chk_cmd' will look up a 'len' byte 'str' and return + the corresponding 'samp_chk_enum_t' value. That value is + 'SAMP_OOPS_CMD' if the string is not "one" or "two". + * 'samp_chk_handler_t' is the type of the callback procedures. + Three must be provided for the dispatching function to call: + 'hdl_oops_cmd', 'hdl_one_cmd' and 'hdl_two_cmd'. + 'hdl_oops_cmd' will receive calls when the string does not + match. + * 'disp_samp_chk' this function will call the handler function + and return whatever the handler returns. In this case, it is + void. + * 'samp_chk_name' will return a string corresponding to the + enumeration value argument. If the value is not valid, "* + UNDEFINED *" (or the value of 'undef-str') is used. + + +File: autogen.info, Node: masks, Prev: enum-code, Up: Bit Maps + +8.4.3 Bit Maps and Masks +------------------------ + +'str2mask.tpl' + + This template leverages highly off of enumerations (*note enums::). +It will produce a header file with bit masks defined for each bit +specified with a 'cmd' attribute. 63 is the highest legal bit number +because this template has not been extended to cope with multiple word +masks. (Patches would be welcome.) + + There are a few constraints on the names allowed: + + * names are constrained to alphanumerics and the underscore + * aliases are not allowed + * dispatch procedures are not allowed + + 'no-code' and 'no-name' are honored. 'dispatch' is not. The lookup +function will examine each token in an input string, determine which bit +is specified and add it into a result. The names may be prefixed with a +hyphen (-) or tilde (~) to remove the bit(s) from the cumulative result. +If the string begins with a plus (+), hyphen or tilde, a "base value" +parameter is used for the starting mask, otherwise the conversion starts +with zero. + + Beyond the enumeration attributes that are used (or ignored), the +'str2mask' template accepts a 'mask' attribute. It takes a few +"subattributes": + +'m-name' + a special name for a sub-collection of the mask bits + +'m-bit' + The name of each previously defined bit(s). If the desired + previously defined value is a mask, that 'm-name' must be suffixed + with "-mask". + +'m-invert' + When all done collecting the bits, x-or the value with the mask of + all the bits in the collection. + +A mask of all bits in the collection is always generated. + + +File: autogen.info, Node: columns Invocation, Next: getdefs Invocation, Prev: Bit Maps, Up: Add-Ons + +8.5 Invoking columns +==================== + +This program was designed for the purpose of generating compact, +columnized tables. It will read a list of text items from standard in +or a specified input file and produce a columnized listing of all the +non-blank lines. Leading white space on each line is preserved, but +trailing white space is stripped. Methods of applying per-entry and +per-line embellishments are provided. See the formatting and separation +arguments below. + + This program is used by AutoGen to help clean up and organize its +output. + + See 'autogen/agen5/fsm.tpl' and the generated output 'pseudo-fsm.h'. + + This function was not implemented as an expression function because +either it would have to be many expression functions, or a provision +would have to be added to provide options to expression functions. +Maybe not a bad idea, but it is not being implemented at the moment. + + A side benefit is that you can use it outside of 'autogen' to +columnize input, a la the 'ls' command. + + This section was generated by *AutoGen*, using the 'agtexi-cmd' +template and the option descriptions for the 'columns' program. This +software is released under the GNU General Public License, version 3 or +later. + +* Menu: + +* columns usage:: columns help/usage ('--help') +* columns dimensions:: dimensions options +* columns treatment:: treatment options +* columns ordering:: ordering options +* columns input-text:: input-text options +* columns config:: presetting/configuring columns +* columns exit status:: exit status +* columns See Also:: See Also + + +File: autogen.info, Node: columns usage, Next: columns dimensions, Up: columns Invocation + +8.5.1 columns help/usage ('--help') +----------------------------------- + +This is the automatically generated usage text for columns. + + The text printed is the same whether selected with the 'help' option +('--help') or the 'more-help' option ('--more-help'). 'more-help' will +print the usage text by passing it through a pager program. 'more-help' +is disabled on platforms without a working 'fork(2)' function. The +'PAGER' environment variable is used to select the program, defaulting +to 'more'. Both will exit with a status code of 0. + + columns (GNU AutoGen) - Columnize Input Text - Ver. 1.2 + Usage: columns [ -<flag> [<val>] | --<name>[{=| }<val>] ]... + + Specify the output dimensions: + + Flg Arg Option-Name Description + -W Num width Maximum Line Width + - it must be in the range: + 16 to 4095 + -c Num columns Desired number of columns + - it must be in the range: + 1 to 2048 + -w Num col-width Set width of each column + - it must be in the range: + 1 to 2048 + Num tab-width tab width + + Specify how to lay out the text: + + Flg Arg Option-Name Description + Num spread maximum spread added to column width + - it must be in the range: + 1 to 1024 + no fill Fill lines with input + - prohibits these options: + spread + col-width + by-columns + -I Str indent Line prefix or indentation + Str first-indent First line prefix + - requires the option 'indent' + -f Str format Formatting string for each input + -S Str separation Separation string - follows all but last + Str line-separation string at end of all lines but last + Str ending string at end of last line + + Specify the ordering of the entries: + + Flg Arg Option-Name Description + no by-columns Print entries in column order + -s opt sort Sort input text + + Redirecting stdin to an alternate file: + + Flg Arg Option-Name Description + -i Str input Input file (if not stdin) + + Version, usage and configuration options: + + Flg Arg Option-Name Description + -v opt version output version information and exit + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + -> opt save-opts save the option state to a config file + -< Str load-opts load options from a config file + - disabled as '--no-load-opts' + - may appear multiple times + + Options are specified by doubled hyphens and their name or by a single + hyphen and the flag character. + + The following option preset mechanisms are supported: + - reading file ./.columnsrc + - reading file $HOME/.columnsrc + - examining environment variables named COLUMNS_* + + Please send bug reports to: <autogen-users@lists.sourceforge.net> + + +File: autogen.info, Node: columns dimensions, Next: columns treatment, Prev: columns usage, Up: columns Invocation + +8.5.2 dimensions options +------------------------ + +Specify the output dimensions. + +width option (-W). +.................. + +This is the "maximum line width" option. This option takes a number +argument 'num'. This option specifies the full width of the output +line, including any start-of-line indentation. The output will fill +each line as completely as possible, unless the column width has been +explicitly specified. If the maximum width is less than the length of +the widest input, you will get a single column of output. + +columns option (-c). +.................... + +This is the "desired number of columns" option. This option takes a +number argument 'count'. Use this option to specify exactly how many +columns to produce. If that many columns will not fit within +LINE_WIDTH, then the count will be reduced to the number that fit. + +col-width option (-w). +...................... + +This is the "set width of each column" option. This option takes a +number argument 'num'. Use this option to specify exactly how many +characters are to be allocated for each column. If it is narrower than +the widest entry, it will be over-ridden with the required width. + +tab-width option. +................. + +This is the "tab width" option. This option takes a number argument +'num'. If an indentation string contains tabs, then this value is used +to compute the ending column of the prefix string. + + +File: autogen.info, Node: columns treatment, Next: columns ordering, Prev: columns dimensions, Up: columns Invocation + +8.5.3 treatment options +----------------------- + +Specify how to lay out the text. + +spread option. +.............. + +This is the "maximum spread added to column width" option. This option +takes a number argument 'num'. Use this option to specify exactly how +many characters may be added to each column. It allows you to prevent +columns from becoming too far apart. Without this option, 'columns' +will attempt to widen columns to fill the full width. + +fill option. +............ + +This is the "fill lines with input" option. + +This option has some usage constraints. It: + * must not appear in combination with any of the following options: + spread, col_width, by_columns. + + Instead of columnizing the input text, fill the output lines with the +input lines. Blank lines on input will cause a blank line in the +output, unless the output is sorted. With sorted output, blank lines +are ignored. + +indent option (-I). +................... + +This is the "line prefix or indentation" option. This option takes a +string argument 'l-pfx'. If a number, then this many spaces will be +inserted at the start of every line. Otherwise, it is a line prefix +that will be inserted at the start of every line. + +first-indent option. +.................... + +This is the "first line prefix" option. This option takes a string +argument 'l-pfx'. + +This option has some usage constraints. It: + * must appear in combination with the following options: indent. + + If a number, then this many spaces will be inserted at the start of +the first line. Otherwise, it is a line prefix that will be inserted at +the start of that line. If its length exceeds "indent", then it will be +emitted on a line by itself, suffixed by any line separation string. +For example: + + $ columns --first='#define TABLE' -c 2 -I4 --line=' \' <<_EOF_ + one + two + three + four + _EOF_ + #define TABLE \ + one two \ + three four + +format option (-f). +................... + +This is the "formatting string for each input" option. This option +takes a string argument 'fmt-str'. If you need to reformat each input +text, the argument to this option is interpreted as an 'sprintf(3)' +format that is used to produce each output entry. + +separation option (-S). +....................... + +This is the "separation string - follows all but last" option. This +option takes a string argument 'sep-str'. Use this option if, for +example, you wish a comma to appear after each entry except the last. + +line-separation option. +....................... + +This is the "string at end of all lines but last" option. This option +takes a string argument 'sep-str'. Use this option if, for example, you +wish a backslash to appear at the end of every line, except the last. + +ending option. +.............. + +This is the "string at end of last line" option. This option takes a +string argument 'end-str'. This option puts the specified string at the +end of the output. + + +File: autogen.info, Node: columns ordering, Next: columns input-text, Prev: columns treatment, Up: columns Invocation + +8.5.4 ordering options +---------------------- + +Specify the ordering of the entries. + +by-columns option. +.................. + +This is the "print entries in column order" option. Normally, the +entries are printed out in order by rows and then columns. This option +will cause the entries to be ordered within columns. The final column, +instead of the final row, may be shorter than the others. + +sort option (-s). +................. + +This is the "sort input text" option. This option takes an optional +string argument 'key-pat'. Causes the input text to be sorted. If an +argument is supplied, it is presumed to be a pattern and the sort is +based upon the matched text. If the pattern starts with or consists of +an asterisk ('*'), then the sort is case insensitive. + + +File: autogen.info, Node: columns input-text, Next: columns config, Prev: columns ordering, Up: columns Invocation + +8.5.5 input-text options +------------------------ + +Redirecting stdin to an alternate file. + +input option (-i). +.................. + +This is the "input file (if not stdin)" option. This option takes a +string argument 'file'. This program normally runs as a 'filter', +reading from standard input, columnizing and writing to standard out. +This option redirects input to a file. + + +File: autogen.info, Node: columns config, Next: columns exit status, Prev: columns input-text, Up: columns Invocation + +8.5.6 presetting/configuring columns +------------------------------------ + +Any option that is not marked as not presettable may be preset by +loading values from configuration ("rc" or "ini") files, and values from +environment variables named 'COLUMNS' and 'COLUMNS_<OPTION_NAME>'. +'<OPTION_NAME>' must be one of the options listed above in upper case +and segmented with underscores. The 'COLUMNS' variable will be +tokenized and parsed like the command line. The remaining variables are +tested for existence and their values are treated like option arguments. + +'libopts' will search in 2 places for configuration files: + * $PWD + * $HOME + The environment variables 'PWD', and 'HOME' are expanded and replaced +when 'columns' runs. For any of these that are plain files, they are +simply processed. For any that are directories, then a file named +'.columnsrc' is searched for within that directory and processed. + + Configuration files may be in a wide variety of formats. The basic +format is an option name followed by a value (argument) on the same +line. Values may be separated from the option name with a colon, equal +sign or simply white space. Values may be continued across multiple +lines by escaping the newline with a backslash. + + Multiple programs may also share the same initialization file. +Common options are collected at the top, followed by program specific +segments. The segments are separated by lines like: + [COLUMNS] +or by + <?program columns> +Do not mix these styles within one configuration file. + + Compound values and carefully constructed string values may also be +specified using XML syntax: + <option-name> + <sub-opt>...<...>...</sub-opt> + </option-name> +yielding an 'option-name.sub-opt' string value of + "...<...>..." + 'AutoOpts' does not track suboptions. You simply note that it is a +hierarchicly valued option. 'AutoOpts' does provide a means for +searching the associated name/value pair list (see: optionFindValue). + + The command line options relating to configuration and/or usage help +are: + +version (-v) +............ + +Print the program version to standard out, optionally with licensing +information, then exit 0. The optional argument specifies how much +licensing detail to provide. The default is to print just the version. +The licensing information may be selected with an option argument. Only +the first letter of the argument is examined: + +'version' + Only print the version. This is the default. +'copyright' + Name the copyright usage licensing terms. +'verbose' + Print the full copyright usage licensing terms. + + +File: autogen.info, Node: columns exit status, Next: columns See Also, Prev: columns config, Up: columns Invocation + +8.5.7 columns exit status +------------------------- + +One of the following exit values will be returned: +'0 (EXIT_SUCCESS)' + Successful program execution. +'1 (EXIT_FAILURE)' + The operation failed or the command syntax was not valid. +'66 (EX_NOINPUT)' + A specified configuration file could not be loaded. +'70 (EX_SOFTWARE)' + libopts had an internal operational error. Please report it to + autogen-users@lists.sourceforge.net. Thank you. + + +File: autogen.info, Node: columns See Also, Prev: columns exit status, Up: columns Invocation + +8.5.8 columns See Also +---------------------- + +This program is documented more fully in the Columns section of the +Add-On chapter in the 'AutoGen' Info system documentation. + + +File: autogen.info, Node: getdefs Invocation, Next: xml2ag Invocation, Prev: columns Invocation, Up: Add-Ons + +8.6 Invoking getdefs +==================== + +If no 'input' argument is provided or is set to simply "-", and if +'stdin' is not a 'tty', then the list of input files will be read from +'stdin'. This program extracts AutoGen definitions from a list of +source files. Definitions are delimited by '/*=<entry-type> +<entry-name>\n' and '=*/\n'. From that, this program creates a +definition of the following form: + + #line nnn "source-file-name" + entry_type = { + name = entry_name; + ... + }; + + 1. The ellipsis '...' is filled in by text found between the two + delimiters. Each line of text is stripped of anything before the + first asterisk, then leading asterisks, then any leading or + trailing white space. + + 2. If what is left starts with what looks like a name followed by a + colon, then it is interpreted as a name followed by a value. + + 3. If the first character of the value is either a single or double + quote, then you are responsible for quoting the text as it gets + inserted into the output definitions. So, if you want whitespace + at the beginnings of the lines of text, you must do something like + this: + + * mumble: + * " this is some\n" + * " indented text." + + 4. If the '<entry-name>' is followed by a comma, the word 'ifdef' (or + 'ifndef') and a name 'if_name', then the above entry will be under + 'ifdef' control. + + /*=group entry_name, ifdef FOO + * attr: attribute value + =*/ + + Will produce the following: + + #ifdef FOO + #line nnn "source-file-name" + group = { + name = entry_name; + attr = 'attribute value'; + }; + #endif + + 5. If you use of the 'subblock' option, you can specify a nested + value, *Note getdefs subblock::. That is, this text: + + * arg: int, this, what-it-is + + with the '--subblock=arg=type,name,doc' option would yield: + + arg = { type = int; name = this; doc = what-it-is; }; + + This section was generated by *AutoGen*, using the 'agtexi-cmd' +template and the option descriptions for the 'getdefs' program. This +software is released under the GNU General Public License, version 3 or +later. + +* Menu: + +* getdefs usage:: getdefs help/usage ('help') +* getdefs def-selection:: def-selection options +* getdefs enumerating:: enumerating options +* getdefs doc-insert:: doc-insert options +* getdefs input-files:: input-files options +* getdefs doc-output:: doc-output options +* getdefs config:: presetting/configuring getdefs +* getdefs exit status:: exit status +* getdefs See Also:: See Also + + +File: autogen.info, Node: getdefs usage, Next: getdefs def-selection, Up: getdefs Invocation + +8.6.1 getdefs help/usage ('help') +--------------------------------- + +This is the automatically generated usage text for getdefs. + + The text printed is the same whether selected with the 'help' option +('help') or the 'more-help' option ('more-help'). 'more-help' will +print the usage text by passing it through a pager program. 'more-help' +is disabled on platforms without a working 'fork(2)' function. The +'PAGER' environment variable is used to select the program, defaulting +to 'more'. Both will exit with a status code of 0. + + getdefs error: invalid option descriptor for version + getdefs (GNU AutoGen) - AutoGen Definition Extraction Tool - Ver. 1.5 + Usage: getdefs [ <option-name>[{=| }<val>] ]... + + Specify which definitions are of interest and what to say about them: + + Arg Option-Name Description + Str defs-to-get Regexp to look for after the "/*=" + Str subblock subblock definition names + - may appear multiple times + Str listattr attribute with list of values + - may appear multiple times + + specify how to number the definitions: + + Arg Option-Name Description + opt ordering Alphabetize or use named file + - disabled as '--no-ordering' + - enabled by default + Num first-index The first index to apply to groups + + Definition insertion options: + + Arg Option-Name Description + opt filelist Insert source file names into defs + Str assign Global assignments + - may appear multiple times + Str common-assign Assignments common to all blocks + - may appear multiple times + Str copy File(s) to copy into definitions + - may appear multiple times + opt srcfile Insert source file name into each def + opt linenum Insert source line number into each def + + specify which files to search for markers: + + Arg Option-Name Description + Str input Input file to search for defs + - may appear multiple times + - default option for unnamed options + + Definition output disposition options:: + + Arg Option-Name Description + Str output Output file to open + - an alternate for 'autogen' + opt autogen Invoke AutoGen with defs + - disabled as '--no-autogen' + - enabled by default + Str template Template Name + Str agarg AutoGen Argument + - prohibits the option 'output' + - may appear multiple times + Str base-name Base name for output file(s) + - prohibits the option 'output' + + Version, usage and configuration options: + + Arg Option-Name Description + + +File: autogen.info, Node: getdefs def-selection, Next: getdefs enumerating, Prev: getdefs usage, Up: getdefs Invocation + +8.6.2 def-selection options +--------------------------- + +Specify which definitions are of interest and what to say about them. + +defs-to-get option. +................... + +This is the "regexp to look for after the "/*="" option. This option +takes a string argument 'reg-ex'. If you want definitions only from a +particular category, or even with names matching particular patterns, +then specify this regular expression for the text that must follow the +'/*='. + +subblock option. +................ + +This is the "subblock definition names" option. This option takes a +string argument 'sub-def'. + +This option has some usage constraints. It: + * may appear an unlimited number of times. + + This option is used to create shorthand entries for nested +definitions. For example, with: +using subblock thus + '--subblock=arg=argname,type,null' +and defining an 'arg' thus + 'arg: this, char *' +will then expand to: + 'arg = { argname = this; type = "char *"; };' + The "this, char *" string is separated at the commas, with the white +space removed. You may use characters other than commas by starting the +value string with a punctuation character other than a single or double +quote character. You may also omit intermediate values by placing the +commas next to each other with no intervening white space. For example, +"+mumble++yes+" will expand to: +'arg = { argname = mumble; null = "yes"; };'. + +listattr option. +................ + +This is the "attribute with list of values" option. This option takes a +string argument 'def'. + +This option has some usage constraints. It: + * may appear an unlimited number of times. + + This option is used to create shorthand entries for definitions that +generally appear several times. That is, they tend to be a list of +values. For example, with: +'listattr=foo' defined, the text: +'foo: this, is, a, multi-list' will then expand to: +'foo = 'this', 'is', 'a', 'multi-list';' +The texts are separated by the commas, with the white space removed. +You may use characters other than commas by starting the value string +with a punctuation character other than a single or double quote +character. + + +File: autogen.info, Node: getdefs enumerating, Next: getdefs doc-insert, Prev: getdefs def-selection, Up: getdefs Invocation + +8.6.3 enumerating options +------------------------- + +specify how to number the definitions. + +ordering option. +................ + +This is the "alphabetize or use named file" option. This option takes +an optional string argument 'file-name'. + +This option has some usage constraints. It: + * can be disabled with -no-ordering. + * It is enabled by default. + + By default, ordering is alphabetical by the entry name. Use, +'no-ordering' if order is unimportant. Use 'ordering' with no argument +to order without case sensitivity. Use 'ordering=<file-name>' if +chronological order is important. getdefs will maintain the text +content of 'file-name'. 'file-name' need not exist. + +first-index option. +................... + +This is the "the first index to apply to groups" option. This option +takes a number argument 'first-index'. By default, the first occurrence +of a named definition will have an index of zero. Sometimes, that needs +to be a reserved value. Provide this option to specify a different +starting point. + + +File: autogen.info, Node: getdefs doc-insert, Next: getdefs input-files, Prev: getdefs enumerating, Up: getdefs Invocation + +8.6.4 doc-insert options +------------------------ + +Definition insertion options. + +filelist option. +................ + +This is the "insert source file names into defs" option. This option +takes an optional string argument 'file'. Inserts the name of each +input file into the output definitions. If no argument is supplied, the +format will be: + infile = '%s'; + If an argument is supplied, that string will be used for the entry +name instead of INFILE. + +assign option. +.............. + +This is the "global assignments" option. This option takes a string +argument 'ag-def'. + +This option has some usage constraints. It: + * may appear an unlimited number of times. + + The argument to each copy of this option will be inserted into the +output definitions, with only a semicolon attached. + +common-assign option. +..................... + +This is the "assignments common to all blocks" option. This option +takes a string argument 'ag-def'. + +This option has some usage constraints. It: + * may appear an unlimited number of times. + + The argument to each copy of this option will be inserted into each +output definition, with only a semicolon attached. + +copy option. +............ + +This is the "file(s) to copy into definitions" option. This option +takes a string argument 'file'. + +This option has some usage constraints. It: + * may appear an unlimited number of times. + + The content of each file named by these options will be inserted into +the output definitions. + +srcfile option. +............... + +This is the "insert source file name into each def" option. This option +takes an optional string argument 'file'. Inserts the name of the input +file where a definition was found into the output definition. If no +argument is supplied, the format will be: + srcfile = '%s'; + If an argument is supplied, that string will be used for the entry +name instead of SRCFILE. + +linenum option. +............... + +This is the "insert source line number into each def" option. This +option takes an optional string argument 'def-name'. Inserts the line +number in the input file where a definition was found into the output +definition. If no argument is supplied, the format will be: + linenum = '%s'; + If an argument is supplied, that string will be used for the entry +name instead of LINENUM. + + +File: autogen.info, Node: getdefs input-files, Next: getdefs doc-output, Prev: getdefs doc-insert, Up: getdefs Invocation + +8.6.5 input-files options +------------------------- + +specify which files to search for markers. + +input option. +............. + +This is the "input file to search for defs" option. This option takes a +string argument 'src-file'. + +This option has some usage constraints. It: + * may appear an unlimited number of times. + + All files that are to be searched for definitions must be named on +the command line or read from 'stdin'. If there is only one 'input' +option and it is the string, "-", then the input file list is read from +'stdin'. If a command line argument is not an option name and does not +contain an assignment operator ('='), then it defaults to being an input +file name. At least one input file must be specified. + + +File: autogen.info, Node: getdefs doc-output, Next: getdefs config, Prev: getdefs input-files, Up: getdefs Invocation + +8.6.6 doc-output options +------------------------ + +Definition output disposition options:. + +output option. +.............. + +This is the "output file to open" option. This option takes a string +argument 'file'. + +This option has some usage constraints. It: + * is a member of the autogen class of options. + + If you are not sending the output to an AutoGen process, you may name +an output file instead. + +autogen option. +............... + +This is the "invoke autogen with defs" option. This option takes an +optional string argument 'ag-cmd'. + +This option has some usage constraints. It: + * can be disabled with -no-autogen. + * It is enabled by default. + * is a member of the autogen class of options. + + This is the default output mode. Specifying 'no-autogen' is +equivalent to 'output=-'. If you supply an argument to this option, +that program will be started as if it were AutoGen and its standard in +will be set to the output definitions of this program. + +template option. +................ + +This is the "template name" option. This option takes a string argument +'file'. Specifies the template name to be used for generating the final +output. + +agarg option. +............. + +This is the "autogen argument" option. This option takes a string +argument 'ag-opt'. + +This option has some usage constraints. It: + * may appear an unlimited number of times. + * must not appear in combination with any of the following options: + output. + + This is a pass-through argument. It allows you to specify any +arbitrary argument to be passed to AutoGen. + +base-name option. +................. + +This is the "base name for output file(s)" option. This option takes a +string argument 'name'. + +This option has some usage constraints. It: + * must not appear in combination with any of the following options: + output. + + When output is going to AutoGen, a base name must either be supplied +or derived. If this option is not supplied, then it is taken from the +'template' option. If that is not provided either, then it is set to +the base name of the current directory. + + +File: autogen.info, Node: getdefs config, Next: getdefs exit status, Prev: getdefs doc-output, Up: getdefs Invocation + +8.6.7 presetting/configuring getdefs +------------------------------------ + +Any option that is not marked as not presettable may be preset by +loading values from configuration ("rc" or "ini") files. + +'libopts' will search in '/dev/null' for configuration (option) data. +If this is a plain file, it is simply processed. If it is a directory, +then a file named '.getdefsrc' is searched for within that directory. + + Configuration files may be in a wide variety of formats. The basic +format is an option name followed by a value (argument) on the same +line. Values may be separated from the option name with a colon, equal +sign or simply white space. Values may be continued across multiple +lines by escaping the newline with a backslash. + + Multiple programs may also share the same initialization file. +Common options are collected at the top, followed by program specific +segments. The segments are separated by lines like: + [GETDEFS] +or by + <?program getdefs> +Do not mix these styles within one configuration file. + + Compound values and carefully constructed string values may also be +specified using XML syntax: + <option-name> + <sub-opt>...<...>...</sub-opt> + </option-name> +yielding an 'option-name.sub-opt' string value of + "...<...>..." + 'AutoOpts' does not track suboptions. You simply note that it is a +hierarchicly valued option. 'AutoOpts' does provide a means for +searching the associated name/value pair list (see: optionFindValue). + + The command line options relating to configuration and/or usage help +are: + +version +....... + +Print the program version to standard out, optionally with licensing +information, then exit 0. The optional argument specifies how much +licensing detail to provide. The default is to print just the version. +The licensing information may be selected with an option argument. Only +the first letter of the argument is examined: + +'version' + Only print the version. This is the default. +'copyright' + Name the copyright usage licensing terms. +'verbose' + Print the full copyright usage licensing terms. + + +File: autogen.info, Node: getdefs exit status, Next: getdefs See Also, Prev: getdefs config, Up: getdefs Invocation + +8.6.8 getdefs exit status +------------------------- + +One of the following exit values will be returned: +'0 (EXIT_SUCCESS)' + Successful program execution. +'1 (EXIT_FAILURE)' + The operation failed or the command syntax was not valid. +'2 (EXIT_INVALID_INPUT)' + An input file was specified that is not a file +'3 (EXIT_NO_MEM)' + Insufficient memory for operation +'66 (EX_NOINPUT)' + A specified configuration file could not be loaded. +'70 (EX_SOFTWARE)' + libopts had an internal operational error. Please report it to + autogen-users@lists.sourceforge.net. Thank you. + + +File: autogen.info, Node: getdefs See Also, Prev: getdefs exit status, Up: getdefs Invocation + +8.6.9 getdefs See Also +---------------------- + +This program is documented more fully in the Getdefs section of the +Add-On chapter in the 'AutoGen' Info system documentation. + + +File: autogen.info, Node: xml2ag Invocation, Next: snprintfv, Prev: getdefs Invocation, Up: Add-Ons + +8.7 Invoking xml2ag +=================== + +This program will convert any arbitrary XML file into equivalent AutoGen +definitions, and invoke AutoGen. The template used will be derived from +either: + * The *-override-tpl* command line option + * A top level XML attribute named, "'template'" +One or the other *must* be provided, or the program will exit with a +failure message. + + The _base-name_ for the output will similarly be either: + * The *-base-name* command line option. + * The base name of the '.xml' file. + + The definitions derived from XML generally have an extra layer of +definition. Specifically, this XML input: + <mumble attr="foo"> + mumble-1 + <grumble> + grumble, grumble, grumble. + </grumble>mumble, mumble + </mumble> + Will get converted into this: + mumble = { + grumble = { + text = 'grumble, grumble, grumble'; + }; + text = 'mumble-1'; + text = 'mumble, mumble'; + }; + Please notice that some information is lost. AutoGen cannot tell +that "grumble" used to lie between the mumble texts. Also please note +that you cannot assign: + grumble = 'grumble, grumble, grumble.'; + because if another "grumble" has an attribute or multiple texts, it +becomes impossible to have the definitions be the same type (compound or +text values). + + This section was generated by *AutoGen*, using the 'agtexi-cmd' +template and the option descriptions for the 'xml2ag' program. This +software is released under the GNU General Public License, version 3 or +later. + +* Menu: + +* xml2ag usage:: xml2ag help/usage ('--help') +* xml2ag the-xml2ag-option:: the-xml2ag-option options +* xml2ag autogen-options:: autogen-options options +* xml2ag exit status:: exit status + + +File: autogen.info, Node: xml2ag usage, Next: xml2ag the-xml2ag-option, Up: xml2ag Invocation + +8.7.1 xml2ag help/usage ('--help') +---------------------------------- + +This is the automatically generated usage text for xml2ag. + + The text printed is the same whether selected with the 'help' option +('--help') or the 'more-help' option ('--more-help'). 'more-help' will +print the usage text by passing it through a pager program. 'more-help' +is disabled on platforms without a working 'fork(2)' function. The +'PAGER' environment variable is used to select the program, defaulting +to 'more'. Both will exit with a status code of 0. + + xml2ag (GNU AutoGen) - XML to AutoGen Definiton Converter - Ver. 5.18.16 + Usage: xml2ag [ -<flag> [<val>] | --<name>[{=| }<val>] ]... [ <def-file> ] + + All other options are derived from autogen: + + Flg Arg Option-Name Description + -O Str output Output file in lieu of AutoGen processing + + All other options: + + Flg Arg Option-Name Description + -L Str templ-dirs Search for templates in DIR + - may appear multiple times + -T Str override-tpl Use TPL-FILE for the template + Str definitions Read definitions from FILE + Str shell name or path name of shell to use + -m no no-fmemopen Do not use in-mem streams + Str equate characters considered equivalent + -b Str base-name Specify NAME as the base name for output + no source-time set mod times to latest source + no writable Allow output files to be writable + - disabled as '--not-writable' + Num loop-limit Limit on increment loops + - is scalable with a suffix: k/K/m/M/g/G/t/T + - it must lie in one of the ranges: + -1 exactly, or + 1 to 16777216 + -t Num timeout Limit server shell operations to SECONDS + - it must be in the range: + 0 to 3600 + KWd trace tracing level of detail + Str trace-out tracing output file or filter + no show-defs Show the definition tree + no used-defines Show the definitions used + -C no core Leave a core dump on a failure exit + -s Str skip-suffix Skip the file with this SUFFIX + - prohibits the option 'select-suffix' + - may appear multiple times + -o Str select-suffix specify this output suffix + - may appear multiple times + -D Str define name to add to definition list + - may appear multiple times + -U Str undefine definition list removal pattern + - an alternate for 'define' + -M opt make-dep emit make dependency file + - may appear multiple times + + Version, usage and configuration options: + + Flg Arg Option-Name Description + -v opt version output version information and exit + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + + Options are specified by doubled hyphens and their name or by a single + hyphen and the flag character. + This program will convert any arbitrary XML file into equivalent AutoGen + definitions, and invoke AutoGen. + + The valid "trace" option keywords are: + nothing debug-message server-shell templates block-macros + expressions everything + or an integer from 0 through 6 + The template will be derived from either: * the ``--override-tpl'' command + line option * a top level XML attribute named, "template" + + The ``base-name'' for the output will similarly be either: * the + ``--base-name'' command line option * the base name of the .xml file + + Please send bug reports to: <autogen-users@lists.sourceforge.net> + + +File: autogen.info, Node: xml2ag the-xml2ag-option, Next: xml2ag autogen-options, Prev: xml2ag usage, Up: xml2ag Invocation + +8.7.2 the-xml2ag-option options +------------------------------- + +All other options are derived from autogen. + +output option (-O). +................... + +This is the "output file in lieu of autogen processing" option. This +option takes a string argument 'file'. By default, the output is handed +to an AutoGen for processing. However, you may save the definitions to +a file instead. + + +File: autogen.info, Node: xml2ag autogen-options, Next: xml2ag exit status, Prev: xml2ag the-xml2ag-option, Up: xml2ag Invocation + +8.7.3 autogen-options options +----------------------------- + +All other options. These options are mostly just passed throug to +'autogen'. The one exception is '--override-tpl' which replaces the +default template in the output definitions. It does not get passed +through on the command line. + +templ-dirs option (-L). +....................... + +This is the "search for templates in 'dir'" option. This option takes a +string argument 'DIR'. + +This option has some usage constraints. It: + * may appear an unlimited number of times. + + Pass-through AutoGen argument + +override-tpl option (-T). +......................... + +This is the "use 'tpl-file' for the template" option. This option takes +a string argument 'TPL-FILE'. Pass-through AutoGen argument + +definitions option. +................... + +This is the "read definitions from 'file'" option. This option takes a +string argument 'FILE'. Pass-through AutoGen argument + +shell option. +............. + +This is the "name or path name of shell to use" option. This option +takes a string argument 'shell'. Pass-through AutoGen argument + +no-fmemopen option (-m). +........................ + +This is the "do not use in-mem streams" option. Pass-through AutoGen +argument + +equate option. +.............. + +This is the "characters considered equivalent" option. This option +takes a string argument 'char-list'. Pass-through AutoGen argument + +base-name option (-b). +...................... + +This is the "specify 'name' as the base name for output" option. This +option takes a string argument 'NAME'. Pass-through AutoGen argument + +source-time option. +................... + +This is the "set mod times to latest source" option. Pass-through +AutoGen argument + +writable option. +................ + +This is the "allow output files to be writable" option. + +This option has some usage constraints. It: + * can be disabled with -not-writable. + + Pass-through AutoGen argument + +loop-limit option. +.................. + +This is the "limit on increment loops" option. This option takes a +number argument 'lim'. Pass-through AutoGen argument + +timeout option (-t). +.................... + +This is the "limit server shell operations to 'seconds'" option. This +option takes a number argument 'SECONDS'. Pass-through AutoGen argument + +trace option. +............. + +This is the "tracing level of detail" option. This option takes a +keyword argument 'level'. + +This option has some usage constraints. It: + * This option takes a keyword as its argument. The argument sets an + enumeration value that can be tested by comparing the option value + macro (OPT_VALUE_TRACE). The available keywords are: + nothing debug-message server-shell + templates block-macros expressions + everything + + or their numeric equivalent. + + Pass-through AutoGen argument + +trace-out option. +................. + +This is the "tracing output file or filter" option. This option takes a +string argument 'file'. Pass-through AutoGen argument + +show-defs option. +................. + +This is the "show the definition tree" option. Pass-through AutoGen +argument + +used-defines option. +.................... + +This is the "show the definitions used" option. Pass-through AutoGen +argument + +core option (-C). +................. + +This is the "leave a core dump on a failure exit" option. + +This option has some usage constraints. It: + * must be compiled in by defining 'HAVE_SYS_RESOURCE_H' during the + compilation. + + Many systems default to a zero sized core limit. If the system has +the sys/resource.h header and if this option is supplied, then in the +failure exit path, autogen will attempt to set the soft core limit to +whatever the hard core limit is. If that does not work, then an +administrator must raise the hard core size limit. + +skip-suffix option (-s). +........................ + +This is the "skip the file with this 'suffix'" option. This option +takes a string argument 'SUFFIX'. + +This option has some usage constraints. It: + * may appear an unlimited number of times. + * must not appear in combination with any of the following options: + select-suffix. + + Pass-through AutoGen argument + +select-suffix option (-o). +.......................... + +This is the "specify this output suffix" option. This option takes a +string argument 'SUFFIX'. + +This option has some usage constraints. It: + * may appear an unlimited number of times. + + Pass-through AutoGen argument + +define option (-D). +................... + +This is the "name to add to definition list" option. This option takes +a string argument 'value'. + +This option has some usage constraints. It: + * may appear an unlimited number of times. + + Pass-through AutoGen argument + +undefine option (-U). +..................... + +This is the "definition list removal pattern" option. This option takes +a string argument 'name-pat'. + +This option has some usage constraints. It: + * may appear an unlimited number of times. + + Pass-through AutoGen argument + +make-dep option (-M). +..................... + +This is the "emit make dependency file" option. This option takes an +optional string argument 'type'. + +This option has some usage constraints. It: + * may appear an unlimited number of times. + + Pass-through AutoGen argument + + +File: autogen.info, Node: xml2ag exit status, Prev: xml2ag autogen-options, Up: xml2ag Invocation + +8.7.4 xml2ag exit status +------------------------ + +One of the following exit values will be returned: +'0 (EXIT_SUCCESS)' + Successful program execution. +'1 (EXIT_FAILURE)' + The operation failed or the command syntax was not valid. + + +File: autogen.info, Node: snprintfv, Prev: xml2ag Invocation, Up: Add-Ons + +8.8 Replacement for Stdio Formatting Library +============================================ + +Using the 'printf' formatting routines in a portable fashion has always +been a pain, and this package has been way more pain than anyone ever +imagined. Hopefully, with this release of snprintfv, the pain is now +over for all time. + + The issues with portable usage are these: + + 1. Argument number specifiers are often either not implemented or are + buggy. Even GNU libc, version 1 got it wrong. + + 2. ANSI/ISO "forgot" to provide a mechanism for computing argument + lists for vararg procedures. + + 3. The argument array version of printf ('printfv()') is not generally + available, does not work with the native printf, and does not have + a working argument number specifier in the format specification. + (Last I knew, anyway.) + + 4. You cannot fake varargs by calling 'vprintf()' with an array of + arguments, because ANSI does not require such an implementation and + some vendors play funny tricks because they are allowed to. + + These four issues made it impossible for AutoGen to ship without its +own implementation of the 'printf' formatting routines. Since we were +forced to do this, we decided to make the formatting routines both +better and more complete :-). We addressed these issues and added the +following features to the common printf API: + + 5. The formatted output can be written to + + * a string allocated by the formatting function ('asprintf()'). + * a file descriptor instead of a file stream ('dprintf()'). + * a user specified stream ('stream_printf()'). + + 6. The formatting functions can be augmented with your own functions. + These functions are allowed to consume more than one character from + the format, but must commence with a unique character. For + example, + + "%{struct stat}\n" + + might be used with '{' registered to a procedure that would look up + "struct stat" in a symbol table and do appropriate things, + consuming the format string through the '}' character. + + Gary V. Vaughan was generous enough to supply this implementation. +Many thanks!! + + For further details, the reader is referred to the snprintfv +documentation. These functions are also available in the template +processing as 'sprintf' (*note SCM sprintf::), 'printf' (*note SCM +printf::), 'fprintf' (*note SCM fprintf::), and 'shellf' (*note SCM +shellf::). + + +File: autogen.info, Node: Future, Next: Copying This Manual, Prev: Add-Ons, Up: Top + +9 Some ideas for the future. +**************************** + +Here are some things that might happen in the distant future. + + * Fix up current tools that contain miserably complex perl, shell, + sed, awk and m4 scripts to instead use this tool. + + +File: autogen.info, Node: Copying This Manual, Next: Concept Index, Prev: Future, Up: Top + +Appendix A Copying This Manual +****************************** + +You may copy this manual under the terms of the FDL (the GNU Free +Documentation License (http://gnu.org/licenses/fdl.texi)). + + +File: autogen.info, Node: Concept Index, Next: Function Index, Prev: Copying This Manual, Up: Top + +Concept Index +************* + +�[index�] +* Menu: + +* .: naming values. (line 23) +* .def file: Definitions File. (line 6) +* .tpl file: Template File. (line 6) +* Alternate Definition: Alternate Definition. + (line 6) +* assert: Directives. (line 26) +* assert directive: Directives. (line 26) +* Augmenting AutoGen: Augmenting AutoGen. (line 6) +* AutoEvents: AutoEvents. (line 6) +* AutoFSM: AutoFSM. (line 6) +* autogen: autogen Invocation. (line 6) +* AutoGen Definition Extraction Tool: getdefs Invocation. (line 6) +* autogen help: autogen usage. (line 6) +* autogen-base-name: autogen out-handling. + (line 11) +* autogen-core: autogen debug-tpl. (line 138) +* autogen-define: autogen processing. (line 46) +* autogen-definitions: autogen input-select. + (line 40) +* autogen-equate: autogen input-select. + (line 90) +* autogen-loop-limit: autogen debug-tpl. (line 13) +* autogen-make-dep: autogen dep-track. (line 11) +* autogen-no-abort: autogen autoopts-opts. + (line 11) +* autogen-no-fmemopen: autogen input-select. + (line 74) +* autogen-override-tpl: autogen input-select. + (line 26) +* autogen-select-suffix: autogen processing. (line 31) +* autogen-shell: autogen input-select. + (line 58) +* autogen-show-defs: autogen debug-tpl. (line 106) +* autogen-skip-suffix: autogen processing. (line 13) +* autogen-source-time: autogen out-handling. + (line 33) +* autogen-templ-dirs: autogen input-select. + (line 12) +* autogen-timeout: autogen debug-tpl. (line 23) +* autogen-trace: autogen debug-tpl. (line 40) +* autogen-trace-out: autogen debug-tpl. (line 95) +* autogen-undefine: autogen processing. (line 76) +* autogen-used-defines: autogen debug-tpl. (line 120) +* autogen-writable: autogen out-handling. + (line 47) +* AutoInfo: AutoInfo. (line 6) +* AutoMan pages: AutoMan pages. (line 6) +* automatic options: automatic options. (line 6) +* autoopts: AutoOpts. (line 6) +* autoopts <1>: Caveats. (line 34) +* AutoOpts API: AutoOpts API. (line 6) +* autoopts directives: config directives. (line 6) +* AutoXDR: AutoXDR. (line 6) +* backtrack: naming values. (line 24) +* Columnize Input Text: columns Invocation. (line 6) +* columns: columns Invocation. (line 6) +* columns help: columns usage. (line 6) +* columns-by-columns: columns ordering. (line 11) +* columns-col-width: columns dimensions. (line 29) +* columns-columns: columns dimensions. (line 21) +* columns-ending: columns treatment. (line 89) +* columns-fill: columns treatment. (line 20) +* columns-first-indent: columns treatment. (line 42) +* columns-format: columns treatment. (line 67) +* columns-indent: columns treatment. (line 34) +* columns-input: columns input-text. (line 11) +* columns-line-separation: columns treatment. (line 82) +* columns-separation: columns treatment. (line 75) +* columns-sort: columns ordering. (line 19) +* columns-spread: columns treatment. (line 11) +* columns-tab-width: columns dimensions. (line 37) +* columns-width: columns dimensions. (line 11) +* comments: Comments. (line 6) +* Common Option Attributes: Common Attributes. (line 6) +* compound definitions: Definitions. (line 43) +* concat-string: concat-string. (line 6) +* conditional emit: IF. (line 6) +* conditional emit <1>: WHILE. (line 6) +* configuration file: opt-attr no-preset. (line 6) +* configuration file <1>: automatic options. (line 67) +* configuration file <2>: automatic options. (line 83) +* configuration file <3>: Option Processing Data. + (line 40) +* Configuration File: config example. (line 6) +* Configuration File <1>: Config File Format. (line 6) +* configuration file <4>: shell options. (line 6) +* Configuration File example: config example. (line 6) +* configuring: configuring. (line 6) +* define: Directives. (line 41) +* define directive: Directives. (line 41) +* define macro: DEFINE. (line 6) +* Definition Index: Index Assignments. (line 6) +* definitions: Definitions. (line 6) +* definitions file: Definitions File. (line 6) +* design goals: Generalities. (line 11) +* directives: Directives. (line 6) +* diversion: output controls. (line 6) +* documentation attributes: documentation attributes. + (line 6) +* Dynamic Definition Text: Dynamic Text. (line 6) +* elif: Directives. (line 49) +* elif directive: Directives. (line 49) +* else: Directives. (line 53) +* else directive: Directives. (line 53) +* endif: Directives. (line 58) +* endif directive: Directives. (line 58) +* endmac: Directives. (line 62) +* endmac directive: Directives. (line 62) +* endshell: Directives. (line 65) +* endshell directive: Directives. (line 65) +* environrc: environrc. (line 6) +* error: Directives. (line 68) +* error directive: Directives. (line 68) +* example, simple AutoGen: Example Usage. (line 6) +* example, simple AutoOpts: Quick Start. (line 6) +* expression syntax: expression syntax. (line 6) +* features: Features. (line 6) +* finite state machine: AutoFSM. (line 6) +* flags-cant: Option Conflict Attributes. + (line 19) +* flags-must: Option Conflict Attributes. + (line 15) +* fOptState: Option Processing Data. + (line 28) +* for loop: FOR. (line 6) +* futures: Future. (line 6) +* getdefs: getdefs Invocation. (line 6) +* getdefs help: getdefs usage. (line 6) +* getdefs-agarg: getdefs doc-output. (line 46) +* getdefs-assign: getdefs doc-insert. (line 22) +* getdefs-autogen: getdefs doc-output. (line 23) +* getdefs-base-name: getdefs doc-output. (line 60) +* getdefs-common-assign: getdefs doc-insert. (line 34) +* getdefs-copy: getdefs doc-insert. (line 46) +* getdefs-defs-to-get: getdefs def-selection. + (line 11) +* getdefs-filelist: getdefs doc-insert. (line 11) +* getdefs-first-index: getdefs enumerating. (line 27) +* getdefs-input: getdefs input-files. (line 11) +* getdefs-linenum: getdefs doc-insert. (line 69) +* getdefs-listattr: getdefs def-selection. + (line 45) +* getdefs-ordering: getdefs enumerating. (line 11) +* getdefs-output: getdefs doc-output. (line 11) +* getdefs-srcfile: getdefs doc-insert. (line 58) +* getdefs-subblock: getdefs def-selection. + (line 20) +* getdefs-template: getdefs doc-output. (line 39) +* getopt_long: getopt_long. (line 6) +* gnu: Caveats. (line 29) +* here-string: here-string. (line 6) +* ident: Directives. (line 72) +* ident directive: Directives. (line 72) +* identification: Identification. (line 6) +* if: Directives. (line 75) +* if directive: Directives. (line 75) +* if test: IF. (line 6) +* ifdef: Directives. (line 79) +* ifdef directive: Directives. (line 79) +* ifndef: Directives. (line 85) +* ifndef directive: Directives. (line 85) +* immediate action: Immediate Action. (line 6) +* include: Directives. (line 89) +* include directive: Directives. (line 89) +* information attributes: information attributes. + (line 6) +* Installing: installing. (line 6) +* Internationalizing AutoOpts: i18n. (line 6) +* Internationalizing Options: Internationalizing Options. + (line 6) +* Introduction: Introduction. (line 6) +* let: Directives. (line 94) +* let directive: Directives. (line 94) +* library attributes: library attributes. (line 6) +* Licensing: Licensing. (line 6) +* line: Directives. (line 97) +* line directive: Directives. (line 97) +* looping, for: FOR. (line 6) +* m4: Testimonial. (line 41) +* macdef: Directives. (line 104) +* macdef directive: Directives. (line 104) +* macro syntax: AGMacro syntax. (line 6) +* macro, pseudo: Template File. (line 10) +* main procedure: Generated main. (line 6) +* misuse-usage: Caveats. (line 45) +* named option mode: presentation attributes. + (line 15) +* Naming Conflicts: Naming Conflicts. (line 6) +* naming values: naming values. (line 6) +* native macros: native macros. (line 6) +* no-misuse-usage: Caveats. (line 40) +* optActualIndex: Option Processing Data. + (line 16) +* optActualValue: Option Processing Data. + (line 17) +* optIndex: Option Processing Data. + (line 11) +* option: Directives. (line 110) +* Option Argument Handling: Option Argument Handling. + (line 6) +* Option Arguments: Option Arguments. (line 6) +* option attributes: option attributes. (line 6) +* Option Conflict Attributes: Option Conflict Attributes. + (line 6) +* Option Definitions: Option Definitions. (line 6) +* option descriptor: option descriptor. (line 6) +* option directive: Directives. (line 110) +* Option Processing Data: Option Processing Data. + (line 6) +* optOccCt: Option Processing Data. + (line 22) +* optValue: Option Processing Data. + (line 12) +* pragma: Directives. (line 125) +* pragma directive: Directives. (line 125) +* predefines: Predefines. (line 6) +* program attributes: program attributes. (line 6) +* pseudo macro: Template File. (line 10) +* pseudo macro <1>: pseudo macro. (line 6) +* pzLastArg: Option Processing Data. + (line 80) +* pzProgName: Option Processing Data. + (line 87) +* pzProgPath: Option Processing Data. + (line 91) +* rcfile: loading rcfile. (line 6) +* rcfile <1>: config example. (line 6) +* Redirecting Output: output controls. (line 6) +* remote procedure call: AutoXDR. (line 6) +* Required Attributes: Required Attributes. (line 6) +* RPC: AutoXDR. (line 6) +* rpcgen: AutoXDR. (line 6) +* sample rcfile: sample rcfile. (line 6) +* shell: Directives. (line 128) +* shell directive: Directives. (line 128) +* shell options: Presetting Options. (line 6) +* shell options <1>: shell options. (line 6) +* shell-generated string: shell-generated. (line 6) +* Signal Names: signal names. (line 6) +* simple definitions: Definitions. (line 44) +* standard options: standard options. (line 6) +* string, double quote: double-quote-string. (line 6) +* string, shell output: shell-generated. (line 6) +* string, single quote: single-quote-string. (line 6) +* template file: Identification. (line 21) +* template file <1>: Template File. (line 6) +* The Automated Program Generator: autogen Invocation. (line 6) +* undef: Directives. (line 136) +* undef directive: Directives. (line 136) +* using AutoOpts: Using AutoOpts. (line 6) +* while test: WHILE. (line 6) +* XDR: AutoXDR. (line 6) +* XML to AutoGen Definiton Converter: xml2ag Invocation. (line 6) +* xml2ag: xml2ag Invocation. (line 6) +* xml2ag help: xml2ag usage. (line 6) +* xml2ag-base-name: xml2ag autogen-options. + (line 55) +* xml2ag-core: xml2ag autogen-options. + (line 125) +* xml2ag-define: xml2ag autogen-options. + (line 164) +* xml2ag-definitions: xml2ag autogen-options. + (line 31) +* xml2ag-equate: xml2ag autogen-options. + (line 49) +* xml2ag-loop-limit: xml2ag autogen-options. + (line 77) +* xml2ag-make-dep: xml2ag autogen-options. + (line 186) +* xml2ag-no-fmemopen: xml2ag autogen-options. + (line 43) +* xml2ag-output: xml2ag the-xml2ag-option. + (line 11) +* xml2ag-override-tpl: xml2ag autogen-options. + (line 25) +* xml2ag-select-suffix: xml2ag autogen-options. + (line 153) +* xml2ag-shell: xml2ag autogen-options. + (line 37) +* xml2ag-show-defs: xml2ag autogen-options. + (line 113) +* xml2ag-skip-suffix: xml2ag autogen-options. + (line 140) +* xml2ag-source-time: xml2ag autogen-options. + (line 61) +* xml2ag-templ-dirs: xml2ag autogen-options. + (line 14) +* xml2ag-timeout: xml2ag autogen-options. + (line 83) +* xml2ag-trace: xml2ag autogen-options. + (line 89) +* xml2ag-trace-out: xml2ag autogen-options. + (line 107) +* xml2ag-undefine: xml2ag autogen-options. + (line 175) +* xml2ag-used-defines: xml2ag autogen-options. + (line 119) +* xml2ag-writable: xml2ag autogen-options. + (line 67) + + +File: autogen.info, Node: Function Index, Prev: Concept Index, Up: Top + +Function Index +************** + +�[index�] +* Menu: + +* *=: SCM *=. (line 6) +* *=*: SCM *=*. (line 6) +* *==: SCM *==. (line 6) +* *==*: SCM *==*. (line 6) +* *~: SCM *~. (line 6) +* *~*: SCM *~*. (line 6) +* *~~: SCM *~~. (line 6) +* *~~*: SCM *~~*. (line 6) +* =: SCM =. (line 6) +* =*: SCM =*. (line 6) +* ==: SCM ==. (line 6) +* ==*: SCM ==*. (line 6) +* ~: SCM ~. (line 6) +* ~*: SCM ~*. (line 6) +* ~~: SCM ~~. (line 6) +* ~~*: SCM ~~*. (line 6) +* ag-fprintf: SCM ag-fprintf. (line 6) +* ag-function?: SCM ag-function?. (line 6) +* agpl: SCM agpl. (line 6) +* ao_string_tokenize: libopts-ao_string_tokenize. + (line 6) +* autogen-version: SCM autogen-version. (line 6) +* base-name: SCM base-name. (line 6) +* BREAK: BREAK. (line 6) +* bsd: SCM bsd. (line 6) +* c-file-line-fmt: SCM c-file-line-fmt. (line 6) +* c-string: SCM c-string. (line 6) +* CASE: CASE. (line 6) +* chdir: SCM chdir. (line 6) +* CLEAR_OPT: CLEAR_OPT. (line 6) +* COMMENT: COMMENT. (line 6) +* configFileLoad: libopts-configFileLoad. + (line 6) +* CONTINUE: CONTINUE. (line 6) +* count: SCM count. (line 6) +* COUNT_OPT: COUNT_OPT. (line 6) +* DEBUG: DEBUG. (line 6) +* def-file: SCM def-file. (line 6) +* def-file-line: SCM def-file-line. (line 6) +* DEFINE: DEFINE. (line 6) +* DESC: DESC. (line 6) +* DISABLE_OPT_name: DISABLE_OPT_name. (line 6) +* dne: SCM dne. (line 6) +* ELIF: ELIF. (line 6) +* ELSE: ELSE. (line 6) +* emit: SCM emit. (line 6) +* emit-string-table: SCM emit-string-table. (line 6) +* ENABLED_OPT: ENABLED_OPT. (line 6) +* ENDDEF: ENDDEF. (line 6) +* ENDFOR: ENDFOR. (line 6) +* ENDIF: ENDIF. (line 6) +* ENDWHILE: ENDWHILE. (line 6) +* error: SCM error. (line 6) +* error-source-line: SCM error-source-line. (line 6) +* ERRSKIP_OPTERR: ERRSKIP_OPTERR. (line 6) +* ERRSTOP_OPTERR: ERRSTOP_OPTERR. (line 6) +* ESAC: ESAC. (line 6) +* exist?: SCM exist?. (line 6) +* EXPR: EXPR. (line 6) +* extract: SCM extract. (line 6) +* find-file: SCM find-file. (line 6) +* first-for?: SCM first-for?. (line 6) +* FOR: FOR. (line 6) +* for-by: SCM for-by. (line 6) +* for-from: SCM for-from. (line 6) +* for-index: SCM for-index. (line 6) +* for-sep: SCM for-sep. (line 6) +* for-to: SCM for-to. (line 6) +* format-arg-count: SCM format-arg-count. (line 6) +* found-for?: SCM found-for?. (line 6) +* fprintf: SCM fprintf. (line 6) +* get: SCM get. (line 6) +* get-c-name: SCM get-c-name. (line 6) +* get-down-name: SCM get-down-name. (line 6) +* get-up-name: SCM get-up-name. (line 6) +* gperf: SCM gperf. (line 6) +* gperf-code: SCM gperf-code. (line 6) +* gpl: SCM gpl. (line 6) +* HAVE_OPT: HAVE_OPT. (line 6) +* hide-email: SCM hide-email. (line 6) +* high-lim: SCM high-lim. (line 6) +* html-escape-encode: SCM html-escape-encode. + (line 6) +* IF: IF. (line 6) +* in?: SCM in?. (line 6) +* INCLUDE: INCLUDE. (line 6) +* insert-file: SCM insert-file. (line 6) +* insert-suspended: SCM insert-suspended. (line 6) +* INVOKE: INVOKE. (line 6) +* ISSEL_OPT: ISSEL_OPT. (line 6) +* ISUNUSED_OPT: ISUNUSED_OPT. (line 6) +* join: SCM join. (line 6) +* kr-string: SCM kr-string. (line 6) +* last-for?: SCM last-for?. (line 6) +* len: SCM len. (line 6) +* lgpl: SCM lgpl. (line 6) +* license: SCM license. (line 6) +* license-description: SCM license-description. + (line 6) +* license-full: SCM license-full. (line 6) +* license-info: SCM license-info. (line 6) +* license-name: SCM license-name. (line 6) +* low-lim: SCM low-lim. (line 6) +* make-gperf: SCM make-gperf. (line 6) +* make-header-guard: SCM make-header-guard. (line 6) +* make-tmp-dir: SCM make-tmp-dir. (line 6) +* makefile-script: SCM makefile-script. (line 6) +* match-value?: SCM match-value?. (line 6) +* max: SCM max. (line 6) +* max-file-time: SCM max-file-time. (line 6) +* min: SCM min. (line 6) +* mk-gettextable: SCM mk-gettextable. (line 6) +* optionFileLoad: libopts-optionFileLoad. + (line 6) +* optionFindNextValue: libopts-optionFindNextValue. + (line 6) +* optionFindValue: libopts-optionFindValue. + (line 6) +* optionFree: libopts-optionFree. (line 6) +* optionGetValue: libopts-optionGetValue. + (line 6) +* optionLoadLine: libopts-optionLoadLine. + (line 6) +* optionMemberList: libopts-optionMemberList. + (line 6) +* optionNextValue: libopts-optionNextValue. + (line 6) +* optionOnlyUsage: libopts-optionOnlyUsage. + (line 6) +* optionPrintVersion: libopts-optionPrintVersion. + (line 6) +* optionPrintVersionAndReturn: libopts-optionPrintVersionAndReturn. + (line 6) +* optionProcess: libopts-optionProcess. (line 6) +* optionRestore: libopts-optionRestore. (line 6) +* optionSaveFile: libopts-optionSaveFile. + (line 6) +* optionSaveState: libopts-optionSaveState. + (line 6) +* optionUnloadNested: libopts-optionUnloadNested. + (line 6) +* optionVersion: libopts-optionVersion. (line 6) +* OPTION_CT: OPTION_CT. (line 6) +* OPT_ARG: OPT_ARG. (line 6) +* OPT_NO_XLAT_CFG_NAMES: OPT_NO_XLAT_CFG_NAMES. (line 6) +* OPT_NO_XLAT_OPT_NAMES: OPT_NO_XLAT_OPT_NAMES. (line 6) +* OPT_VALUE_name: OPT_VALUE_name. (line 6) +* OPT_XLAT_CFG_NAMES: OPT_XLAT_CFG_NAMES. (line 6) +* OPT_XLAT_OPT_NAMES: OPT_XLAT_OPT_NAMES. (line 6) +* out-delete: SCM out-delete. (line 6) +* out-depth: SCM out-depth. (line 6) +* out-emit-suspended: SCM out-emit-suspended. + (line 6) +* out-line: SCM out-line. (line 6) +* out-move: SCM out-move. (line 6) +* out-name: SCM out-name. (line 6) +* out-pop: SCM out-pop. (line 6) +* out-push-add: SCM out-push-add. (line 6) +* out-push-new: SCM out-push-new. (line 6) +* out-resume: SCM out-resume. (line 6) +* out-suspend: SCM out-suspend. (line 6) +* out-switch: SCM out-switch. (line 6) +* output-file-next-line: SCM output-file-next-line. + (line 6) +* prefix: SCM prefix. (line 6) +* printf: SCM printf. (line 6) +* raw-shell-str: SCM raw-shell-str. (line 6) +* RESTART_OPT: RESTART_OPT. (line 6) +* RETURN: RETURN. (line 6) +* SELECT: SELECT. (line 6) +* set-option: SCM set-option. (line 6) +* set-writable: SCM set-writable. (line 6) +* SET_OPT_name: SET_OPT_name. (line 6) +* shell: SCM shell. (line 6) +* shell-str: SCM shell-str. (line 6) +* shellf: SCM shellf. (line 6) +* sprintf: SCM sprintf. (line 6) +* stack: SCM stack. (line 6) +* stack-join: SCM stack-join. (line 6) +* STACKCT_OPT: STACKCT_OPT. (line 6) +* STACKLST_OPT: STACKLST_OPT. (line 6) +* START_OPT: START_OPT. (line 6) +* STATE_OPT: STATE_OPT. (line 6) +* strequate: libopts-strequate. (line 6) +* streqvcmp: libopts-streqvcmp. (line 6) +* streqvmap: libopts-streqvmap. (line 6) +* string->c-name!: SCM string->c-name!. (line 6) +* string->camelcase: SCM string->camelcase. (line 6) +* string-capitalize: SCM string-capitalize. (line 6) +* string-capitalize!: SCM string-capitalize!. + (line 6) +* string-contains-eqv?: SCM *=*. (line 6) +* string-contains?: SCM *==*. (line 6) +* string-downcase: SCM string-downcase. (line 6) +* string-downcase!: SCM string-downcase!. (line 6) +* string-end-eqv-match?: SCM *~. (line 6) +* string-end-match?: SCM *~~. (line 6) +* string-ends-eqv?: SCM *=. (line 6) +* string-ends-with?: SCM *==. (line 6) +* string-equals?: SCM ==. (line 6) +* string-eqv-match?: SCM ~. (line 6) +* string-eqv?: SCM =. (line 6) +* string-has-eqv-match?: SCM *~*. (line 6) +* string-has-match?: SCM *~~*. (line 6) +* string-match?: SCM ~~. (line 6) +* string-start-eqv-match?: SCM ~*. (line 6) +* string-start-match?: SCM ~~*. (line 6) +* string-starts-eqv?: SCM =*. (line 6) +* string-starts-with?: SCM ==*. (line 6) +* string-substitute: SCM string-substitute. (line 6) +* string-table-add: SCM string-table-add. (line 6) +* string-table-add-ref: SCM string-table-add-ref. + (line 6) +* string-table-new: SCM string-table-new. (line 6) +* string-table-size: SCM string-table-size. (line 6) +* string-tr: SCM string-tr. (line 6) +* string-tr!: SCM string-tr!. (line 6) +* string-upcase: SCM string-upcase. (line 6) +* string-upcase!: SCM string-upcase!. (line 6) +* strneqvcmp: libopts-strneqvcmp. (line 6) +* strtransform: libopts-strtransform. (line 6) +* sub-shell-str: SCM sub-shell-str. (line 6) +* suffix: SCM suffix. (line 6) +* sum: SCM sum. (line 6) +* teOptIndex: teOptIndex. (line 6) +* time-string->number: SCM time-string->number. + (line 6) +* tpl-file: SCM tpl-file. (line 6) +* tpl-file-line: SCM tpl-file-line. (line 6) +* tpl-file-next-line: SCM tpl-file-next-line. + (line 6) +* UNKNOWN: UNKNOWN. (line 6) +* USAGE: USAGE. (line 6) +* VALUE_OPT_name: VALUE_OPT_name. (line 6) +* VERSION: VERSION. (line 6) +* version-compare: SCM version-compare. (line 6) +* warn: SCM warn. (line 6) +* WHICH_IDX_name: WHICH_IDX_name. (line 6) +* WHICH_OPT_name: WHICH_OPT_name. (line 6) +* WHILE: WHILE. (line 6) + diff --git a/doc/autogen.texi b/doc/autogen.texi new file mode 100644 index 0000000..e6f2a83 --- /dev/null +++ b/doc/autogen.texi @@ -0,0 +1,7 @@ +\input texinfo +@ignore +\internalpagesizes{46\baselineskip}{6in}{-.25in}{-.25in}{\bindingoffset}{36pt}% +@end ignore +@c %**start of header +@setfilename autogen.info +@include agdoc.texi diff --git a/doc/bitmaps.texi b/doc/bitmaps.texi new file mode 100644 index 0000000..b3b5592 --- /dev/null +++ b/doc/bitmaps.texi @@ -0,0 +1,348 @@ +@ignore + +This file is part of AutoGen. +AutoGen is free software. +AutoGen is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + +AutoGen is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +AutoGen is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program. If not, see <http://www.gnu.org/licenses/>. + +This file has the following md5sum: + +43b91e8ca915626ed3818ffb1b71248b COPYING.gplv3 + +@end ignore +@node Bit Maps +@section Bit Maps and Enumerations + +AutoGen provides two templates for managing enumerations and bit maps +(flag words). They produce an enumeration of the enum or @code{#define}s +for the bit maps, plus conversion functions for converting a string into +one of these values or converting one of these values into a human readable +string. Finally, for enumerations, you may specify one or more sets of +dispatching functions that will be selected by identifying a keyword +prefix of a string (@pxref{enum-code, the @i{dispatch} attribute in +Strings to Enums and Back}). + +There is a separate project that produces a GDB add-on that +will add these capabilities into GDB for bit masks. (GDB does just fine +with enumerations.) + +@menu +* enums:: Enumerations +* enum-code:: Strings to Enums and Back +* masks:: Bit Maps and Masks +@end menu + +@node enums +@subsection Enumerations + +@file{str2enum.tpl} + +Produce an enumeration for a list of input ``cmd''s (names). +Optionally, produce functions to: + +@itemize @bullet +@item +convert a string to an enumeration +@item +convert an enumeration value into a string +@item +invoke a function based on the first token name found in a string +@end itemize + +The header file produced will contain the enumeration and declarations +for the optional procedures. The code (@file{.c}) file will contain +these optional procedures, but can be omitted if the @code{no-code} +attribute is specified. + +The following attributes are recognized with the @code{str2enum} template: + +@table @samp +@item cmd +You must provide a series of these attributes: they specify the list of +names used in the enumeration. Specific values for the names may be +specified by specifying a numeric index for these attributes. +e.g. @code{cmd[5] = mumble;} will cause +@example +FOO_CMD_MUMBLE = 5 +@end example +@noindent +to be inserted into the enumeration. +Do not specify a value of ``@t{invalid}'', unless you specify the +@code{invalid-name} attribute. (In that case, do not specify a +@code{cmd} value that matches the @code{invalid-name} value.) + +@item prefix +This specifies the first segment of each enumeration name. +If not specified, the first segment of the enumeration definition file name +will be used. e.g. @file{foo-bar.def} will default to a @code{FOO} prefix. + +@item type +Normally, there is a second constant segment following the prefix. If not +specified, it will be @code{CMD}, so if both @code{prefix} and @code{type} +were to default from @file{foo-bar.def}, you will have enumeration values +prefixed with @code{FOO_CMD_}. If specified as the empty string, there will +be no ``type'' component to the name and the default constant prefix will +thus be @code{FOO_}. + +@item base-name +This specifies the base name of the output files, enumeration type and the +translation functions. The default is to use the @code{basename(3)} of +the definition file. e.g. @file{foo-bar.def} results in a @code{base-name} +of @code{foo-bar}. + +@item invalid-val +The default invalid value is zero. Sometimes, it is useful for zero to be +valid. If so, you can specify @t{~0} or the empty string to be invalid. +The empty string will cause the enumeration count (maximum value plus 1) to +be the invalid value. + +@item invalid-name +By default, the invalid value is emitted into the enumeration as +@code{FOO_INVALID_CMD}. Specifying this attribute will replace +@code{INVALID} with whatever you place in this attribute. + +@item add-on-text +Additional text to insert into the code or header file. + +@table @samp +@item ao-file +Which file to insert the text into. There are four choices, +only two of which are relevant for the @file{str2enum} template: +``@t{enum-header}'', ``@t{enum-code}'', ``@t{mask-header}'' or ``@t{mask-code}''. + +@item ao-text +The text to insert. +@end table +@end table + +@c +@c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +@c +@node enum-code +@subsection Strings to Enums and Back + +A continuation of the attributes for the @file{str2enum.tpl} template. + +@table @samp +@item no-code +Do not emit any string to enumeration or enumeration to string code at all. +If this is specified, the remainder of the attributes have no effect. + +@item no-name +Do not emit the enumeration to name function. + +@item no-case +When looking up a string, the case of the input string is ignored. + +@item alias +A single punctuation character can be interpreted as a command. The first +character of this attribute is the aliased character and the remainder the +aliased-to command. e.g. ``@t{#comment}'' makes '@t{#}' an alias for the +@command{comment} command. ``@t{#comment}'' must still be listed in the +@code{cmd} attributes. + +@item length +Specify how lengths are to be handled. Under the covers, @command{gperf(1)} +is used to map a string to an enumeration value. The code it produces +requires the string length to be passed in. You may pass in the length +yourself, or the generated code may figure it out, or you may ask for that +length to be returned back after being figured out. + +You have four choices with the @code{length} attribute: + +@itemize @bullet +@item +Do not specify it. You will need to provide the length. +@item +Specify ``@t{provided}''. You will need to provide the length. +@item +Specify ``@t{returned}''. You must pass a pointer to a @t{size_t} object. +If the name is found, the length will be put there. +@item +Specify an empty string. The generated code will compute the length and +that computed length will not be returned. The length parameter may be +omitted. If the input strings contain only enumeration names, then this +would be sufficient. +@item +Specifying anything else is undefined. +@end itemize + +@item partial +Normally, a name must fully match to be found successfully. This attribute +causes the generated code to look for partial matches if the full match +@command{gperf} function fails. Partial matches must be at least two +characters long. + +@item undef-str +by default, the display string for an undefined value is +``@t{* UNDEFINED *}''. Use this to change that. + +@item equate +A series of punctuation characters considered equivalent. +Typically, ``@t{-_}'' but sometimes (Tandem) ``@t{-_^}''. +Do not use '@t{#}' in the list of characters. + +@item dispatch +A lookup procedure will call a dispatch function for the procedure named +after the keyword identified at the start of a string. Other than as +specially noted below, for every named ``cmd'', must have a handling +function, plus another function to handle errors, with ``invalid'' (or the +@code{invalid-name} value) as the @code{cmd} name. Multiple @code{dispatch} +definitions will produce multiple dispatching functions, each with +(potentially) unique argument lists and return types. + +You may also use @code{add-on-text} to ``@t{#define}'' one function to +another, thus allowing one function to handle multiple keywords or commands. +The @code{d-nam} and @code{d-ret} attributes are required. The @code{d-arg}, +@code{d-omit} and @code{d-only} attributes are optional: + +@table @samp +@item d-nam +This must be a printf format string with one formatting element: @code{%s}. +The @code{%s} will be replaced by each @code{cmd} name. The @code{%s} will +be stripped and the result will be combined with the base name to construct +the dispatch procedure name. + +@item d-ret +The return type of the dispatched function, even if ``@t{void}''. + +@item d-arg +If there are additional arguments that are to be passed through to the +dispatched function, specify this as though it were part of the procedure +header. (It will be glued into the dispatching function as is and sedded +into what is needed for the dispatched function.) + +@item d-omit +Instead of providing handling functions for all of the @code{cmd} names, +the invalid function will be called for omitted command codes. + +@item d-only +You need only provide functions for the names listed by @code{d-only}, plus +the ``invalid'' name. All other command values will trigger calls to +the invalid handling function. Note that the invalid call can distinguish +from a command that could not be found by examining the value of its +first (@code{id}) argument. +@end table + +The handler functions will have the command enumeration as its first first +argument, a pointer to a constant string that will be the character +@i{after} the parsed command (keyword) name, plus any @code{d-arg} arguments +that follow that. + +@noindent +As an example, a file @file{samp-chk.def} containing this: +@example +AutoGen Definitions str2enum; +cmd = one, two; invalid-name = oops; +dispatch = @{ d-nam = 'hdl_%s_cmd'; d-ret = void; @}; +@end example +@noindent +will produce a header containing: +@example +typedef enum @{ + SAMP_OOPS_CMD = 0, + SAMP_CMD_ONE = 1, + SAMP_CMD_TWO = 2, + SAMP_COUNT_CMD +@} samp_chk_enum_t; + +extern samp_chk_enum_t +find_samp_chk_cmd(char const * str, size_t len); + +typedef void(samp_chk_handler_t)( + samp_chk_enum_t id, char const * str); + +samp_chk_handler_t + hdl_oops_cmd, hdl_one_cmd, hdl_two_cmd; + +extern void +disp_samp_chk(char * str, size_t len); + +extern char const * +samp_chk_name(samp_chk_enum_t id); +@end example + +@itemize @bullet +@item +@code{find_samp_chk_cmd} will look up a @code{len} byte @code{str} and +return the corresponding @code{samp_chk_enum_t} value. That value is +@code{SAMP_OOPS_CMD} if the string is not ``one'' or ``two''. +@item +@code{samp_chk_handler_t} is the type of the callback procedures. +Three must be provided for the dispatching function to call: +@code{hdl_oops_cmd}, @code{hdl_one_cmd} and @code{hdl_two_cmd}. +@code{hdl_oops_cmd} will receive calls when the string does not match. +@item +@code{disp_samp_chk} this function will call the handler function +and return whatever the handler returns. In this case, it is void. +@item +@code{samp_chk_name} will return a string corresponding to the enumeration +value argument. If the value is not valid, ``* UNDEFINED *'' (or the +value of @code{undef-str}) is used. +@end itemize +@end table + +@c +@c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +@c +@node masks +@subsection Bit Maps and Masks + +@file{str2mask.tpl} + +This template leverages highly off of enumerations (@pxref{enums}). It will +produce a header file with bit masks defined for each bit specified with a +@code{cmd} attribute. 63 is the highest legal bit number because this +template has not been extended to cope with multiple word masks. (Patches +would be welcome.) + +There are a few constraints on the names allowed: + +@itemize @bullet +@item +names are constrained to alphanumerics and the underscore +@item +aliases are not allowed +@item +dispatch procedures are not allowed +@end itemize + +@code{no-code} and @code{no-name} are honored. @code{dispatch} is not. The +lookup function will examine each token in an input string, determine which +bit is specified and add it into a result. The names may be prefixed with a +hyphen (@t{-}) or tilde (@t{~}) to remove the bit(s) from the cumulative +result. If the string begins with a plus (@t{+}), hyphen or tilde, a ``base +value'' parameter is used for the starting mask, otherwise the conversion +starts with zero. + +Beyond the enumeration attributes that are used (or ignored), the +@file{str2mask} template accepts a @code{mask} attribute. It takes a few +``subattributes'': + +@table @samp +@item m-name +a special name for a sub-collection of the mask bits + +@item m-bit +The name of each previously defined bit(s). If the desired previously +defined value is a mask, that @code{m-name} must be suffixed with ``@t{-mask}''. + +@item m-invert +When all done collecting the bits, x-or the value with the mask +of all the bits in the collection. +@end table + +@noindent +A mask of all bits in the collection is always generated. diff --git a/doc/fdl.texi b/doc/fdl.texi new file mode 100644 index 0000000..cb71f05 --- /dev/null +++ b/doc/fdl.texi @@ -0,0 +1,505 @@ +@c The GNU Free Documentation License. +@center Version 1.3, 3 November 2008 + +@c This file is intended to be included within another document, +@c hence no sectioning command or @node. + +@display +Copyright @copyright{} 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc. +@uref{http://fsf.org/} + +Everyone is permitted to copy and distribute verbatim copies +of this license document, but changing it is not allowed. +@end display + +@enumerate 0 +@item +PREAMBLE + +The purpose of this License is to make a manual, textbook, or other +functional and useful document @dfn{free} in the sense of freedom: to +assure everyone the effective freedom to copy and redistribute it, +with or without modifying it, either commercially or noncommercially. +Secondarily, this License preserves for the author and publisher a way +to get credit for their work, while not being considered responsible +for modifications made by others. + +This License is a kind of ``copyleft'', which means that derivative +works of the document must themselves be free in the same sense. It +complements the GNU General Public License, which is a copyleft +license designed for free software. + +We have designed this License in order to use it for manuals for free +software, because free software needs free documentation: a free +program should come with manuals providing the same freedoms that the +software does. But this License is not limited to software manuals; +it can be used for any textual work, regardless of subject matter or +whether it is published as a printed book. We recommend this License +principally for works whose purpose is instruction or reference. + +@item +APPLICABILITY AND DEFINITIONS + +This License applies to any manual or other work, in any medium, that +contains a notice placed by the copyright holder saying it can be +distributed under the terms of this License. Such a notice grants a +world-wide, royalty-free license, unlimited in duration, to use that +work under the conditions stated herein. The ``Document'', below, +refers to any such manual or work. Any member of the public is a +licensee, and is addressed as ``you''. You accept the license if you +copy, modify or distribute the work in a way requiring permission +under copyright law. + +A ``Modified Version'' of the Document means any work containing the +Document or a portion of it, either copied verbatim, or with +modifications and/or translated into another language. + +A ``Secondary Section'' is a named appendix or a front-matter section +of the Document that deals exclusively with the relationship of the +publishers or authors of the Document to the Document's overall +subject (or to related matters) and contains nothing that could fall +directly within that overall subject. (Thus, if the Document is in +part a textbook of mathematics, a Secondary Section may not explain +any mathematics.) The relationship could be a matter of historical +connection with the subject or with related matters, or of legal, +commercial, philosophical, ethical or political position regarding +them. + +The ``Invariant Sections'' are certain Secondary Sections whose titles +are designated, as being those of Invariant Sections, in the notice +that says that the Document is released under this License. If a +section does not fit the above definition of Secondary then it is not +allowed to be designated as Invariant. The Document may contain zero +Invariant Sections. If the Document does not identify any Invariant +Sections then there are none. + +The ``Cover Texts'' are certain short passages of text that are listed, +as Front-Cover Texts or Back-Cover Texts, in the notice that says that +the Document is released under this License. A Front-Cover Text may +be at most 5 words, and a Back-Cover Text may be at most 25 words. + +A ``Transparent'' copy of the Document means a machine-readable copy, +represented in a format whose specification is available to the +general public, that is suitable for revising the document +straightforwardly with generic text editors or (for images composed of +pixels) generic paint programs or (for drawings) some widely available +drawing editor, and that is suitable for input to text formatters or +for automatic translation to a variety of formats suitable for input +to text formatters. A copy made in an otherwise Transparent file +format whose markup, or absence of markup, has been arranged to thwart +or discourage subsequent modification by readers is not Transparent. +An image format is not Transparent if used for any substantial amount +of text. A copy that is not ``Transparent'' is called ``Opaque''. + +Examples of suitable formats for Transparent copies include plain +ASCII without markup, Texinfo input format, La@TeX{} input +format, SGML or XML using a publicly available +DTD, and standard-conforming simple HTML, +PostScript or PDF designed for human modification. Examples +of transparent image formats include PNG, XCF and +JPG. Opaque formats include proprietary formats that can be +read and edited only by proprietary word processors, SGML or +XML for which the DTD and/or processing tools are +not generally available, and the machine-generated HTML, +PostScript or PDF produced by some word processors for +output purposes only. + +The ``Title Page'' means, for a printed book, the title page itself, +plus such following pages as are needed to hold, legibly, the material +this License requires to appear in the title page. For works in +formats which do not have any title page as such, ``Title Page'' means +the text near the most prominent appearance of the work's title, +preceding the beginning of the body of the text. + +The ``publisher'' means any person or entity that distributes copies +of the Document to the public. + +A section ``Entitled XYZ'' means a named subunit of the Document whose +title either is precisely XYZ or contains XYZ in parentheses following +text that translates XYZ in another language. (Here XYZ stands for a +specific section name mentioned below, such as ``Acknowledgements'', +``Dedications'', ``Endorsements'', or ``History''.) To ``Preserve the Title'' +of such a section when you modify the Document means that it remains a +section ``Entitled XYZ'' according to this definition. + +The Document may include Warranty Disclaimers next to the notice which +states that this License applies to the Document. These Warranty +Disclaimers are considered to be included by reference in this +License, but only as regards disclaiming warranties: any other +implication that these Warranty Disclaimers may have is void and has +no effect on the meaning of this License. + +@item +VERBATIM COPYING + +You may copy and distribute the Document in any medium, either +commercially or noncommercially, provided that this License, the +copyright notices, and the license notice saying this License applies +to the Document are reproduced in all copies, and that you add no other +conditions whatsoever to those of this License. You may not use +technical measures to obstruct or control the reading or further +copying of the copies you make or distribute. However, you may accept +compensation in exchange for copies. If you distribute a large enough +number of copies you must also follow the conditions in section 3. + +You may also lend copies, under the same conditions stated above, and +you may publicly display copies. + +@item +COPYING IN QUANTITY + +If you publish printed copies (or copies in media that commonly have +printed covers) of the Document, numbering more than 100, and the +Document's license notice requires Cover Texts, you must enclose the +copies in covers that carry, clearly and legibly, all these Cover +Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on +the back cover. Both covers must also clearly and legibly identify +you as the publisher of these copies. The front cover must present +the full title with all words of the title equally prominent and +visible. You may add other material on the covers in addition. +Copying with changes limited to the covers, as long as they preserve +the title of the Document and satisfy these conditions, can be treated +as verbatim copying in other respects. + +If the required texts for either cover are too voluminous to fit +legibly, you should put the first ones listed (as many as fit +reasonably) on the actual cover, and continue the rest onto adjacent +pages. + +If you publish or distribute Opaque copies of the Document numbering +more than 100, you must either include a machine-readable Transparent +copy along with each Opaque copy, or state in or with each Opaque copy +a computer-network location from which the general network-using +public has access to download using public-standard network protocols +a complete Transparent copy of the Document, free of added material. +If you use the latter option, you must take reasonably prudent steps, +when you begin distribution of Opaque copies in quantity, to ensure +that this Transparent copy will remain thus accessible at the stated +location until at least one year after the last time you distribute an +Opaque copy (directly or through your agents or retailers) of that +edition to the public. + +It is requested, but not required, that you contact the authors of the +Document well before redistributing any large number of copies, to give +them a chance to provide you with an updated version of the Document. + +@item +MODIFICATIONS + +You may copy and distribute a Modified Version of the Document under +the conditions of sections 2 and 3 above, provided that you release +the Modified Version under precisely this License, with the Modified +Version filling the role of the Document, thus licensing distribution +and modification of the Modified Version to whoever possesses a copy +of it. In addition, you must do these things in the Modified Version: + +@enumerate A +@item +Use in the Title Page (and on the covers, if any) a title distinct +from that of the Document, and from those of previous versions +(which should, if there were any, be listed in the History section +of the Document). You may use the same title as a previous version +if the original publisher of that version gives permission. + +@item +List on the Title Page, as authors, one or more persons or entities +responsible for authorship of the modifications in the Modified +Version, together with at least five of the principal authors of the +Document (all of its principal authors, if it has fewer than five), +unless they release you from this requirement. + +@item +State on the Title page the name of the publisher of the +Modified Version, as the publisher. + +@item +Preserve all the copyright notices of the Document. + +@item +Add an appropriate copyright notice for your modifications +adjacent to the other copyright notices. + +@item +Include, immediately after the copyright notices, a license notice +giving the public permission to use the Modified Version under the +terms of this License, in the form shown in the Addendum below. + +@item +Preserve in that license notice the full lists of Invariant Sections +and required Cover Texts given in the Document's license notice. + +@item +Include an unaltered copy of this License. + +@item +Preserve the section Entitled ``History'', Preserve its Title, and add +to it an item stating at least the title, year, new authors, and +publisher of the Modified Version as given on the Title Page. If +there is no section Entitled ``History'' in the Document, create one +stating the title, year, authors, and publisher of the Document as +given on its Title Page, then add an item describing the Modified +Version as stated in the previous sentence. + +@item +Preserve the network location, if any, given in the Document for +public access to a Transparent copy of the Document, and likewise +the network locations given in the Document for previous versions +it was based on. These may be placed in the ``History'' section. +You may omit a network location for a work that was published at +least four years before the Document itself, or if the original +publisher of the version it refers to gives permission. + +@item +For any section Entitled ``Acknowledgements'' or ``Dedications'', Preserve +the Title of the section, and preserve in the section all the +substance and tone of each of the contributor acknowledgements and/or +dedications given therein. + +@item +Preserve all the Invariant Sections of the Document, +unaltered in their text and in their titles. Section numbers +or the equivalent are not considered part of the section titles. + +@item +Delete any section Entitled ``Endorsements''. Such a section +may not be included in the Modified Version. + +@item +Do not retitle any existing section to be Entitled ``Endorsements'' or +to conflict in title with any Invariant Section. + +@item +Preserve any Warranty Disclaimers. +@end enumerate + +If the Modified Version includes new front-matter sections or +appendices that qualify as Secondary Sections and contain no material +copied from the Document, you may at your option designate some or all +of these sections as invariant. To do this, add their titles to the +list of Invariant Sections in the Modified Version's license notice. +These titles must be distinct from any other section titles. + +You may add a section Entitled ``Endorsements'', provided it contains +nothing but endorsements of your Modified Version by various +parties---for example, statements of peer review or that the text has +been approved by an organization as the authoritative definition of a +standard. + +You may add a passage of up to five words as a Front-Cover Text, and a +passage of up to 25 words as a Back-Cover Text, to the end of the list +of Cover Texts in the Modified Version. Only one passage of +Front-Cover Text and one of Back-Cover Text may be added by (or +through arrangements made by) any one entity. If the Document already +includes a cover text for the same cover, previously added by you or +by arrangement made by the same entity you are acting on behalf of, +you may not add another; but you may replace the old one, on explicit +permission from the previous publisher that added the old one. + +The author(s) and publisher(s) of the Document do not by this License +give permission to use their names for publicity for or to assert or +imply endorsement of any Modified Version. + +@item +COMBINING DOCUMENTS + +You may combine the Document with other documents released under this +License, under the terms defined in section 4 above for modified +versions, provided that you include in the combination all of the +Invariant Sections of all of the original documents, unmodified, and +list them all as Invariant Sections of your combined work in its +license notice, and that you preserve all their Warranty Disclaimers. + +The combined work need only contain one copy of this License, and +multiple identical Invariant Sections may be replaced with a single +copy. If there are multiple Invariant Sections with the same name but +different contents, make the title of each such section unique by +adding at the end of it, in parentheses, the name of the original +author or publisher of that section if known, or else a unique number. +Make the same adjustment to the section titles in the list of +Invariant Sections in the license notice of the combined work. + +In the combination, you must combine any sections Entitled ``History'' +in the various original documents, forming one section Entitled +``History''; likewise combine any sections Entitled ``Acknowledgements'', +and any sections Entitled ``Dedications''. You must delete all +sections Entitled ``Endorsements.'' + +@item +COLLECTIONS OF DOCUMENTS + +You may make a collection consisting of the Document and other documents +released under this License, and replace the individual copies of this +License in the various documents with a single copy that is included in +the collection, provided that you follow the rules of this License for +verbatim copying of each of the documents in all other respects. + +You may extract a single document from such a collection, and distribute +it individually under this License, provided you insert a copy of this +License into the extracted document, and follow this License in all +other respects regarding verbatim copying of that document. + +@item +AGGREGATION WITH INDEPENDENT WORKS + +A compilation of the Document or its derivatives with other separate +and independent documents or works, in or on a volume of a storage or +distribution medium, is called an ``aggregate'' if the copyright +resulting from the compilation is not used to limit the legal rights +of the compilation's users beyond what the individual works permit. +When the Document is included in an aggregate, this License does not +apply to the other works in the aggregate which are not themselves +derivative works of the Document. + +If the Cover Text requirement of section 3 is applicable to these +copies of the Document, then if the Document is less than one half of +the entire aggregate, the Document's Cover Texts may be placed on +covers that bracket the Document within the aggregate, or the +electronic equivalent of covers if the Document is in electronic form. +Otherwise they must appear on printed covers that bracket the whole +aggregate. + +@item +TRANSLATION + +Translation is considered a kind of modification, so you may +distribute translations of the Document under the terms of section 4. +Replacing Invariant Sections with translations requires special +permission from their copyright holders, but you may include +translations of some or all Invariant Sections in addition to the +original versions of these Invariant Sections. You may include a +translation of this License, and all the license notices in the +Document, and any Warranty Disclaimers, provided that you also include +the original English version of this License and the original versions +of those notices and disclaimers. In case of a disagreement between +the translation and the original version of this License or a notice +or disclaimer, the original version will prevail. + +If a section in the Document is Entitled ``Acknowledgements'', +``Dedications'', or ``History'', the requirement (section 4) to Preserve +its Title (section 1) will typically require changing the actual +title. + +@item +TERMINATION + +You may not copy, modify, sublicense, or distribute the Document +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense, or distribute it is void, and +will automatically terminate your rights under this License. + +However, if you cease all violation of this License, then your license +from a particular copyright holder is reinstated (a) provisionally, +unless and until the copyright holder explicitly and finally +terminates your license, and (b) permanently, if the copyright holder +fails to notify you of the violation by some reasonable means prior to +60 days after the cessation. + +Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + +Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, receipt of a copy of some or all of the same material does +not give you any rights to use it. + +@item +FUTURE REVISIONS OF THIS LICENSE + +The Free Software Foundation may publish new, revised versions +of the GNU Free Documentation 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. See +@uref{http://www.gnu.org/copyleft/}. + +Each version of the License is given a distinguishing version number. +If the Document specifies that a particular numbered version of this +License ``or any later version'' applies to it, you have the option of +following the terms and conditions either of that specified version or +of any later version that has been published (not as a draft) by the +Free Software Foundation. If the Document does not specify a version +number of this License, you may choose any version ever published (not +as a draft) by the Free Software Foundation. If the Document +specifies that a proxy can decide which future versions of this +License can be used, that proxy's public statement of acceptance of a +version permanently authorizes you to choose that version for the +Document. + +@item +RELICENSING + +``Massive Multiauthor Collaboration Site'' (or ``MMC Site'') means any +World Wide Web server that publishes copyrightable works and also +provides prominent facilities for anybody to edit those works. A +public wiki that anybody can edit is an example of such a server. A +``Massive Multiauthor Collaboration'' (or ``MMC'') contained in the +site means any set of copyrightable works thus published on the MMC +site. + +``CC-BY-SA'' means the Creative Commons Attribution-Share Alike 3.0 +license published by Creative Commons Corporation, a not-for-profit +corporation with a principal place of business in San Francisco, +California, as well as future copyleft versions of that license +published by that same organization. + +``Incorporate'' means to publish or republish a Document, in whole or +in part, as part of another Document. + +An MMC is ``eligible for relicensing'' if it is licensed under this +License, and if all works that were first published under this License +somewhere other than this MMC, and subsequently incorporated in whole +or in part into the MMC, (1) had no cover texts or invariant sections, +and (2) were thus incorporated prior to November 1, 2008. + +The operator of an MMC Site may republish an MMC contained in the site +under CC-BY-SA on the same site at any time before August 1, 2009, +provided the MMC is eligible for relicensing. + +@end enumerate + +@page +@heading ADDENDUM: How to use this License for your documents + +To use this License in a document you have written, include a copy of +the License in the document and put the following copyright and +license notices just after the title page: + +@smallexample +@group + Copyright (C) @var{year} @var{your name}. + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.3 + or any later version published by the Free Software Foundation; + with no Invariant Sections, no Front-Cover Texts, and no Back-Cover + Texts. A copy of the license is included in the section entitled ``GNU + Free Documentation License''. +@end group +@end smallexample + +If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, +replace the ``with@dots{}Texts.''@: line with this: + +@smallexample +@group + with the Invariant Sections being @var{list their titles}, with + the Front-Cover Texts being @var{list}, and with the Back-Cover Texts + being @var{list}. +@end group +@end smallexample + +If you have Invariant Sections without Cover Texts, or some other +combination of the three, merge those two alternatives to suit the +situation. + +If your document contains nontrivial examples of program code, we +recommend releasing these examples in parallel under your choice of +free software license, such as the GNU General Public License, +to permit their use in free software. + +@c Local Variables: +@c ispell-local-pdict: "ispell-dict" +@c End: diff --git a/doc/gendocs_template b/doc/gendocs_template new file mode 100644 index 0000000..daf3bd2 --- /dev/null +++ b/doc/gendocs_template @@ -0,0 +1,91 @@ +<!--#include virtual="/server/header.html" --> +<!-- Parent-Version: 1.77 --> +<title>%%TITLE%% - GNU Project - Free Software Foundation + +

%%TITLE%%

+ +
Free Software Foundation
+
last updated %%DATE%%
+ +

This manual (%%PACKAGE%%) is available in the following formats:

+ + + +

You can buy printed copies of +some manuals (among other items) from the Free Software Foundation; +this helps support FSF activities.

+ +

(This page generated by the %%SCRIPTNAME%% +script.)

+ + + + + + + + diff --git a/doc/invoke-autogen.texi b/doc/invoke-autogen.texi new file mode 100644 index 0000000..b33c1ad --- /dev/null +++ b/doc/invoke-autogen.texi @@ -0,0 +1,859 @@ +@node autogen Invocation +@chapter Invoking autogen +@pindex autogen +@cindex The Automated Program Generator +@ignore +# -*- buffer-read-only: t -*- vi: set ro: +# +# DO NOT EDIT THIS FILE (invoke-autogen.texi) +# +# It has been AutoGen-ed +# From the definitions /u/bkorb/tools/ag/autogen-bld/agen5/opts.def +# and the template file agtexi-cmd.tpl +@end ignore + +AutoGen creates text files from templates using external definitions. + +@code{AutoGen} is designed for generating program files that contain +repetitive text with varied substitutions. The goal is to simplify the +maintenance of programs that contain large amounts of repetitious text. +This is especially valuable if there are several blocks of such text +that must be kept synchronized. + +One common example is the problem of maintaining the code required for +processing program options. Processing options requires a minimum of +four different constructs be kept in proper order in different places +in your program. You need at least: The flag character in the flag +string, code to process the flag when it is encountered, a global +state variable or two, and a line in the usage text. +You will need more things besides this if you choose to implement +long option names, configuration file processing, environment variables +and so on. + +All of this can be done mechanically; with the proper templates +and this program. + + +This chapter was generated by @strong{AutoGen}, +using the @code{agtexi-cmd} template and the option descriptions for the @code{autogen} program. +This software is released under the GNU General Public License, version 3 or later. + +@menu +* autogen usage:: autogen help/usage (@option{--help}) +* autogen input-select:: input-select options +* autogen out-handling:: out-handling options +* autogen debug-tpl:: debug-tpl options +* autogen processing:: processing options +* autogen dep-track:: dep-track options +* autogen autoopts-opts:: autoopts-opts options +* autogen config:: presetting/configuring autogen +* autogen exit status:: exit status +* autogen Examples:: Examples +@end menu + +@node autogen usage +@section autogen help/usage (@option{--help}) +@cindex autogen help + +This is the automatically generated usage text for autogen. + +The text printed is the same whether selected with the @code{help} option +(@option{--help}) or the @code{more-help} option (@option{--more-help}). @code{more-help} will print +the usage text by passing it through a pager program. +@code{more-help} is disabled on platforms without a working +@code{fork(2)} function. The @code{PAGER} environment variable is +used to select the program, defaulting to @file{more}. Both will exit +with a status code of 0. + +@exampleindent 0 +@example +autogen (GNU AutoGen) - The Automated Program Generator - Ver. 5.18.15.001 +Usage: autogen [ - [] | --[@{=| @}] ]... [ ] + +The following options select definitions, templates and scheme functions +to use: + + Flg Arg Option-Name Description + -L Str templ-dirs Search for templates in DIR + - may appear multiple times + -T Str override-tpl Use TPL-FILE for the template + - may not be preset + Str definitions Read definitions from FILE + - disabled as '--no-definitions' + - enabled by default + - may not be preset + Str shell name or path name of shell to use + -m no no-fmemopen Do not use in-mem streams + Str equate characters considered equivalent + +The following options modify how output is handled: + + Flg Arg Option-Name Description + -b Str base-name Specify NAME as the base name for output + - may not be preset + no source-time set mod times to latest source + - disabled as '--no-source-time' + no writable Allow output files to be writable + - disabled as '--not-writable' + +The following options are often useful while debugging new templates: + + Flg Arg Option-Name Description + Num loop-limit Limit on increment loops + - is scalable with a suffix: k/K/m/M/g/G/t/T + - it must lie in one of the ranges: + -1 exactly, or + 1 to 16777216 + -t Num timeout Limit server shell operations to SECONDS + - it must be in the range: + 0 to 3600 + KWd trace tracing level of detail + Str trace-out tracing output file or filter + --- show-defs This option has been disabled + no used-defines Show the definitions used + - may not be preset + -C no core Leave a core dump on a failure exit + +These options can be used to control what gets processed in the +definitions files and template files: + + Flg Arg Option-Name Description + -s Str skip-suffix Skip the file with this SUFFIX + - prohibits the option 'select-suffix' + - may not be preset + - may appear multiple times + -o Str select-suffix specify this output suffix + - may not be preset + - may appear multiple times + -D Str define name to add to definition list + - may appear multiple times + -U Str undefine definition list removal pattern + - an alternate for 'define' + +This option is used to automate dependency tracking: + + Flg Arg Option-Name Description + -M opt make-dep emit make dependency file + - may not be preset + - may appear multiple times + +help, version, option and error handling: + + Flg Arg Option-Name Description + no no-abort Do not abort on errors + +Version, usage and configuration options: + + Flg Arg Option-Name Description + -R Str reset-option reset an option's state + -v opt version output version information and exit + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + -u no usage abbreviated usage to stdout + -> opt save-opts save the option state to a config file + -< Str load-opts load options from a config file + - disabled as '--no-load-opts' + - may appear multiple times + +Options are specified by doubled hyphens and their name or by a single +hyphen and the flag character. +AutoGen creates text files from templates using external definitions. + +The following option preset mechanisms are supported: + - reading file $HOME + - reading file ./.autogenrc + - examining environment variables named AUTOGEN_* + +The valid "trace" option keywords are: + nothing debug-message server-shell templates block-macros + expressions everything + or an integer from 0 through 6 +AutoGen is a tool designed for generating program files that contain +repetitive text with varied substitutions. + +Please send bug reports to: +@end example +@exampleindent 4 + +@node autogen input-select +@section input-select options +The following options select definitions, templates and scheme functions to use. +@subheading templ-dirs option (-L). +@anchor{autogen templ-dirs} +@cindex autogen-templ-dirs + +This is the ``search for templates in @file{dir}'' option. +This option takes a string argument @file{DIR}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +may appear an unlimited number of times. +@end itemize + +Add a directory to the list of directories @command{autogen} searches when +opening a template, either as the primary template or an included one. +The last entry has the highest priority in the search list. That is +to say, they are searched in reverse order. +@subheading override-tpl option (-T). +@anchor{autogen override-tpl} +@cindex autogen-override-tpl + +This is the ``use @file{tpl-file} for the template'' option. +This option takes a string argument @file{TPL-FILE}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +may not be preset with environment variables or configuration (rc/ini) files. +@end itemize + +Definition files specify the standard template that is to be expanded. +This option will override that name and expand a different template. +@subheading definitions option. +@anchor{autogen definitions} +@cindex autogen-definitions + +This is the ``read definitions from @file{file}'' option. +This option takes a string argument @file{FILE}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +can be disabled with --no-definitions. +@item +It is enabled by default. +@item +may not be preset with environment variables or configuration (rc/ini) files. +@end itemize + +Use this argument to specify the input definitions file with a +command line option. If you do not specify this option, then +there must be a command line argument that specifies the file, +even if only to specify stdin with a hyphen (@code{-}). +Specify, @code{--no-definitions} when you wish to process +a template without any active AutoGen definitions. +@subheading shell option. +@anchor{autogen shell} +@cindex autogen-shell + +This is the ``name or path name of shell to use'' option. +This option takes a string argument @file{shell}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +must be compiled in by defining @code{SHELL_ENABLED} during the compilation. +@end itemize + +By default, when AutoGen is built, the configuration is probed for a +reasonable Bourne-like shell to use for shell script processing. If +a particular template needs an alternate shell, it must be specified +with this option on the command line, with an environment variable +(@code{SHELL}) or in the configuration/initialization file. +@subheading no-fmemopen option (-m). +@anchor{autogen no-fmemopen} +@cindex autogen-no-fmemopen + +This is the ``do not use in-mem streams'' option. +If the local C library supports "@code{fopencookie(3GNU)}", or +"@code{funopen(3BSD)}" then AutoGen prefers to use in-memory stream +buffer opens instead of anonymous files. This may lead to problems +if there is a shortage of virtual memory. If, for a particular +application, you run out of memory, then specify this option. +This is unlikely in a modern 64-bit virtual memory environment. + +On platforms without these functions, the option is accepted +but ignored. @code{fmemopen(POSIX)} is not adequate because +its string buffer is not reallocatable. @code{open_memstream(POSIX)} +is @i{also} not adequate because the stream is only opened for +output. AutoGen needs a reallocatable buffer available for both +reading and writing. +@subheading equate option. +@anchor{autogen equate} +@cindex autogen-equate + +This is the ``characters considered equivalent'' option. +This option takes a string argument @file{char-list}. +This option will alter the list of characters considered equivalent. +The default are the three characters, "_-^". (The last is conventional +on a Tandem/HP-NonStop, and I used to do a lot of work on Tandems.) +@node autogen out-handling +@section out-handling options +The following options modify how output is handled. +@subheading base-name option (-b). +@anchor{autogen base-name} +@cindex autogen-base-name + +This is the ``specify @code{name} as the base name for output'' option. +This option takes a string argument @file{NAME}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +may not be preset with environment variables or configuration (rc/ini) files. +@end itemize + +A template may specify the exact name of the output file. Normally, +it does not. Instead, the name is composed of the base name of the +definitions file with suffixes appended. This option will override the +base name derived from the definitions file name. This is required if +there is no definitions file and advisable if definitions are being +read from stdin. If the definitions are being read from standard in, +the base name defaults to @file{stdin}. Any leading directory components +in the name will be silently removed. If you wish the output file to +appear in a particular directory, it is recommended that you "cd" into +that directory first, or use directory names in the format specification +for the output suffix lists, @xref{pseudo macro}. +@subheading source-time option. +@anchor{autogen source-time} +@cindex autogen-source-time + +This is the ``set mod times to latest source'' option. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +can be disabled with --no-source-time. +@end itemize + +If you stamp your output files with the @code{DNE} macro output, then +your output files will always be different, even if the content has +not really changed. If you use this option, then the modification +time of the output files will change only if the input files change. +This will help reduce unneeded builds. +@subheading writable option. +@anchor{autogen writable} +@cindex autogen-writable + +This is the ``allow output files to be writable'' option. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +can be disabled with --not-writable. +@end itemize + +This option will leave output files writable. +Normally, output files are read-only. +@node autogen debug-tpl +@section debug-tpl options +The following options are often useful while debugging new templates. +They specify limits that prevent the template from taking overly long +or producing more output than expected. +@subheading loop-limit option. +@anchor{autogen loop-limit} +@cindex autogen-loop-limit + +This is the ``limit on increment loops'' option. +This option takes a number argument @file{lim}. +This option prevents runaway loops. For example, if you accidentally +specify, "FOR x (for-from 1) (for-to -1) (for-by 1)", it will take a +long time to finish. If you do have more than 256 entries in tables, +you will need to specify a new limit with this option. +@subheading timeout option (-t). +@anchor{autogen timeout} +@cindex autogen-timeout + +This is the ``limit server shell operations to @code{seconds}'' option. +This option takes a number argument @file{SECONDS}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +must be compiled in by defining @code{SHELL_ENABLED} during the compilation. +@end itemize + +AutoGen works with a shell server process. Most normal commands will +complete in less than 10 seconds. If, however, your commands need more +time than this, use this option. + +The valid range is 0 to 3600 seconds (1 hour). +Zero will disable the server time limit. +@subheading trace option. +@anchor{autogen trace} +@cindex autogen-trace + +This is the ``tracing level of detail'' option. +This option takes a keyword argument @file{level}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +This option takes a keyword as its argument. +The argument sets an enumeration value that can be tested by comparing the option value macro (OPT_VALUE_TRACE). +The available keywords are: +@example + nothing debug-message server-shell + templates block-macros expressions + everything +@end example + +or their numeric equivalent. +@end itemize + +This option will cause AutoGen to display a trace of its template +processing. There are six levels, each level including messages from +the previous levels: + +@table @samp +@item nothing +Does no tracing at all (default) + +@item debug-message +Print messages from the "DEBUG" AutoGen macro (@pxref{DEBUG}). + +@item server-shell +Traces all input and output to the server shell. This includes a shell +"independent" initialization script about 30 lines long. Its output is +discarded and not inserted into any template. + +@item templates +Traces the invocation of @code{DEFINE}d macros and @code{INCLUDE}s + +@item block-macros +Traces all block macros. The above, plus @code{IF}, @code{FOR}, +@code{CASE} and @code{WHILE}. + +@item expressions +Displays the results of expression evaluations. + +@item everything +Displays the invocation of every AutoGen macro, even @code{TEXT} macros +(i.e. the text outside of macro quotes). Additionally, if you rebuild +the ``expr.ini'' file with debugging enabled, then all calls to +AutoGen defined scheme functions will also get logged: +@* +@example +cd $@{top_builddir@}/agen5 +DEBUG_ENABLED=true bash bootstrap.dir expr.ini +make CFLAGS='-g -DDEBUG_ENABLED=1' +@end example + +Be aware that you cannot rebuild this source in this way without first +having installed the @code{autogen} executable in your search path. +Because of this, "expr.ini" is in the distributed source list, and +not in the dependencies. +@end table +@subheading trace-out option. +@anchor{autogen trace-out} +@cindex autogen-trace-out + +This is the ``tracing output file or filter'' option. +This option takes a string argument @file{file}. +The output specified may be a file name, a file that is appended to, +or, if the option argument begins with the @code{pipe} operator +(@code{|}), a command that will receive the tracing output as standard +in. For example, @code{--traceout='| less'} will run the trace output +through the @code{less} program. Appending to a file is specified by +preceding the file name with two greater-than characters (@code{>>}). +@subheading show-defs option. +@anchor{autogen show-defs} +@cindex autogen-show-defs + +This is the ``show the definition tree'' option. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +must be compiled in by defining @code{DEBUG_ENABLED} during the compilation. +@item +may not be preset with environment variables or configuration (rc/ini) files. +@end itemize + +This will print out the complete definition tree before processing +the template. +@subheading used-defines option. +@anchor{autogen used-defines} +@cindex autogen-used-defines + +This is the ``show the definitions used'' option. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +may not be preset with environment variables or configuration (rc/ini) files. +@end itemize + +This will print out the names of definition values searched for +during the processing of the template, whether actually found or +not. There may be other referenced definitions in a template in +portions of the template not evaluated. Some of the names listed +may be computed names and others AutoGen macro arguments. This is +not a means for producing a definitive, all-encompassing list of all +and only the values used from a definition file. This is intended +as an aid to template documentation only. +@subheading core option (-C). +@anchor{autogen core} +@cindex autogen-core + +This is the ``leave a core dump on a failure exit'' option. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +must be compiled in by defining @code{HAVE_SYS_RESOURCE_H} during the compilation. +@end itemize + +Many systems default to a zero sized core limit. If the system +has the sys/resource.h header and if this option is supplied, +then in the failure exit path, autogen will attempt to set the +soft core limit to whatever the hard core limit is. If that +does not work, then an administrator must raise the hard core +size limit. +@node autogen processing +@section processing options +These options can be used to control what gets processed +in the definitions files and template files. +They specify which outputs and parts of outputs to produce. +@subheading skip-suffix option (-s). +@anchor{autogen skip-suffix} +@cindex autogen-skip-suffix + +This is the ``skip the file with this @file{suffix}'' option. +This option takes a string argument @file{SUFFIX}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +may appear an unlimited number of times. +@item +may not be preset with environment variables or configuration (rc/ini) files. +@item +must not appear in combination with any of the following options: +select-suffix. +@end itemize + +Occasionally, it may not be desirable to produce all of the output +files specified in the template. (For example, only the @file{.h} +header file, but not the @file{.c} program text.) To do this +specify @code{--skip-suffix=c} on the command line. +@subheading select-suffix option (-o). +@anchor{autogen select-suffix} +@cindex autogen-select-suffix + +This is the ``specify this output suffix'' option. +This option takes a string argument @file{SUFFIX}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +may appear an unlimited number of times. +@item +may not be preset with environment variables or configuration (rc/ini) files. +@end itemize + +If you wish to override the suffix specifications in the template, +you can use one or more copies of this option. See the suffix +specification in the @ref{pseudo macro} section of the info doc. +@subheading define option (-D). +@anchor{autogen define} +@cindex autogen-define + +This is the ``name to add to definition list'' option. +This option takes a string argument @file{value}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +may appear an unlimited number of times. +@end itemize + +The AutoGen define names are used for the following purposes: + +@enumerate +@item +Sections of the AutoGen definitions may be enabled or disabled +by using C-style #ifdef and #ifndef directives. +@item +When defining a value for a name, you may specify the index +for a particular value. That index may be a literal value, +a define option or a value #define-d in the definitions themselves. +@item +The name of a file may be prefixed with @code{$NAME/}. +The @code{$NAME} part of the name string will be replaced with +the define-d value for @code{NAME}. +@item +When AutoGen is finished loading the definitions, the defined values +are exported to the environment with, @code{putenv(3)}. +These values can then be used in shell scripts with @code{$@{NAME@}} +references and in templates with @code{(getenv "NAME")}. +@item +While processing a template, you may specify an index to retrieve +a specific value. That index may also be a define-d value. +@end enumerate + +It is entirely equivalent to place this name in the exported environment. +Internally, that is what AutoGen actually does with this option. +@subheading undefine option (-U). +@anchor{autogen undefine} +@cindex autogen-undefine + +This is the ``definition list removal pattern'' option. +This option takes a string argument @file{name-pat}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +may appear an unlimited number of times. +@item +may not be preset with environment variables or configuration (rc/ini) files. +@end itemize + +Similar to 'C', AutoGen uses @code{#ifdef/#ifndef} preprocessing +directives. This option will cause the matching names to be +removed from the list of defined values. +@node autogen dep-track +@section dep-track options +This option is used to automate dependency tracking. +@subheading make-dep option (-M). +@anchor{autogen make-dep} +@cindex autogen-make-dep + +This is the ``emit make dependency file'' option. +This option takes an optional string argument @file{type}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +may appear an unlimited number of times. +@item +may not be preset with environment variables or configuration (rc/ini) files. +@end itemize + + +This option behaves fairly closely to the way the @code{-M} series of +options work with the gcc compiler, except that instead of just +emitting the predecessor dependencies, this also emits the successor +dependencies (output target files). By default, the output dependency +information will be placed in @code{.d}, but may also be +specified with @code{-MF}. The time stamp on this file will be +manipulated so that it will be one second older than the oldest +primary output file. + +The target in this dependency file will normally be the dependency +file name, but may also be overridden with @code{-MT}. +AutoGen will not alter the contents of that file, but it may create +it and it will adjust the modification time to match the start time. + +@strong{NB:} these second letters are part of the option argument, so +@code{-MF } must have the space character quoted or omitted, and +@code{-M "F "} is acceptable because the @code{F} is part of the +option argument. + +@code{-M} may be followed by any of the letters M, F, P, T, Q, D, or G. +However, only F, Q, T and P are meaningful. All but F have somewhat +different meanings. @code{-MT} is interpreted as meaning +@code{} is a sentinel file that will depend on all inputs +(templates and definition files) and all the output files will depend +on this sentinel file. It is suitable for use as a real make target. +Q is treated identically to T, except dollar characters ('$') are +doubled. P causes a special clean (clobber) phoney rule to be inserted +into the make file fragment. An empty rule is always created for +building the list of targets. + +This is the recommended usage: +@example + -MFwhatever-you-like.dep -MTyour-sentinel-file -MP +@end example +and then in your @code{Makefile}, make the @file{autogen} rule: +@example + -include whatever-you-like.dep + clean_targets += clean-your-sentinel-file + + your-sentinel-file: + autogen -MT$@@ -MF$*.d ..... + + local-clean : + rm -f $(clean_targets) +@end example + +The modification time on the dependency file is adjusted to be one +second before the earliest time stamp of any other output file. +Consequently, it is suitable for use as the sentinel file testifying +to the fact the program was successfully run. (@code{-include} is +the GNU make way of specifying "include it if it exists". Your make +must support that feature or your bootstrap process must create the +file.) + +All of this may also be specified using the @code{DEPENDENCIES_OUTPUT} +or @code{AUTOGEN_MAKE_DEP} environment variables. If defined, +dependency information will be output. If defined with white space +free text that is something other than @code{true}, @code{false}, +@code{yes}, @code{no}, @code{0} or @code{1}, then the string is taken +to be an output file name. If it contains a string of white space +characters, the first token is as above and the second token is taken +to be the target (sentinel) file as @code{-MT} in the paragraphs +above. @code{DEPENDENCIES_OUTPUT} will be ignored if there are +multiple sequences of white space characters or if its contents are, +specifically, @code{false}, @code{no} or @code{0}. +@node autogen autoopts-opts +@section autoopts-opts options +help, version, option and error handling. +@subheading no-abort option. +@anchor{autogen no-abort} +@cindex autogen-no-abort + +This is the ``do not abort on errors'' option. +By default, @code{AutoGen} will abort on an error leaving behind a core image. +That is sometimes inconvenient. If present on the command line or in +the environment, AutoGen will call @code{exit(1)} instead of @code{abort()}. + + +@node autogen config +@section presetting/configuring autogen + +Any option that is not marked as @i{not presettable} may be preset by +loading values from configuration ("rc" or "ini") files, and values from environment variables named @code{AUTOGEN} and @code{AUTOGEN_}. @code{} must be one of +the options listed above in upper case and segmented with underscores. +The @code{AUTOGEN} variable will be tokenized and parsed like +the command line. The remaining variables are tested for existence and their +values are treated like option arguments. + + +@noindent +@code{libopts} will search in 2 places for configuration files: +@itemize @bullet +@item +$HOME +@item +$PWD +@end itemize +The environment variables @code{HOME}, and @code{PWD} +are expanded and replaced when @file{autogen} runs. +For any of these that are plain files, they are simply processed. +For any that are directories, then a file named @file{.autogenrc} is searched for +within that directory and processed. + +Configuration files may be in a wide variety of formats. +The basic format is an option name followed by a value (argument) on the +same line. Values may be separated from the option name with a colon, +equal sign or simply white space. Values may be continued across multiple +lines by escaping the newline with a backslash. + +Multiple programs may also share the same initialization file. +Common options are collected at the top, followed by program specific +segments. The segments are separated by lines like: +@example +[AUTOGEN] +@end example +@noindent +or by +@example + +@end example +@noindent +Do not mix these styles within one configuration file. + +Compound values and carefully constructed string values may also be +specified using XML syntax: +@example + + ...<...>... + +@end example +@noindent +yielding an @code{option-name.sub-opt} string value of +@example +"...<...>..." +@end example +@code{AutoOpts} does not track suboptions. You simply note that it is a +hierarchicly valued option. @code{AutoOpts} does provide a means for searching +the associated name/value pair list (see: optionFindValue). + +The command line options relating to configuration and/or usage help are: + +@subheading version (-v) + +Print the program version to standard out, optionally with licensing +information, then exit 0. The optional argument specifies how much licensing +detail to provide. The default is to print just the version. The licensing information may be selected with an option argument. +Only the first letter of the argument is examined: + +@table @samp +@item version +Only print the version. This is the default. +@item copyright +Name the copyright usage licensing terms. +@item verbose +Print the full copyright usage licensing terms. +@end table + +@subheading usage (-u) + +Print abbreviated usage to standard out, then exit 0. + +@subheading reset-option (-R) + +Resets the specified option to the compiled-in initial state. +This will undo anything that may have been set by configuration files. +The option argument may be either the option flag character or its long name. + +@node autogen exit status +@section autogen exit status + +One of the following exit values will be returned: +@table @samp +@item 0 (EXIT_SUCCESS) +Successful program execution. +@item 1 (EXIT_OPTION_ERROR) +The command options were misconfigured. +@item 2 (EXIT_BAD_TEMPLATE) +An error was encountered processing the template. +@item 3 (EXIT_BAD_DEFINITIONS) +The definitions could not be deciphered. +@item 4 (EXIT_LOAD_ERROR) +An error was encountered during the load phase. +@item 5 (EXIT_FS_ERROR) +a file system error stopped the program. +@item 6 (EXIT_NO_MEM) +Insufficient memory to operate. +@item 128 (EXIT_SIGNAL) +@command{autogen} exited due to catching a signal. If your template includes +string formatting, a number argument to a "%s" formatting element will +trigger a segmentation fault. Autogen will catch the seg fault signal +and exit with @code{AUTOGEN_EXIT_SIGNAL(5)}. Alternatively, AutoGen +may have been interrupted with a @code{kill(2)} signal. + +Subtract 128 from the actual exit code to detect the signal number. +@item 66 (EX_NOINPUT) +A specified configuration file could not be loaded. +@item 70 (EX_SOFTWARE) +libopts had an internal operational error. Please report +it to autogen-users@@lists.sourceforge.net. Thank you. +@end table +@node autogen Examples +@section autogen Examples +Here is how the man page is produced: +@example +autogen -Tagman-cmd.tpl -MFman-dep -MTstamp-man opts.def +@end example + +This command produced this man page from the AutoGen option definition +file. It overrides the template specified in @file{opts.def} (normally +@file{options.tpl}) and uses @file{agman-cmd.tpl}. It also sets the +make file dependency output to @file{man-dep} and the sentinel file +(time stamp file) to @file{man-stamp}. The base of the file name is +derived from the defined @code{prog-name}. + +The texi invocation document is produced via: +@example +autogen -Tagtexi-cmd.tpl -MFtexi-dep -MTtexi-stamp opts.def +@end example diff --git a/doc/invoke-bitmaps.texi b/doc/invoke-bitmaps.texi new file mode 100644 index 0000000..b3b5592 --- /dev/null +++ b/doc/invoke-bitmaps.texi @@ -0,0 +1,348 @@ +@ignore + +This file is part of AutoGen. +AutoGen is free software. +AutoGen is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + +AutoGen is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +AutoGen is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program. If not, see . + +This file has the following md5sum: + +43b91e8ca915626ed3818ffb1b71248b COPYING.gplv3 + +@end ignore +@node Bit Maps +@section Bit Maps and Enumerations + +AutoGen provides two templates for managing enumerations and bit maps +(flag words). They produce an enumeration of the enum or @code{#define}s +for the bit maps, plus conversion functions for converting a string into +one of these values or converting one of these values into a human readable +string. Finally, for enumerations, you may specify one or more sets of +dispatching functions that will be selected by identifying a keyword +prefix of a string (@pxref{enum-code, the @i{dispatch} attribute in +Strings to Enums and Back}). + +There is a separate project that produces a GDB add-on that +will add these capabilities into GDB for bit masks. (GDB does just fine +with enumerations.) + +@menu +* enums:: Enumerations +* enum-code:: Strings to Enums and Back +* masks:: Bit Maps and Masks +@end menu + +@node enums +@subsection Enumerations + +@file{str2enum.tpl} + +Produce an enumeration for a list of input ``cmd''s (names). +Optionally, produce functions to: + +@itemize @bullet +@item +convert a string to an enumeration +@item +convert an enumeration value into a string +@item +invoke a function based on the first token name found in a string +@end itemize + +The header file produced will contain the enumeration and declarations +for the optional procedures. The code (@file{.c}) file will contain +these optional procedures, but can be omitted if the @code{no-code} +attribute is specified. + +The following attributes are recognized with the @code{str2enum} template: + +@table @samp +@item cmd +You must provide a series of these attributes: they specify the list of +names used in the enumeration. Specific values for the names may be +specified by specifying a numeric index for these attributes. +e.g. @code{cmd[5] = mumble;} will cause +@example +FOO_CMD_MUMBLE = 5 +@end example +@noindent +to be inserted into the enumeration. +Do not specify a value of ``@t{invalid}'', unless you specify the +@code{invalid-name} attribute. (In that case, do not specify a +@code{cmd} value that matches the @code{invalid-name} value.) + +@item prefix +This specifies the first segment of each enumeration name. +If not specified, the first segment of the enumeration definition file name +will be used. e.g. @file{foo-bar.def} will default to a @code{FOO} prefix. + +@item type +Normally, there is a second constant segment following the prefix. If not +specified, it will be @code{CMD}, so if both @code{prefix} and @code{type} +were to default from @file{foo-bar.def}, you will have enumeration values +prefixed with @code{FOO_CMD_}. If specified as the empty string, there will +be no ``type'' component to the name and the default constant prefix will +thus be @code{FOO_}. + +@item base-name +This specifies the base name of the output files, enumeration type and the +translation functions. The default is to use the @code{basename(3)} of +the definition file. e.g. @file{foo-bar.def} results in a @code{base-name} +of @code{foo-bar}. + +@item invalid-val +The default invalid value is zero. Sometimes, it is useful for zero to be +valid. If so, you can specify @t{~0} or the empty string to be invalid. +The empty string will cause the enumeration count (maximum value plus 1) to +be the invalid value. + +@item invalid-name +By default, the invalid value is emitted into the enumeration as +@code{FOO_INVALID_CMD}. Specifying this attribute will replace +@code{INVALID} with whatever you place in this attribute. + +@item add-on-text +Additional text to insert into the code or header file. + +@table @samp +@item ao-file +Which file to insert the text into. There are four choices, +only two of which are relevant for the @file{str2enum} template: +``@t{enum-header}'', ``@t{enum-code}'', ``@t{mask-header}'' or ``@t{mask-code}''. + +@item ao-text +The text to insert. +@end table +@end table + +@c +@c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +@c +@node enum-code +@subsection Strings to Enums and Back + +A continuation of the attributes for the @file{str2enum.tpl} template. + +@table @samp +@item no-code +Do not emit any string to enumeration or enumeration to string code at all. +If this is specified, the remainder of the attributes have no effect. + +@item no-name +Do not emit the enumeration to name function. + +@item no-case +When looking up a string, the case of the input string is ignored. + +@item alias +A single punctuation character can be interpreted as a command. The first +character of this attribute is the aliased character and the remainder the +aliased-to command. e.g. ``@t{#comment}'' makes '@t{#}' an alias for the +@command{comment} command. ``@t{#comment}'' must still be listed in the +@code{cmd} attributes. + +@item length +Specify how lengths are to be handled. Under the covers, @command{gperf(1)} +is used to map a string to an enumeration value. The code it produces +requires the string length to be passed in. You may pass in the length +yourself, or the generated code may figure it out, or you may ask for that +length to be returned back after being figured out. + +You have four choices with the @code{length} attribute: + +@itemize @bullet +@item +Do not specify it. You will need to provide the length. +@item +Specify ``@t{provided}''. You will need to provide the length. +@item +Specify ``@t{returned}''. You must pass a pointer to a @t{size_t} object. +If the name is found, the length will be put there. +@item +Specify an empty string. The generated code will compute the length and +that computed length will not be returned. The length parameter may be +omitted. If the input strings contain only enumeration names, then this +would be sufficient. +@item +Specifying anything else is undefined. +@end itemize + +@item partial +Normally, a name must fully match to be found successfully. This attribute +causes the generated code to look for partial matches if the full match +@command{gperf} function fails. Partial matches must be at least two +characters long. + +@item undef-str +by default, the display string for an undefined value is +``@t{* UNDEFINED *}''. Use this to change that. + +@item equate +A series of punctuation characters considered equivalent. +Typically, ``@t{-_}'' but sometimes (Tandem) ``@t{-_^}''. +Do not use '@t{#}' in the list of characters. + +@item dispatch +A lookup procedure will call a dispatch function for the procedure named +after the keyword identified at the start of a string. Other than as +specially noted below, for every named ``cmd'', must have a handling +function, plus another function to handle errors, with ``invalid'' (or the +@code{invalid-name} value) as the @code{cmd} name. Multiple @code{dispatch} +definitions will produce multiple dispatching functions, each with +(potentially) unique argument lists and return types. + +You may also use @code{add-on-text} to ``@t{#define}'' one function to +another, thus allowing one function to handle multiple keywords or commands. +The @code{d-nam} and @code{d-ret} attributes are required. The @code{d-arg}, +@code{d-omit} and @code{d-only} attributes are optional: + +@table @samp +@item d-nam +This must be a printf format string with one formatting element: @code{%s}. +The @code{%s} will be replaced by each @code{cmd} name. The @code{%s} will +be stripped and the result will be combined with the base name to construct +the dispatch procedure name. + +@item d-ret +The return type of the dispatched function, even if ``@t{void}''. + +@item d-arg +If there are additional arguments that are to be passed through to the +dispatched function, specify this as though it were part of the procedure +header. (It will be glued into the dispatching function as is and sedded +into what is needed for the dispatched function.) + +@item d-omit +Instead of providing handling functions for all of the @code{cmd} names, +the invalid function will be called for omitted command codes. + +@item d-only +You need only provide functions for the names listed by @code{d-only}, plus +the ``invalid'' name. All other command values will trigger calls to +the invalid handling function. Note that the invalid call can distinguish +from a command that could not be found by examining the value of its +first (@code{id}) argument. +@end table + +The handler functions will have the command enumeration as its first first +argument, a pointer to a constant string that will be the character +@i{after} the parsed command (keyword) name, plus any @code{d-arg} arguments +that follow that. + +@noindent +As an example, a file @file{samp-chk.def} containing this: +@example +AutoGen Definitions str2enum; +cmd = one, two; invalid-name = oops; +dispatch = @{ d-nam = 'hdl_%s_cmd'; d-ret = void; @}; +@end example +@noindent +will produce a header containing: +@example +typedef enum @{ + SAMP_OOPS_CMD = 0, + SAMP_CMD_ONE = 1, + SAMP_CMD_TWO = 2, + SAMP_COUNT_CMD +@} samp_chk_enum_t; + +extern samp_chk_enum_t +find_samp_chk_cmd(char const * str, size_t len); + +typedef void(samp_chk_handler_t)( + samp_chk_enum_t id, char const * str); + +samp_chk_handler_t + hdl_oops_cmd, hdl_one_cmd, hdl_two_cmd; + +extern void +disp_samp_chk(char * str, size_t len); + +extern char const * +samp_chk_name(samp_chk_enum_t id); +@end example + +@itemize @bullet +@item +@code{find_samp_chk_cmd} will look up a @code{len} byte @code{str} and +return the corresponding @code{samp_chk_enum_t} value. That value is +@code{SAMP_OOPS_CMD} if the string is not ``one'' or ``two''. +@item +@code{samp_chk_handler_t} is the type of the callback procedures. +Three must be provided for the dispatching function to call: +@code{hdl_oops_cmd}, @code{hdl_one_cmd} and @code{hdl_two_cmd}. +@code{hdl_oops_cmd} will receive calls when the string does not match. +@item +@code{disp_samp_chk} this function will call the handler function +and return whatever the handler returns. In this case, it is void. +@item +@code{samp_chk_name} will return a string corresponding to the enumeration +value argument. If the value is not valid, ``* UNDEFINED *'' (or the +value of @code{undef-str}) is used. +@end itemize +@end table + +@c +@c * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * +@c +@node masks +@subsection Bit Maps and Masks + +@file{str2mask.tpl} + +This template leverages highly off of enumerations (@pxref{enums}). It will +produce a header file with bit masks defined for each bit specified with a +@code{cmd} attribute. 63 is the highest legal bit number because this +template has not been extended to cope with multiple word masks. (Patches +would be welcome.) + +There are a few constraints on the names allowed: + +@itemize @bullet +@item +names are constrained to alphanumerics and the underscore +@item +aliases are not allowed +@item +dispatch procedures are not allowed +@end itemize + +@code{no-code} and @code{no-name} are honored. @code{dispatch} is not. The +lookup function will examine each token in an input string, determine which +bit is specified and add it into a result. The names may be prefixed with a +hyphen (@t{-}) or tilde (@t{~}) to remove the bit(s) from the cumulative +result. If the string begins with a plus (@t{+}), hyphen or tilde, a ``base +value'' parameter is used for the starting mask, otherwise the conversion +starts with zero. + +Beyond the enumeration attributes that are used (or ignored), the +@file{str2mask} template accepts a @code{mask} attribute. It takes a few +``subattributes'': + +@table @samp +@item m-name +a special name for a sub-collection of the mask bits + +@item m-bit +The name of each previously defined bit(s). If the desired previously +defined value is a mask, that @code{m-name} must be suffixed with ``@t{-mask}''. + +@item m-invert +When all done collecting the bits, x-or the value with the mask +of all the bits in the collection. +@end table + +@noindent +A mask of all bits in the collection is always generated. diff --git a/doc/invoke-columns.texi b/doc/invoke-columns.texi new file mode 100644 index 0000000..a426832 --- /dev/null +++ b/doc/invoke-columns.texi @@ -0,0 +1,415 @@ +@node columns Invocation +@section Invoking columns +@pindex columns +@cindex Columnize Input Text +@ignore +# -*- buffer-read-only: t -*- vi: set ro: +# +# DO NOT EDIT THIS FILE (invoke-columns.texi) +# +# It has been AutoGen-ed +# From the definitions ./opts.def +# and the template file agtexi-cmd.tpl +@end ignore +This program was designed for the purpose of generating compact, +columnized tables. It will read a list of text items from standard +in or a specified input file and produce a columnized listing of +all the non-blank lines. Leading white space on each line is +preserved, but trailing white space is stripped. Methods of +applying per-entry and per-line embellishments are provided. +See the formatting and separation arguments below. + +This program is used by AutoGen to help clean up and organize +its output. + +See @file{autogen/agen5/fsm.tpl} and the generated output +@file{pseudo-fsm.h}. + +This function was not implemented as an expression function because +either it would have to be many expression functions, or a provision +would have to be added to provide options to expression functions. +Maybe not a bad idea, but it is not being implemented at the moment. + +A side benefit is that you can use it outside of @code{autogen} to +columnize input, a la the @code{ls} command. + +This section was generated by @strong{AutoGen}, +using the @code{agtexi-cmd} template and the option descriptions for the @code{columns} program. +This software is released under the GNU General Public License, version 3 or later. + +@menu +* columns usage:: columns help/usage (@option{--help}) +* columns dimensions:: dimensions options +* columns treatment:: treatment options +* columns ordering:: ordering options +* columns input-text:: input-text options +* columns config:: presetting/configuring columns +* columns exit status:: exit status +* columns See Also:: See Also +@end menu + +@node columns usage +@subsection columns help/usage (@option{--help}) +@cindex columns help + +This is the automatically generated usage text for columns. + +The text printed is the same whether selected with the @code{help} option +(@option{--help}) or the @code{more-help} option (@option{--more-help}). @code{more-help} will print +the usage text by passing it through a pager program. +@code{more-help} is disabled on platforms without a working +@code{fork(2)} function. The @code{PAGER} environment variable is +used to select the program, defaulting to @file{more}. Both will exit +with a status code of 0. + +@exampleindent 0 +@example +columns (GNU AutoGen) - Columnize Input Text - Ver. 1.2 +Usage: columns [ - [] | --[@{=| @}] ]... + +Specify the output dimensions: + + Flg Arg Option-Name Description + -W Num width Maximum Line Width + - it must be in the range: + 16 to 4095 + -c Num columns Desired number of columns + - it must be in the range: + 1 to 2048 + -w Num col-width Set width of each column + - it must be in the range: + 1 to 2048 + Num tab-width tab width + +Specify how to lay out the text: + + Flg Arg Option-Name Description + Num spread maximum spread added to column width + - it must be in the range: + 1 to 1024 + no fill Fill lines with input + - prohibits these options: + spread + col-width + by-columns + -I Str indent Line prefix or indentation + Str first-indent First line prefix + - requires the option 'indent' + -f Str format Formatting string for each input + -S Str separation Separation string - follows all but last + Str line-separation string at end of all lines but last + Str ending string at end of last line + +Specify the ordering of the entries: + + Flg Arg Option-Name Description + no by-columns Print entries in column order + -s opt sort Sort input text + +Redirecting stdin to an alternate file: + + Flg Arg Option-Name Description + -i Str input Input file (if not stdin) + +Version, usage and configuration options: + + Flg Arg Option-Name Description + -v opt version output version information and exit + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + -> opt save-opts save the option state to a config file + -< Str load-opts load options from a config file + - disabled as '--no-load-opts' + - may appear multiple times + +Options are specified by doubled hyphens and their name or by a single +hyphen and the flag character. + +The following option preset mechanisms are supported: + - reading file ./.columnsrc + - reading file $HOME/.columnsrc + - examining environment variables named COLUMNS_* + +Please send bug reports to: +@end example +@exampleindent 4 + +@node columns dimensions +@subsection dimensions options +Specify the output dimensions. +@subsubheading width option (-W). +@anchor{columns width} +@cindex columns-width + +This is the ``maximum line width'' option. +This option takes a number argument @file{num}. +This option specifies the full width of the output line, +including any start-of-line indentation. The output will fill +each line as completely as possible, unless the column width has +been explicitly specified. If the maximum width is less than +the length of the widest input, you will get a single column +of output. +@subsubheading columns option (-c). +@anchor{columns columns} +@cindex columns-columns + +This is the ``desired number of columns'' option. +This option takes a number argument @file{count}. +Use this option to specify exactly how many columns to produce. +If that many columns will not fit within @var{line_width}, then +the count will be reduced to the number that fit. +@subsubheading col-width option (-w). +@anchor{columns col-width} +@cindex columns-col-width + +This is the ``set width of each column'' option. +This option takes a number argument @file{num}. +Use this option to specify exactly how many characters are to be +allocated for each column. If it is narrower than the widest entry, +it will be over-ridden with the required width. +@subsubheading tab-width option. +@anchor{columns tab-width} +@cindex columns-tab-width + +This is the ``tab width'' option. +This option takes a number argument @file{num}. +If an indentation string contains tabs, then this value is used to +compute the ending column of the prefix string. +@node columns treatment +@subsection treatment options +Specify how to lay out the text. +@subsubheading spread option. +@anchor{columns spread} +@cindex columns-spread + +This is the ``maximum spread added to column width'' option. +This option takes a number argument @file{num}. +Use this option to specify exactly how many characters may be +added to each column. It allows you to prevent columns from +becoming too far apart. Without this option, @file{columns} +will attempt to widen columns to fill the full width. +@subsubheading fill option. +@anchor{columns fill} +@cindex columns-fill + +This is the ``fill lines with input'' option. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +must not appear in combination with any of the following options: +spread, col_width, by_columns. +@end itemize + +Instead of columnizing the input text, fill the output lines +with the input lines. Blank lines on input will cause a +blank line in the output, unless the output is sorted. +With sorted output, blank lines are ignored. +@subsubheading indent option (-I). +@anchor{columns indent} +@cindex columns-indent + +This is the ``line prefix or indentation'' option. +This option takes a string argument @file{l-pfx}. +If a number, then this many spaces will be inserted at the start of +every line. Otherwise, it is a line prefix that will be inserted +at the start of every line. +@subsubheading first-indent option. +@anchor{columns first-indent} +@cindex columns-first-indent + +This is the ``first line prefix'' option. +This option takes a string argument @file{l-pfx}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +must appear in combination with the following options: +indent. +@end itemize + +If a number, then this many spaces will be inserted at the start of +the first line. Otherwise, it is a line prefix that will be inserted +at the start of that line. If its length exceeds "indent", then it +will be emitted on a line by itself, suffixed by any line separation +string. For example: + +@example +$ columns --first='#define TABLE' -c 2 -I4 --line=' \' <<_EOF_ +one +two +three +four +_EOF_ +#define TABLE \ + one two \ + three four +@end example +@subsubheading format option (-f). +@anchor{columns format} +@cindex columns-format + +This is the ``formatting string for each input'' option. +This option takes a string argument @file{fmt-str}. +If you need to reformat each input text, the argument to this +option is interpreted as an @code{sprintf(3)} format that is used +to produce each output entry. +@subsubheading separation option (-S). +@anchor{columns separation} +@cindex columns-separation + +This is the ``separation string - follows all but last'' option. +This option takes a string argument @file{sep-str}. +Use this option if, for example, you wish a comma to appear after +each entry except the last. +@subsubheading line-separation option. +@anchor{columns line-separation} +@cindex columns-line-separation + +This is the ``string at end of all lines but last'' option. +This option takes a string argument @file{sep-str}. +Use this option if, for example, you wish a backslash to appear at +the end of every line, except the last. +@subsubheading ending option. +@anchor{columns ending} +@cindex columns-ending + +This is the ``string at end of last line'' option. +This option takes a string argument @file{end-str}. +This option puts the specified string at the end of the output. +@node columns ordering +@subsection ordering options +Specify the ordering of the entries. +@subsubheading by-columns option. +@anchor{columns by-columns} +@cindex columns-by-columns + +This is the ``print entries in column order'' option. +Normally, the entries are printed out in order by rows and then columns. +This option will cause the entries to be ordered within columns. +The final column, instead of the final row, may be shorter than the +others. +@subsubheading sort option (-s). +@anchor{columns sort} +@cindex columns-sort + +This is the ``sort input text'' option. +This option takes an optional string argument @file{key-pat}. +Causes the input text to be sorted. If an argument is supplied, +it is presumed to be a pattern and the sort is based upon the +matched text. If the pattern starts with or consists of +an asterisk (@code{*}), then the sort is case insensitive. +@node columns input-text +@subsection input-text options +Redirecting stdin to an alternate file. +@subsubheading input option (-i). +@anchor{columns input} +@cindex columns-input + +This is the ``input file (if not stdin)'' option. +This option takes a string argument @file{file}. +This program normally runs as a @code{filter}, reading from standard +input, columnizing and writing to standard out. This option redirects +input to a file. + + +@node columns config +@subsection presetting/configuring columns + +Any option that is not marked as @i{not presettable} may be preset by +loading values from configuration ("rc" or "ini") files, and values from environment variables named @code{COLUMNS} and @code{COLUMNS_}. @code{} must be one of +the options listed above in upper case and segmented with underscores. +The @code{COLUMNS} variable will be tokenized and parsed like +the command line. The remaining variables are tested for existence and their +values are treated like option arguments. + + +@noindent +@code{libopts} will search in 2 places for configuration files: +@itemize @bullet +@item +$PWD +@item +$HOME +@end itemize +The environment variables @code{PWD}, and @code{HOME} +are expanded and replaced when @file{columns} runs. +For any of these that are plain files, they are simply processed. +For any that are directories, then a file named @file{.columnsrc} is searched for +within that directory and processed. + +Configuration files may be in a wide variety of formats. +The basic format is an option name followed by a value (argument) on the +same line. Values may be separated from the option name with a colon, +equal sign or simply white space. Values may be continued across multiple +lines by escaping the newline with a backslash. + +Multiple programs may also share the same initialization file. +Common options are collected at the top, followed by program specific +segments. The segments are separated by lines like: +@example +[COLUMNS] +@end example +@noindent +or by +@example + +@end example +@noindent +Do not mix these styles within one configuration file. + +Compound values and carefully constructed string values may also be +specified using XML syntax: +@example + + ...<...>... + +@end example +@noindent +yielding an @code{option-name.sub-opt} string value of +@example +"...<...>..." +@end example +@code{AutoOpts} does not track suboptions. You simply note that it is a +hierarchicly valued option. @code{AutoOpts} does provide a means for searching +the associated name/value pair list (see: optionFindValue). + +The command line options relating to configuration and/or usage help are: + +@subsubheading version (-v) + +Print the program version to standard out, optionally with licensing +information, then exit 0. The optional argument specifies how much licensing +detail to provide. The default is to print just the version. The licensing information may be selected with an option argument. +Only the first letter of the argument is examined: + +@table @samp +@item version +Only print the version. This is the default. +@item copyright +Name the copyright usage licensing terms. +@item verbose +Print the full copyright usage licensing terms. +@end table + +@node columns exit status +@subsection columns exit status + +One of the following exit values will be returned: +@table @samp +@item 0 (EXIT_SUCCESS) +Successful program execution. +@item 1 (EXIT_FAILURE) +The operation failed or the command syntax was not valid. +@item 66 (EX_NOINPUT) +A specified configuration file could not be loaded. +@item 70 (EX_SOFTWARE) +libopts had an internal operational error. Please report +it to autogen-users@@lists.sourceforge.net. Thank you. +@end table +@node columns See Also +@subsection columns See Also +This program is documented more fully in the Columns section +of the Add-On chapter in the @code{AutoGen} Info system documentation. diff --git a/doc/invoke-getdefs.texi b/doc/invoke-getdefs.texi new file mode 100644 index 0000000..60e42e8 --- /dev/null +++ b/doc/invoke-getdefs.texi @@ -0,0 +1,583 @@ +@node getdefs Invocation +@section Invoking getdefs +@pindex getdefs +@cindex AutoGen Definition Extraction Tool +@ignore +# -*- buffer-read-only: t -*- vi: set ro: +# +# DO NOT EDIT THIS FILE (invoke-getdefs.texi) +# +# It has been AutoGen-ed +# From the definitions ./opts.def +# and the template file agtexi-cmd +@end ignore + +If no @code{input} argument is provided or is set to simply "-", and if +@code{stdin} is not a @code{tty}, then the list of input files will be +read from @code{stdin}. +This program extracts AutoGen definitions from a list of source files. +Definitions are delimited by @code{/*= \n} and +@code{=*/\n}. From that, this program creates a definition of the following +form: + +@example + #line nnn "source-file-name" + entry_type = @{ + name = entry_name; + ... + @}; +@end example + +@enumerate +@item +The ellipsis @code{...} is filled in by text found between the two +delimiters. Each line of text is stripped of anything before the first +asterisk, then leading asterisks, then any leading or trailing white space. + +@item +If what is left starts with what looks like a name followed by a colon, then +it is interpreted as a name followed by a value. + +@item +If the first character of the value is either a single or double quote, then +you are responsible for quoting the text as it gets inserted into the output +definitions. So, if you want whitespace at the beginnings of the lines of +text, you must do something like this: + +@example + * mumble: + * " this is some\n" + * " indented text." +@end example + +@item +If the @code{} is followed by a comma, the word @code{ifdef} (or +@code{ifndef}) and a name @code{if_name}, then the above entry will be under +@code{ifdef} control. + +@example +/*=group entry_name, ifdef FOO + * attr: attribute value +=*/ +@end example + +Will produce the following: + +@example +#ifdef FOO +#line nnn "source-file-name" +group = @{ + name = entry_name; + attr = 'attribute value'; +@}; +#endif +@end example + +@item +If you use of the @code{subblock} option, you can specify a nested +value, @xref{getdefs subblock}. That is, this text: + +@example + * arg: int, this, what-it-is +@end example + +with the @code{--subblock=arg=type,name,doc} option would yield: + +@example +arg = @{ type = int; name = this; doc = what-it-is; @}; +@end example +@end enumerate + +This section was generated by @strong{AutoGen}, +using the @code{agtexi-cmd} template and the option descriptions for the @code{getdefs} program. +This software is released under the GNU General Public License, version 3 or later. + +@menu +* getdefs usage:: getdefs help/usage (@option{help}) +* getdefs def-selection:: def-selection options +* getdefs enumerating:: enumerating options +* getdefs doc-insert:: doc-insert options +* getdefs input-files:: input-files options +* getdefs doc-output:: doc-output options +* getdefs config:: presetting/configuring getdefs +* getdefs exit status:: exit status +* getdefs See Also:: See Also +@end menu + +@node getdefs usage +@subsection getdefs help/usage (@option{help}) +@cindex getdefs help + +This is the automatically generated usage text for getdefs. + +The text printed is the same whether selected with the @code{help} option +(@option{help}) or the @code{more-help} option (@option{more-help}). @code{more-help} will print +the usage text by passing it through a pager program. +@code{more-help} is disabled on platforms without a working +@code{fork(2)} function. The @code{PAGER} environment variable is +used to select the program, defaulting to @file{more}. Both will exit +with a status code of 0. + +@exampleindent 0 +@example +getdefs error: invalid option descriptor for version +getdefs (GNU AutoGen) - AutoGen Definition Extraction Tool - Ver. 1.5 +Usage: getdefs [ [@{=| @}] ]... + +Specify which definitions are of interest and what to say about them: + + Arg Option-Name Description + Str defs-to-get Regexp to look for after the "/*=" + Str subblock subblock definition names + - may appear multiple times + Str listattr attribute with list of values + - may appear multiple times + +specify how to number the definitions: + + Arg Option-Name Description + opt ordering Alphabetize or use named file + - disabled as '--no-ordering' + - enabled by default + Num first-index The first index to apply to groups + +Definition insertion options: + + Arg Option-Name Description + opt filelist Insert source file names into defs + Str assign Global assignments + - may appear multiple times + Str common-assign Assignments common to all blocks + - may appear multiple times + Str copy File(s) to copy into definitions + - may appear multiple times + opt srcfile Insert source file name into each def + opt linenum Insert source line number into each def + +specify which files to search for markers: + + Arg Option-Name Description + Str input Input file to search for defs + - may appear multiple times + - default option for unnamed options + +Definition output disposition options:: + + Arg Option-Name Description + Str output Output file to open + - an alternate for 'autogen' + opt autogen Invoke AutoGen with defs + - disabled as '--no-autogen' + - enabled by default + Str template Template Name + Str agarg AutoGen Argument + - prohibits the option 'output' + - may appear multiple times + Str base-name Base name for output file(s) + - prohibits the option 'output' + +Version, usage and configuration options: + + Arg Option-Name Description +@end example +@exampleindent 4 + +@node getdefs def-selection +@subsection def-selection options +Specify which definitions are of interest and what to say about them. +@subsubheading defs-to-get option. +@anchor{getdefs defs-to-get} +@cindex getdefs-defs-to-get + +This is the ``regexp to look for after the "/*="'' option. +This option takes a string argument @file{reg-ex}. +If you want definitions only from a particular category, or even +with names matching particular patterns, then specify this regular +expression for the text that must follow the @code{/*=}. +@subsubheading subblock option. +@anchor{getdefs subblock} +@cindex getdefs-subblock + +This is the ``subblock definition names'' option. +This option takes a string argument @file{sub-def}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +may appear an unlimited number of times. +@end itemize + +This option is used to create shorthand entries for nested definitions. +For example, with: +@table @r +@item using subblock thus +@code{--subblock=arg=argname,type,null} +@item and defining an @code{arg} thus +@code{arg: this, char *} +@item will then expand to: +@code{arg = @{ argname = this; type = "char *"; @};} +@end table +The "this, char *" string is separated at the commas, with the +white space removed. You may use characters other than commas by +starting the value string with a punctuation character other than +a single or double quote character. You may also omit intermediate +values by placing the commas next to each other with no intervening +white space. For example, "+mumble++yes+" will expand to: +@* +@code{arg = @{ argname = mumble; null = "yes"; @};}. +@subsubheading listattr option. +@anchor{getdefs listattr} +@cindex getdefs-listattr + +This is the ``attribute with list of values'' option. +This option takes a string argument @file{def}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +may appear an unlimited number of times. +@end itemize + +This option is used to create shorthand entries for definitions +that generally appear several times. That is, they tend to be +a list of values. For example, with: +@* +@code{listattr=foo} defined, the text: +@* +@code{foo: this, is, a, multi-list} will then expand to: +@* +@code{foo = 'this', 'is', 'a', 'multi-list';} +@* +The texts are separated by the commas, with the +white space removed. You may use characters other than commas by +starting the value string with a punctuation character other than +a single or double quote character. +@node getdefs enumerating +@subsection enumerating options +specify how to number the definitions. +@subsubheading ordering option. +@anchor{getdefs ordering} +@cindex getdefs-ordering + +This is the ``alphabetize or use named file'' option. +This option takes an optional string argument @file{file-name}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +can be disabled with --no-ordering. +@item +It is enabled by default. +@end itemize + +By default, ordering is alphabetical by the entry name. Use, +@code{no-ordering} if order is unimportant. Use @code{ordering} +with no argument to order without case sensitivity. Use +@code{ordering=} if chronological order is important. +getdefs will maintain the text content of @code{file-name}. +@code{file-name} need not exist. +@subsubheading first-index option. +@anchor{getdefs first-index} +@cindex getdefs-first-index + +This is the ``the first index to apply to groups'' option. +This option takes a number argument @file{first-index}. +By default, the first occurrence of a named definition will have an +index of zero. Sometimes, that needs to be a reserved value. Provide +this option to specify a different starting point. +@node getdefs doc-insert +@subsection doc-insert options +Definition insertion options. +@subsubheading filelist option. +@anchor{getdefs filelist} +@cindex getdefs-filelist + +This is the ``insert source file names into defs'' option. +This option takes an optional string argument @file{file}. +Inserts the name of each input file into the output definitions. +If no argument is supplied, the format will be: +@example +infile = '%s'; +@end example +If an argument is supplied, that string will be used for the entry +name instead of @var{infile}. +@subsubheading assign option. +@anchor{getdefs assign} +@cindex getdefs-assign + +This is the ``global assignments'' option. +This option takes a string argument @file{ag-def}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +may appear an unlimited number of times. +@end itemize + +The argument to each copy of this option will be inserted into +the output definitions, with only a semicolon attached. +@subsubheading common-assign option. +@anchor{getdefs common-assign} +@cindex getdefs-common-assign + +This is the ``assignments common to all blocks'' option. +This option takes a string argument @file{ag-def}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +may appear an unlimited number of times. +@end itemize + +The argument to each copy of this option will be inserted into +each output definition, with only a semicolon attached. +@subsubheading copy option. +@anchor{getdefs copy} +@cindex getdefs-copy + +This is the ``file(s) to copy into definitions'' option. +This option takes a string argument @file{file}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +may appear an unlimited number of times. +@end itemize + +The content of each file named by these options will be inserted into +the output definitions. +@subsubheading srcfile option. +@anchor{getdefs srcfile} +@cindex getdefs-srcfile + +This is the ``insert source file name into each def'' option. +This option takes an optional string argument @file{file}. +Inserts the name of the input file where a definition was found +into the output definition. +If no argument is supplied, the format will be: +@example +srcfile = '%s'; +@end example +If an argument is supplied, that string will be used for the entry +name instead of @var{srcfile}. +@subsubheading linenum option. +@anchor{getdefs linenum} +@cindex getdefs-linenum + +This is the ``insert source line number into each def'' option. +This option takes an optional string argument @file{def-name}. +Inserts the line number in the input file where a definition +was found into the output definition. +If no argument is supplied, the format will be: +@example +linenum = '%s'; +@end example +If an argument is supplied, that string will be used for the entry +name instead of @var{linenum}. +@node getdefs input-files +@subsection input-files options +specify which files to search for markers. +@subsubheading input option. +@anchor{getdefs input} +@cindex getdefs-input + +This is the ``input file to search for defs'' option. +This option takes a string argument @file{src-file}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +may appear an unlimited number of times. +@end itemize + +All files that are to be searched for definitions must be named on +the command line or read from @code{stdin}. If there is only one +@code{input} option and it is the string, "-", then the input file +list is read from @code{stdin}. If a command line argument is not +an option name and does not contain an assignment operator +(@code{=}), then it defaults to being an input file name. +At least one input file must be specified. +@node getdefs doc-output +@subsection doc-output options +Definition output disposition options:. +@subsubheading output option. +@anchor{getdefs output} +@cindex getdefs-output + +This is the ``output file to open'' option. +This option takes a string argument @file{file}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +is a member of the autogen class of options. +@end itemize + +If you are not sending the output to an AutoGen process, +you may name an output file instead. +@subsubheading autogen option. +@anchor{getdefs autogen} +@cindex getdefs-autogen + +This is the ``invoke autogen with defs'' option. +This option takes an optional string argument @file{ag-cmd}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +can be disabled with --no-autogen. +@item +It is enabled by default. +@item +is a member of the autogen class of options. +@end itemize + +This is the default output mode. Specifying @code{no-autogen} is +equivalent to @code{output=-}. If you supply an argument to this +option, that program will be started as if it were AutoGen and +its standard in will be set to the output definitions of this program. +@subsubheading template option. +@anchor{getdefs template} +@cindex getdefs-template + +This is the ``template name'' option. +This option takes a string argument @file{file}. +Specifies the template name to be used for generating the final output. +@subsubheading agarg option. +@anchor{getdefs agarg} +@cindex getdefs-agarg + +This is the ``autogen argument'' option. +This option takes a string argument @file{ag-opt}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +may appear an unlimited number of times. +@item +must not appear in combination with any of the following options: +output. +@end itemize + +This is a pass-through argument. It allows you to specify any +arbitrary argument to be passed to AutoGen. +@subsubheading base-name option. +@anchor{getdefs base-name} +@cindex getdefs-base-name + +This is the ``base name for output file(s)'' option. +This option takes a string argument @file{name}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +must not appear in combination with any of the following options: +output. +@end itemize + +When output is going to AutoGen, a base name must either be supplied +or derived. If this option is not supplied, then it is taken from +the @code{template} option. If that is not provided either, then +it is set to the base name of the current directory. + + +@node getdefs config +@subsection presetting/configuring getdefs + +Any option that is not marked as @i{not presettable} may be preset by +loading values from configuration ("rc" or "ini") files. + + +@noindent +@code{libopts} will search in @file{/dev/null} for configuration (option) data. +If this is a plain file, it is simply processed. +If it is a directory, then a file named @file{.getdefsrc} is searched for within that directory. + +Configuration files may be in a wide variety of formats. +The basic format is an option name followed by a value (argument) on the +same line. Values may be separated from the option name with a colon, +equal sign or simply white space. Values may be continued across multiple +lines by escaping the newline with a backslash. + +Multiple programs may also share the same initialization file. +Common options are collected at the top, followed by program specific +segments. The segments are separated by lines like: +@example +[GETDEFS] +@end example +@noindent +or by +@example + +@end example +@noindent +Do not mix these styles within one configuration file. + +Compound values and carefully constructed string values may also be +specified using XML syntax: +@example + + ...<...>... + +@end example +@noindent +yielding an @code{option-name.sub-opt} string value of +@example +"...<...>..." +@end example +@code{AutoOpts} does not track suboptions. You simply note that it is a +hierarchicly valued option. @code{AutoOpts} does provide a means for searching +the associated name/value pair list (see: optionFindValue). + +The command line options relating to configuration and/or usage help are: + +@subsubheading version + +Print the program version to standard out, optionally with licensing +information, then exit 0. The optional argument specifies how much licensing +detail to provide. The default is to print just the version. The licensing information may be selected with an option argument. +Only the first letter of the argument is examined: + +@table @samp +@item version +Only print the version. This is the default. +@item copyright +Name the copyright usage licensing terms. +@item verbose +Print the full copyright usage licensing terms. +@end table + +@node getdefs exit status +@subsection getdefs exit status + +One of the following exit values will be returned: +@table @samp +@item 0 (EXIT_SUCCESS) +Successful program execution. +@item 1 (EXIT_FAILURE) +The operation failed or the command syntax was not valid. +@item 2 (EXIT_INVALID_INPUT) +An input file was specified that is not a file +@item 3 (EXIT_NO_MEM) +Insufficient memory for operation +@item 66 (EX_NOINPUT) +A specified configuration file could not be loaded. +@item 70 (EX_SOFTWARE) +libopts had an internal operational error. Please report +it to autogen-users@@lists.sourceforge.net. Thank you. +@end table +@node getdefs See Also +@subsection getdefs See Also +This program is documented more fully in the Getdefs section +of the Add-On chapter in the @code{AutoGen} Info system documentation. diff --git a/doc/invoke-snprintfv.texi b/doc/invoke-snprintfv.texi new file mode 100644 index 0000000..380641c --- /dev/null +++ b/doc/invoke-snprintfv.texi @@ -0,0 +1,74 @@ +@node snprintfv +@section Replacement for Stdio Formatting Library + + Using the `printf' formatting routines in a portable fashion has +always been a pain, and this package has been way more pain than anyone +ever imagined. Hopefully, with this release of snprintfv, the pain is +now over for all time. + + The issues with portable usage are these: + +@enumerate +@item +Argument number specifiers are often either not implemented or are +buggy. Even GNU libc, version 1 got it wrong. + +@item +ANSI/ISO "forgot" to provide a mechanism for computing argument +lists for vararg procedures. + +@item +The argument array version of printf (`printfv()') is not +generally available, does not work with the native printf, and +does not have a working argument number specifier in the format +specification. (Last I knew, anyway.) + +@item +You cannot fake varargs by calling `vprintf()' with an array of +arguments, because ANSI does not require such an implementation +and some vendors play funny tricks because they are allowed to. +@end enumerate + + These four issues made it impossible for AutoGen to ship without its +own implementation of the `printf' formatting routines. Since we were +forced to do this, we decided to make the formatting routines both +better and more complete :-). We addressed these issues and added the +following features to the common printf API: + +@enumerate 5 +@item +The formatted output can be written to + +@itemize @bullet +@item +a string allocated by the formatting function (`asprintf()'). +@item +a file descriptor instead of a file stream (`dprintf()'). +@item +a user specified stream (`stream_printf()'). +@end itemize + +@item +The formatting functions can be augmented with your own functions. +These functions are allowed to consume more than one character +from the format, but must commence with a unique character. For +example, + +@example +"%@{struct stat@}\n" +@end example + +might be used with '@{' registered to a procedure that would look +up "struct stat" in a symbol table and do appropriate things, +consuming the format string through the '@}' character. +@end enumerate + + Gary V. Vaughan was generous enough to supply this implementation. +Many thanks!! + + For further details, the reader is referred to the snprintfv +documentation. These functions are also available in the template +processing as@: `sprintf' (@pxref{SCM sprintf}), `printf' +(@pxref{SCM printf}), `fprintf' (@pxref{SCM fprintf}), and `shellf' +(@pxref{SCM shellf}). + diff --git a/doc/invoke-xml2ag.texi b/doc/invoke-xml2ag.texi new file mode 100644 index 0000000..eebfaa0 --- /dev/null +++ b/doc/invoke-xml2ag.texi @@ -0,0 +1,423 @@ +@node xml2ag Invocation +@section Invoking xml2ag +@pindex xml2ag +@cindex XML to AutoGen Definiton Converter +@ignore +# -*- buffer-read-only: t -*- vi: set ro: +# +# DO NOT EDIT THIS FILE (invoke-xml2ag.texi) +# +# It has been AutoGen-ed +# From the definitions ./xmlopts.def +# and the template file agtexi-cmd +@end ignore + +This program will convert any arbitrary XML file into equivalent +AutoGen definitions, and invoke AutoGen. +The template used will be derived from either: +@itemize @bullet +@item +The @strong{--override-tpl} command line option +@item +A top level XML attribute named, "@code{template}" +@end itemize +@noindent +One or the other @strong{must} be provided, or the program will +exit with a failure message. + +The @emph{base-name} for the output will similarly be either: +@itemize @bullet +@item +The @strong{--base-name} command line option. +@item +The base name of the @file{.xml} file. +@end itemize + +The definitions derived from XML generally have an extra layer +of definition. Specifically, this XML input: +@example + + mumble-1 + + grumble, grumble, grumble. +mumble, mumble + +@end example +Will get converted into this: +@example +mumble = @{ + grumble = @{ + text = 'grumble, grumble, grumble'; + @}; + text = 'mumble-1'; + text = 'mumble, mumble'; +@}; +@end example +Please notice that some information is lost. AutoGen cannot tell that +"grumble" used to lie between the mumble texts. Also please note that +you cannot assign: +@example +grumble = 'grumble, grumble, grumble.'; +@end example +because if another "grumble" has an attribute or multiple texts, +it becomes impossible to have the definitions be the same type +(compound or text values). + +This section was generated by @strong{AutoGen}, +using the @code{agtexi-cmd} template and the option descriptions for the @code{xml2ag} program. +This software is released under the GNU General Public License, version 3 or later. + +@menu +* xml2ag usage:: xml2ag help/usage (@option{--help}) +* xml2ag the-xml2ag-option:: the-xml2ag-option options +* xml2ag autogen-options:: autogen-options options +* xml2ag exit status:: exit status +@end menu + +@node xml2ag usage +@subsection xml2ag help/usage (@option{--help}) +@cindex xml2ag help + +This is the automatically generated usage text for xml2ag. + +The text printed is the same whether selected with the @code{help} option +(@option{--help}) or the @code{more-help} option (@option{--more-help}). @code{more-help} will print +the usage text by passing it through a pager program. +@code{more-help} is disabled on platforms without a working +@code{fork(2)} function. The @code{PAGER} environment variable is +used to select the program, defaulting to @file{more}. Both will exit +with a status code of 0. + +@exampleindent 0 +@example +xml2ag (GNU AutoGen) - XML to AutoGen Definiton Converter - Ver. 5.18.16 +Usage: xml2ag [ - [] | --[@{=| @}] ]... [ ] + +All other options are derived from autogen: + + Flg Arg Option-Name Description + -O Str output Output file in lieu of AutoGen processing + +All other options: + + Flg Arg Option-Name Description + -L Str templ-dirs Search for templates in DIR + - may appear multiple times + -T Str override-tpl Use TPL-FILE for the template + Str definitions Read definitions from FILE + Str shell name or path name of shell to use + -m no no-fmemopen Do not use in-mem streams + Str equate characters considered equivalent + -b Str base-name Specify NAME as the base name for output + no source-time set mod times to latest source + no writable Allow output files to be writable + - disabled as '--not-writable' + Num loop-limit Limit on increment loops + - is scalable with a suffix: k/K/m/M/g/G/t/T + - it must lie in one of the ranges: + -1 exactly, or + 1 to 16777216 + -t Num timeout Limit server shell operations to SECONDS + - it must be in the range: + 0 to 3600 + KWd trace tracing level of detail + Str trace-out tracing output file or filter + no show-defs Show the definition tree + no used-defines Show the definitions used + -C no core Leave a core dump on a failure exit + -s Str skip-suffix Skip the file with this SUFFIX + - prohibits the option 'select-suffix' + - may appear multiple times + -o Str select-suffix specify this output suffix + - may appear multiple times + -D Str define name to add to definition list + - may appear multiple times + -U Str undefine definition list removal pattern + - an alternate for 'define' + -M opt make-dep emit make dependency file + - may appear multiple times + +Version, usage and configuration options: + + Flg Arg Option-Name Description + -v opt version output version information and exit + -? no help display extended usage information and exit + -! no more-help extended usage information passed thru pager + +Options are specified by doubled hyphens and their name or by a single +hyphen and the flag character. +This program will convert any arbitrary XML file into equivalent AutoGen +definitions, and invoke AutoGen. + +The valid "trace" option keywords are: + nothing debug-message server-shell templates block-macros + expressions everything + or an integer from 0 through 6 +The template will be derived from either: * the ``--override-tpl'' command +line option * a top level XML attribute named, "template" + +The ``base-name'' for the output will similarly be either: * the +``--base-name'' command line option * the base name of the .xml file + +Please send bug reports to: +@end example +@exampleindent 4 + +@node xml2ag the-xml2ag-option +@subsection the-xml2ag-option options +All other options are derived from autogen. +@subsubheading output option (-O). +@anchor{xml2ag output} +@cindex xml2ag-output + +This is the ``output file in lieu of autogen processing'' option. +This option takes a string argument @file{file}. +By default, the output is handed to an AutoGen for processing. +However, you may save the definitions to a file instead. +@node xml2ag autogen-options +@subsection autogen-options options +All other options. +These options are @i{mostly} just passed throug to @code{autogen}. +The one exception is @code{--override-tpl} which replaces the +default template in the output definitions. It does not get passed +through on the command line. +@subsubheading templ-dirs option (-L). +@anchor{xml2ag templ-dirs} +@cindex xml2ag-templ-dirs + +This is the ``search for templates in @file{dir}'' option. +This option takes a string argument @file{DIR}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +may appear an unlimited number of times. +@end itemize + +Pass-through AutoGen argument +@subsubheading override-tpl option (-T). +@anchor{xml2ag override-tpl} +@cindex xml2ag-override-tpl + +This is the ``use @file{tpl-file} for the template'' option. +This option takes a string argument @file{TPL-FILE}. +Pass-through AutoGen argument +@subsubheading definitions option. +@anchor{xml2ag definitions} +@cindex xml2ag-definitions + +This is the ``read definitions from @file{file}'' option. +This option takes a string argument @file{FILE}. +Pass-through AutoGen argument +@subsubheading shell option. +@anchor{xml2ag shell} +@cindex xml2ag-shell + +This is the ``name or path name of shell to use'' option. +This option takes a string argument @file{shell}. +Pass-through AutoGen argument +@subsubheading no-fmemopen option (-m). +@anchor{xml2ag no-fmemopen} +@cindex xml2ag-no-fmemopen + +This is the ``do not use in-mem streams'' option. +Pass-through AutoGen argument +@subsubheading equate option. +@anchor{xml2ag equate} +@cindex xml2ag-equate + +This is the ``characters considered equivalent'' option. +This option takes a string argument @file{char-list}. +Pass-through AutoGen argument +@subsubheading base-name option (-b). +@anchor{xml2ag base-name} +@cindex xml2ag-base-name + +This is the ``specify @code{name} as the base name for output'' option. +This option takes a string argument @file{NAME}. +Pass-through AutoGen argument +@subsubheading source-time option. +@anchor{xml2ag source-time} +@cindex xml2ag-source-time + +This is the ``set mod times to latest source'' option. +Pass-through AutoGen argument +@subsubheading writable option. +@anchor{xml2ag writable} +@cindex xml2ag-writable + +This is the ``allow output files to be writable'' option. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +can be disabled with --not-writable. +@end itemize + +Pass-through AutoGen argument +@subsubheading loop-limit option. +@anchor{xml2ag loop-limit} +@cindex xml2ag-loop-limit + +This is the ``limit on increment loops'' option. +This option takes a number argument @file{lim}. +Pass-through AutoGen argument +@subsubheading timeout option (-t). +@anchor{xml2ag timeout} +@cindex xml2ag-timeout + +This is the ``limit server shell operations to @code{seconds}'' option. +This option takes a number argument @file{SECONDS}. +Pass-through AutoGen argument +@subsubheading trace option. +@anchor{xml2ag trace} +@cindex xml2ag-trace + +This is the ``tracing level of detail'' option. +This option takes a keyword argument @file{level}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +This option takes a keyword as its argument. +The argument sets an enumeration value that can be tested by comparing the option value macro (OPT_VALUE_TRACE). +The available keywords are: +@example + nothing debug-message server-shell + templates block-macros expressions + everything +@end example + +or their numeric equivalent. +@end itemize + +Pass-through AutoGen argument +@subsubheading trace-out option. +@anchor{xml2ag trace-out} +@cindex xml2ag-trace-out + +This is the ``tracing output file or filter'' option. +This option takes a string argument @file{file}. +Pass-through AutoGen argument +@subsubheading show-defs option. +@anchor{xml2ag show-defs} +@cindex xml2ag-show-defs + +This is the ``show the definition tree'' option. +Pass-through AutoGen argument +@subsubheading used-defines option. +@anchor{xml2ag used-defines} +@cindex xml2ag-used-defines + +This is the ``show the definitions used'' option. +Pass-through AutoGen argument +@subsubheading core option (-C). +@anchor{xml2ag core} +@cindex xml2ag-core + +This is the ``leave a core dump on a failure exit'' option. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +must be compiled in by defining @code{HAVE_SYS_RESOURCE_H} during the compilation. +@end itemize + +Many systems default to a zero sized core limit. If the system +has the sys/resource.h header and if this option is supplied, +then in the failure exit path, autogen will attempt to set the +soft core limit to whatever the hard core limit is. If that +does not work, then an administrator must raise the hard core +size limit. +@subsubheading skip-suffix option (-s). +@anchor{xml2ag skip-suffix} +@cindex xml2ag-skip-suffix + +This is the ``skip the file with this @file{suffix}'' option. +This option takes a string argument @file{SUFFIX}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +may appear an unlimited number of times. +@item +must not appear in combination with any of the following options: +select-suffix. +@end itemize + +Pass-through AutoGen argument +@subsubheading select-suffix option (-o). +@anchor{xml2ag select-suffix} +@cindex xml2ag-select-suffix + +This is the ``specify this output suffix'' option. +This option takes a string argument @file{SUFFIX}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +may appear an unlimited number of times. +@end itemize + +Pass-through AutoGen argument +@subsubheading define option (-D). +@anchor{xml2ag define} +@cindex xml2ag-define + +This is the ``name to add to definition list'' option. +This option takes a string argument @file{value}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +may appear an unlimited number of times. +@end itemize + +Pass-through AutoGen argument +@subsubheading undefine option (-U). +@anchor{xml2ag undefine} +@cindex xml2ag-undefine + +This is the ``definition list removal pattern'' option. +This option takes a string argument @file{name-pat}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +may appear an unlimited number of times. +@end itemize + +Pass-through AutoGen argument +@subsubheading make-dep option (-M). +@anchor{xml2ag make-dep} +@cindex xml2ag-make-dep + +This is the ``emit make dependency file'' option. +This option takes an optional string argument @file{type}. + +@noindent +This option has some usage constraints. It: +@itemize @bullet +@item +may appear an unlimited number of times. +@end itemize + +Pass-through AutoGen argument +@node xml2ag exit status +@subsection xml2ag exit status + +One of the following exit values will be returned: +@table @samp +@item 0 (EXIT_SUCCESS) +Successful program execution. +@item 1 (EXIT_FAILURE) +The operation failed or the command syntax was not valid. +@end table diff --git a/doc/libopts.texi b/doc/libopts.texi new file mode 100644 index 0000000..ff3a741 --- /dev/null +++ b/doc/libopts.texi @@ -0,0 +1,927 @@ +@node libopts procedures +@subsection libopts External Procedures + +These are the routines that libopts users may call directly from their +code. There are several other routines that can be called by code +generated by the libopts option templates, but they are not to be +called from any other user code. The @file{options.h} header is +fairly clear about this, too. + +@menu +* libopts-ao_string_tokenize:: ao_string_tokenize +* libopts-configFileLoad:: configFileLoad +* libopts-optionFileLoad:: optionFileLoad +* libopts-optionFindNextValue:: optionFindNextValue +* libopts-optionFindValue:: optionFindValue +* libopts-optionFree:: optionFree +* libopts-optionGetValue:: optionGetValue +* libopts-optionLoadLine:: optionLoadLine +* libopts-optionMemberList:: optionMemberList +* libopts-optionNextValue:: optionNextValue +* libopts-optionOnlyUsage:: optionOnlyUsage +* libopts-optionPrintVersion:: optionPrintVersion +* libopts-optionPrintVersionAndReturn:: optionPrintVersionAndReturn +* libopts-optionProcess:: optionProcess +* libopts-optionRestore:: optionRestore +* libopts-optionSaveFile:: optionSaveFile +* libopts-optionSaveState:: optionSaveState +* libopts-optionUnloadNested:: optionUnloadNested +* libopts-optionVersion:: optionVersion +* libopts-strequate:: strequate +* libopts-streqvcmp:: streqvcmp +* libopts-streqvmap:: streqvmap +* libopts-strneqvcmp:: strneqvcmp +* libopts-strtransform:: strtransform +@end menu + +This subsection was automatically generated by AutoGen +using extracted information and the aginfo3.tpl template. + +@node libopts-ao_string_tokenize +@subsubsection ao_string_tokenize +@findex ao_string_tokenize + +tokenize an input string + +@noindent +Usage: +@example +token_list_t * res = ao_string_tokenize( string ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab string @tab @code{char const *} +@tab string to be tokenized +@item @tab returns @tab token_list_t * +@tab pointer to a structure that lists each token +@end multitable + +This function will convert one input string into a list of strings. +The list of strings is derived by separating the input based on +white space separation. However, if the input contains either single +or double quote characters, then the text after that character up to +a matching quote will become the string in the list. + +The returned pointer should be deallocated with @code{free(3C)} when +are done using the data. The data are placed in a single block of +allocated memory. Do not deallocate individual token/strings. + +The structure pointed to will contain at least these two fields: +@table @samp +@item tkn_ct +The number of tokens found in the input string. +@item tok_list +An array of @code{tkn_ct + 1} pointers to substring tokens, with +the last pointer set to NULL. +@end table + +There are two types of quoted strings: single quoted (@code{'}) and +double quoted (@code{"}). Singly quoted strings are fairly raw in that +escape characters (@code{\\}) are simply another character, except when +preceding the following characters: +@example +@code{\\} double backslashes reduce to one +@code{'} incorporates the single quote into the string +@code{\n} suppresses both the backslash and newline character +@end example + +Double quote strings are formed according to the rules of string +constants in ANSI-C programs. + +NULL is returned and @code{errno} will be set to indicate the problem: +@itemize @bullet +@item +@code{EINVAL} - There was an unterminated quoted string. +@item +@code{ENOENT} - The input string was empty. +@item +@code{ENOMEM} - There is not enough memory. +@end itemize + + +@node libopts-configFileLoad +@subsubsection configFileLoad +@findex configFileLoad + +parse a configuration file + +@noindent +Usage: +@example +const tOptionValue * res = configFileLoad( fname ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab fname @tab @code{char const *} +@tab the file to load +@item @tab returns @tab const tOptionValue * +@tab An allocated, compound value structure +@end multitable + +This routine will load a named configuration file and parse the +text as a hierarchically valued option. The option descriptor +created from an option definition file is not used via this interface. +The returned value is "named" with the input file name and is of +type "@code{OPARG_TYPE_HIERARCHY}". It may be used in calls to +@code{optionGetValue()}, @code{optionNextValue()} and +@code{optionUnloadNested()}. + +If the file cannot be loaded or processed, @code{NULL} is returned and +@var{errno} is set. It may be set by a call to either @code{open(2)} +@code{mmap(2)} or other file system calls, or it may be: +@itemize @bullet +@item +@code{ENOENT} - the file was not found. +@item +@code{ENOMSG} - the file was empty. +@item +@code{EINVAL} - the file contents are invalid -- not properly formed. +@item +@code{ENOMEM} - not enough memory to allocate the needed structures. +@end itemize + + +@node libopts-optionFileLoad +@subsubsection optionFileLoad +@findex optionFileLoad + +Load the locatable config files, in order + +@noindent +Usage: +@example +int res = optionFileLoad( opts, prog ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab opts @tab @code{tOptions *} +@tab program options descriptor + +@item @tab prog @tab @code{char const *} +@tab program name +@item @tab returns @tab int +@tab 0 -> SUCCESS, -1 -> FAILURE +@end multitable + +This function looks in all the specified directories for a configuration +file ("rc" file or "ini" file) and processes any found twice. The first +time through, they are processed in reverse order (last file first). At +that time, only "immediate action" configurables are processed. For +example, if the last named file specifies not processing any more +configuration files, then no more configuration files will be processed. +Such an option in the @strong{first} named directory will have no effect. + +Once the immediate action configurables have been handled, then the +directories are handled in normal, forward order. In that way, later +config files can override the settings of earlier config files. + +See the AutoOpts documentation for a thorough discussion of the +config file format. + +Configuration files not found or not decipherable are simply ignored. + +Returns the value, "-1" if the program options descriptor +is out of date or indecipherable. Otherwise, the value "0" will +always be returned. + + +@node libopts-optionFindNextValue +@subsubsection optionFindNextValue +@findex optionFindNextValue + +find a hierarcicaly valued option instance + +@noindent +Usage: +@example +const tOptionValue * res = optionFindNextValue( odesc, pPrevVal, name, value ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab odesc @tab @code{const tOptDesc *} +@tab an option with a nested arg type + +@item @tab pPrevVal @tab @code{const tOptionValue *} +@tab the last entry + +@item @tab name @tab @code{char const *} +@tab name of value to find + +@item @tab value @tab @code{char const *} +@tab the matching value +@item @tab returns @tab const tOptionValue * +@tab a compound value structure +@end multitable + +This routine will find the next entry in a nested value option or +configurable. It will search through the list and return the next entry +that matches the criteria. + +The returned result is NULL and errno is set: +@itemize @bullet +@item +@code{EINVAL} - the @code{pOptValue} does not point to a valid +hierarchical option value. +@item +@code{ENOENT} - no entry matched the given name. +@end itemize + + +@node libopts-optionFindValue +@subsubsection optionFindValue +@findex optionFindValue + +find a hierarcicaly valued option instance + +@noindent +Usage: +@example +const tOptionValue * res = optionFindValue( odesc, name, val ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab odesc @tab @code{const tOptDesc *} +@tab an option with a nested arg type + +@item @tab name @tab @code{char const *} +@tab name of value to find + +@item @tab val @tab @code{char const *} +@tab the matching value +@item @tab returns @tab const tOptionValue * +@tab a compound value structure +@end multitable + +This routine will find an entry in a nested value option or configurable. +It will search through the list and return a matching entry. + +The returned result is NULL and errno is set: +@itemize @bullet +@item +@code{EINVAL} - the @code{pOptValue} does not point to a valid +hierarchical option value. +@item +@code{ENOENT} - no entry matched the given name. +@end itemize + + +@node libopts-optionFree +@subsubsection optionFree +@findex optionFree + +free allocated option processing memory + +@noindent +Usage: +@example +optionFree( pOpts ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab pOpts @tab @code{tOptions *} +@tab program options descriptor +@end multitable + +AutoOpts sometimes allocates memory and puts pointers to it in the +option state structures. This routine deallocates all such memory. + +As long as memory has not been corrupted, +this routine is always successful. + + +@node libopts-optionGetValue +@subsubsection optionGetValue +@findex optionGetValue + +get a specific value from a hierarcical list + +@noindent +Usage: +@example +const tOptionValue * res = optionGetValue( pOptValue, valueName ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab pOptValue @tab @code{const tOptionValue *} +@tab a hierarchcal value + +@item @tab valueName @tab @code{char const *} +@tab name of value to get +@item @tab returns @tab const tOptionValue * +@tab a compound value structure +@end multitable + +This routine will find an entry in a nested value option or configurable. +If "valueName" is NULL, then the first entry is returned. Otherwise, +the first entry with a name that exactly matches the argument will be +returned. If there is no matching value, NULL is returned and errno is +set to ENOENT. If the provided option value is not a hierarchical value, +NULL is also returned and errno is set to EINVAL. + +The returned result is NULL and errno is set: +@itemize @bullet +@item +@code{EINVAL} - the @code{pOptValue} does not point to a valid +hierarchical option value. +@item +@code{ENOENT} - no entry matched the given name. +@end itemize + + +@node libopts-optionLoadLine +@subsubsection optionLoadLine +@findex optionLoadLine + +process a string for an option name and value + +@noindent +Usage: +@example +optionLoadLine( opts, line ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab opts @tab @code{tOptions *} +@tab program options descriptor + +@item @tab line @tab @code{char const *} +@tab NUL-terminated text +@end multitable + +This is a client program callable routine for setting options from, for +example, the contents of a file that they read in. Only one option may +appear in the text. It will be treated as a normal (non-preset) option. + +When passed a pointer to the option struct and a string, it will find +the option named by the first token on the string and set the option +argument to the remainder of the string. The caller must NUL terminate +the string. The caller need not skip over any introductory hyphens. +Any embedded new lines will be included in the option +argument. If the input looks like one or more quoted strings, then the +input will be "cooked". The "cooking" is identical to the string +formation used in AutoGen definition files (@pxref{basic expression}), +except that you may not use backquotes. + +Invalid options are silently ignored. Invalid option arguments +will cause a warning to print, but the function should return. + + +@node libopts-optionMemberList +@subsubsection optionMemberList +@findex optionMemberList + +Get the list of members of a bit mask set + +@noindent +Usage: +@example +char * res = optionMemberList( od ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab od @tab @code{tOptDesc *} +@tab the set membership option description +@item @tab returns @tab char * +@tab the names of the set bits +@end multitable + +This converts the OPT_VALUE_name mask value to a allocated string. +It is the caller's responsibility to free the string. + + +@node libopts-optionNextValue +@subsubsection optionNextValue +@findex optionNextValue + +get the next value from a hierarchical list + +@noindent +Usage: +@example +const tOptionValue * res = optionNextValue( pOptValue, pOldValue ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab pOptValue @tab @code{const tOptionValue *} +@tab a hierarchcal list value + +@item @tab pOldValue @tab @code{const tOptionValue *} +@tab a value from this list +@item @tab returns @tab const tOptionValue * +@tab a compound value structure +@end multitable + +This routine will return the next entry after the entry passed in. At the +end of the list, NULL will be returned. If the entry is not found on the +list, NULL will be returned and "@var{errno}" will be set to EINVAL. +The "@var{pOldValue}" must have been gotten from a prior call to this +routine or to "@code{opitonGetValue()}". + +The returned result is NULL and errno is set: +@itemize @bullet +@item +@code{EINVAL} - the @code{pOptValue} does not point to a valid +hierarchical option value or @code{pOldValue} does not point to a +member of that option value. +@item +@code{ENOENT} - the supplied @code{pOldValue} pointed to the last entry. +@end itemize + + +@node libopts-optionOnlyUsage +@subsubsection optionOnlyUsage +@findex optionOnlyUsage + +Print usage text for just the options + +@noindent +Usage: +@example +optionOnlyUsage( pOpts, ex_code ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab pOpts @tab @code{tOptions *} +@tab program options descriptor + +@item @tab ex_code @tab @code{int} +@tab exit code for calling exit(3) +@end multitable + +This routine will print only the usage for each option. +This function may be used when the emitted usage must incorporate +information not available to AutoOpts. + + +@node libopts-optionPrintVersion +@subsubsection optionPrintVersion +@findex optionPrintVersion + +Print the program version + +@noindent +Usage: +@example +optionPrintVersion( opts, od ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab opts @tab @code{tOptions *} +@tab program options descriptor + +@item @tab od @tab @code{tOptDesc *} +@tab the descriptor for this arg +@end multitable + +This routine will print the version to stdout. + + +@node libopts-optionPrintVersionAndReturn +@subsubsection optionPrintVersionAndReturn +@findex optionPrintVersionAndReturn + +Print the program version + +@noindent +Usage: +@example +optionPrintVersionAndReturn( opts, od ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab opts @tab @code{tOptions *} +@tab program options descriptor + +@item @tab od @tab @code{tOptDesc *} +@tab the descriptor for this arg +@end multitable + +This routine will print the version to stdout and return +instead of exiting. Please see the source for the +@code{print_ver} funtion for details on selecting how +verbose to be after this function returns. + + +@node libopts-optionProcess +@subsubsection optionProcess +@findex optionProcess + +this is the main option processing routine + +@noindent +Usage: +@example +int res = optionProcess( opts, a_ct, a_v ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab opts @tab @code{tOptions *} +@tab program options descriptor + +@item @tab a_ct @tab @code{int} +@tab program arg count + +@item @tab a_v @tab @code{char **} +@tab program arg vector +@item @tab returns @tab int +@tab the count of the arguments processed +@end multitable + +This is the main entry point for processing options. It is intended +that this procedure be called once at the beginning of the execution of +a program. Depending on options selected earlier, it is sometimes +necessary to stop and restart option processing, or to select completely +different sets of options. This can be done easily, but you generally +do not want to do this. + +The number of arguments processed always includes the program name. +If one of the arguments is "--", then it is counted and the processing +stops. If an error was encountered and errors are to be tolerated, then +the returned value is the index of the argument causing the error. +A hyphen by itself ("-") will also cause processing to stop and will +@emph{not} be counted among the processed arguments. A hyphen by itself +is treated as an operand. Encountering an operand stops option +processing. + +Errors will cause diagnostics to be printed. @code{exit(3)} may +or may not be called. It depends upon whether or not the options +were generated with the "allow-errors" attribute, or if the +ERRSKIP_OPTERR or ERRSTOP_OPTERR macros were invoked. + + +@node libopts-optionRestore +@subsubsection optionRestore +@findex optionRestore + +restore option state from memory copy + +@noindent +Usage: +@example +optionRestore( pOpts ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab pOpts @tab @code{tOptions *} +@tab program options descriptor +@end multitable + +Copy back the option state from saved memory. +The allocated memory is left intact, so this routine can be +called repeatedly without having to call optionSaveState again. +If you are restoring a state that was saved before the first call +to optionProcess(3AO), then you may change the contents of the +argc/argv parameters to optionProcess. + +If you have not called @code{optionSaveState} before, a diagnostic is +printed to @code{stderr} and exit is called. + + +@node libopts-optionSaveFile +@subsubsection optionSaveFile +@findex optionSaveFile + +saves the option state to a file + +@noindent +Usage: +@example +optionSaveFile( opts ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab opts @tab @code{tOptions *} +@tab program options descriptor +@end multitable + +This routine will save the state of option processing to a file. The name +of that file can be specified with the argument to the @code{--save-opts} +option, or by appending the @code{rcfile} attribute to the last +@code{homerc} attribute. If no @code{rcfile} attribute was specified, it +will default to @code{.@i{programname}rc}. If you wish to specify another +file, you should invoke the @code{SET_OPT_SAVE_OPTS(@i{filename})} macro. + +The recommend usage is as follows: +@example +optionProcess(&progOptions, argc, argv); +if (i_want_a_non_standard_place_for_this) +SET_OPT_SAVE_OPTS("myfilename"); +optionSaveFile(&progOptions); +@end example + +If no @code{homerc} file was specified, this routine will silently return +and do nothing. If the output file cannot be created or updated, a message +will be printed to @code{stderr} and the routine will return. + + +@node libopts-optionSaveState +@subsubsection optionSaveState +@findex optionSaveState + +saves the option state to memory + +@noindent +Usage: +@example +optionSaveState( pOpts ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab pOpts @tab @code{tOptions *} +@tab program options descriptor +@end multitable + +This routine will allocate enough memory to save the current option +processing state. If this routine has been called before, that memory +will be reused. You may only save one copy of the option state. This +routine may be called before optionProcess(3AO). If you do call it +before the first call to optionProcess, then you may also change the +contents of argc/argv after you call optionRestore(3AO) + +In fact, more strongly put: it is safest to only use this function +before having processed any options. In particular, the saving and +restoring of stacked string arguments and hierarchical values is +disabled. The values are not saved. + +If it fails to allocate the memory, +it will print a message to stderr and exit. +Otherwise, it will always succeed. + + +@node libopts-optionUnloadNested +@subsubsection optionUnloadNested +@findex optionUnloadNested + +Deallocate the memory for a nested value + +@noindent +Usage: +@example +optionUnloadNested( pOptVal ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab pOptVal @tab @code{tOptionValue const *} +@tab the hierarchical value +@end multitable + +A nested value needs to be deallocated. The pointer passed in should +have been gotten from a call to @code{configFileLoad()} (See +@pxref{libopts-configFileLoad}). + + +@node libopts-optionVersion +@subsubsection optionVersion +@findex optionVersion + +return the compiled AutoOpts version number + +@noindent +Usage: +@example +char const * res = optionVersion(); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab returns @tab char const * +@tab the version string in constant memory +@end multitable + +Returns the full version string compiled into the library. +The returned string cannot be modified. + + +@node libopts-strequate +@subsubsection strequate +@findex strequate + +map a list of characters to the same value + +@noindent +Usage: +@example +strequate( ch_list ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab ch_list @tab @code{char const *} +@tab characters to equivalence +@end multitable + +Each character in the input string get mapped to the first character +in the string. +This function name is mapped to option_strequate so as to not conflict +with the POSIX name space. + +none. + + +@node libopts-streqvcmp +@subsubsection streqvcmp +@findex streqvcmp + +compare two strings with an equivalence mapping + +@noindent +Usage: +@example +int res = streqvcmp( str1, str2 ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab str1 @tab @code{char const *} +@tab first string + +@item @tab str2 @tab @code{char const *} +@tab second string +@item @tab returns @tab int +@tab the difference between two differing characters +@end multitable + +Using a character mapping, two strings are compared for "equivalence". +Each input character is mapped to a comparison character and the +mapped-to characters are compared for the two NUL terminated input strings. +This function name is mapped to option_streqvcmp so as to not conflict +with the POSIX name space. + +none checked. Caller responsible for seg faults. + + +@node libopts-streqvmap +@subsubsection streqvmap +@findex streqvmap + +Set the character mappings for the streqv functions + +@noindent +Usage: +@example +streqvmap( from, to, ct ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab from @tab @code{char} +@tab Input character + +@item @tab to @tab @code{char} +@tab Mapped-to character + +@item @tab ct @tab @code{int} +@tab compare length +@end multitable + +Set the character mapping. If the count (@code{ct}) is set to zero, then +the map is cleared by setting all entries in the map to their index +value. Otherwise, the "@code{From}" character is mapped to the "@code{To}" +character. If @code{ct} is greater than 1, then @code{From} and @code{To} +are incremented and the process repeated until @code{ct} entries have been +set. For example, +@example +streqvmap('a', 'A', 26); +@end example +@noindent +will alter the mapping so that all English lower case letters +will map to upper case. + +This function name is mapped to option_streqvmap so as to not conflict +with the POSIX name space. + +none. + + +@node libopts-strneqvcmp +@subsubsection strneqvcmp +@findex strneqvcmp + +compare two strings with an equivalence mapping + +@noindent +Usage: +@example +int res = strneqvcmp( str1, str2, ct ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab str1 @tab @code{char const *} +@tab first string + +@item @tab str2 @tab @code{char const *} +@tab second string + +@item @tab ct @tab @code{int} +@tab compare length +@item @tab returns @tab int +@tab the difference between two differing characters +@end multitable + +Using a character mapping, two strings are compared for "equivalence". +Each input character is mapped to a comparison character and the +mapped-to characters are compared for the two NUL terminated input strings. +The comparison is limited to @code{ct} bytes. +This function name is mapped to option_strneqvcmp so as to not conflict +with the POSIX name space. + +none checked. Caller responsible for seg faults. + + +@node libopts-strtransform +@subsubsection strtransform +@findex strtransform + +convert a string into its mapped-to value + +@noindent +Usage: +@example +strtransform( dest, src ); +@end example +@noindent +Where the arguments are: +@multitable @columnfractions .05 .15 .20 .55 +@item @tab Name @tab Type @tab Description +@item @tab ----- @tab ----- @tab ------------- +@item @tab dest @tab @code{char *} +@tab output string + +@item @tab src @tab @code{char const *} +@tab input string +@end multitable + +Each character in the input string is mapped and the mapped-to +character is put into the output. +This function name is mapped to option_strtransform so as to not conflict +with the POSIX name space. + +The source and destination may be the same. + +none. + diff --git a/doc/mk-agen-texi.sh b/doc/mk-agen-texi.sh new file mode 100755 index 0000000..764349a --- /dev/null +++ b/doc/mk-agen-texi.sh @@ -0,0 +1,315 @@ +#! /bin/sh + +## This file is part of AutoGen. +## +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . + +PS4='+mtx=${FUNCNAME:-=}-$LINENO> ' +exec 2> ${0%.sh}.log + +set -x + +typeset -r prog=$(basename "$0" .sh) +typeset -r progdir=$(\cd $(dirname "$0") && pwd -P) +typeset -r program=${progdir}/$(basename "$0") +typeset -r progpid=$$ + +builddir=`pwd` +. ${top_builddir:-..}/config/shdefs + +die() +{ + exec 1> ${TMPDIR}/err-report.txt 2>&1 + echo "mk-agen-texi FAILED: $*" + echo + cat ${LOG_FILE} + exec 2>&8 1>&2 8>&- + cat ${TMPDIR}/err-report.txt + trap : EXIT + echo leaving ${TMPDIR} in place + kill -TERM ${progpid} + exit 1 +} + +set_config_values() +{ + TMPDIR=`pwd`/ag-texi-$$.d + rm -rf ag-texi-*.d + mkdir ${TMPDIR} || die "cannot make ${TMPDIR} directory" + export TMPDIR + + case "$-" in + *x* ) trap "echo 'saved tmp dir: ${TMPDIR}';chmod 777 ${TMPDIR}" EXIT + VERBOSE=true ;; + * ) trap "rm -rf ${TMPDIR}" EXIT + VERBOSE=false ;; + esac + + LOG_FILE=${TMPDIR}/texi.log + + exec 8>&2 2> ${LOG_FILE} + + nl=' +' ht=' ' + . ${top_builddir}/config/shdefs + : ${MAKE=`which make`} + : ${srcdir=`pwd`} + srcdir=`cd ${srcdir} >/dev/null ; pwd` + INCLUDES="${DEFS} "` + + for d in ${top_srcdir} ${top_builddir} \ + ${top_builddir}/autoopts ${top_srcdir}/autoopts + do + (\cd ${d} && pwd) 2>/dev/null + done | \ + sort -u | \ + sed s/^/-I/ ` + + CFLAGS="${INCLUDES} "`echo ${CFLAGS} | \ + ${SED:-sed} -e "s/-Werror[^ ${ht}]*//g;s/-Wextra//g"` + + LIBS=-L` + test -d ${top_builddir}/autoopts/.libs \ + && echo ${top_builddir}/autoopts/.libs \ + || echo ${top_builddir}/autoopts + `" $LIBS" + + export CC CFLAGS LIBS MAKE LOG_FILE TMPDIR +} + +setup_exports() +{ + # Now auto-export variables: + # + set -a + + PATH=${top_builddir}/columns:${PATH} + timer=`expr ${AG_TIMEOUT} '*' 5` + d=`find ${top_builddir}/autoopts -type f -name libopts.a -print` + test -f "$d" || die "Cannot locate libopts.a" + LIBS="$d ${LIBS}" + + eval `${EGREP} '^AG_[A-Z_]*' ${top_srcdir}/VERSION` + + AGsrc=${top_srcdir}/agen5 + OPTIONS_DEF=${AGsrc}/opts.def + GETDEF_SRC=`${FGREP} -l '/*=' ${AGsrc}/*.[ch] ${AGsrc}/*.scm` + + for d in "${top_builddir}" "${top_srcdir}" + do test -f "$d/agen5/invoke-autogen.texi" || continue + AGEN_TEXI=${d}/agen5/invoke-autogen.texi + break + done + DOC_TEXT=${top_srcdir}/doc/autogen-texi.txt + + ADDON_TEXI=" + ${top_srcdir}/doc/bitmaps.texi + ${top_builddir}/columns/invoke-columns.texi + ${top_builddir}/getdefs/invoke-getdefs.texi + ${top_builddir}/xml2ag/invoke-xml2ag.texi + ${top_srcdir}/doc/snprintfv.texi" + + DOC_INCLUDES=" + ${AGsrc}/defParse-fsm.c + ${AGsrc}/opts.h + ${top_builddir}/autoopts/libopts.texi + ${top_srcdir}/doc/autogen-intro.texi + ${AGEN_TEXI}" + + DOC_TEMPLATE=${top_builddir}/doc/auto_gen.tpl + + DOC_DEPENDS=` + echo ${DOC_TEMPLATE} ${OPTIONS_DEF} ${ADDON_MENU} ${ADDON_TEXI} \ + ${DOC_INCLUDES} ${GETDEF_SRC} ${DOC_TEXT}` + + set +a +} + +# We have our executables and texi's. Collect the definitions: +# +run_getdefs() +{ + gd_cfg=${TMPDIR}/getdefs.cfg + exec 3> ${gd_cfg} + cat >&3 <<- EOCat + output ${TMPDIR}/${GEN_BASE}.def + copy ${OPTIONS_DEF} + srcfile + linenum + template auto_gen.tpl + assign ag-texi = invoke-autogen.texi + subblock exparg = arg_name,arg_desc,arg_optional,arg_list + EOCat + + tf=invoke-autogen.texi + test -f ${tf} || ln -s ${AGEN_TEXI} ${tf} + + for f in ${ADDON_TEXI} + do + tf=`basename ${f}` + case "$tf" in + invoke-* ) : ;; + * ) tf=invoke-$tf ;; + esac + test -f ${tf} || ln -s ${f} ${tf} + echo "assign addon-texi = ${tf}" + done >&3 + + for f in ${GETDEF_SRC} + do + echo "input " ${f} + done >&3 + exec 3>&- + echo + ${GDexe} load-opt=${gd_cfg} >&8 + ${GDexe} load-opt=${gd_cfg} || die cannot run ${GDexe} +} + +sanity_check() +{ + # Make sure the executables are there + # + test -x ${AGexe} || (cd `dirname ${AGexe}` ; ${MAKE}) || exit 0 + test -x ${GDexe} || (cd `dirname ${GDexe}` ; ${MAKE}) || exit 0 + test -x ${CLexe} || (cd `dirname ${CLexe}` ; ${MAKE}) || exit 0 + PATH="`dirname ${AGexe}`:`dirname ${CLexe}`:$PATH" + + # See to it that the .texi files have been generated, too. + # + for f in ${ADDON_TEXI} ${AGEN_TEXI} \ + ${top_builddir}/autoopts/libopts.texi + do + test -f "${f}" || ( + cd `dirname "${f}"` + ${MAKE} `basename "${f}"` >&2 + test $? -ne 0 && die MAKE of ${f} failed. + ) + done + + # Make sure we have all our sources and generate the doc + # + for f in ${DOC_DEPENDS} + do test -f "${f}" || die cannot find doc file: ${f} + test -f `basename $f` || ln -s "${f}" . + done +} + +build_agdoc() { + # Validate everything: + # + set_config_values + setup_exports + sanity_check + run_getdefs + + { + sh -c set | sed '/^BASH/d' + } >&2 + { + cat <<- _EOF_ + timeout ${timer} + templ-dirs ${srcdir} + templ-dirs ${top_srcdir}/autoopts/tpl + base-name ${GEN_BASE} + make-dep F ${GEN_BASE}.dep + make-dep P + _EOF_ + ${VERBOSE} && { + echo 'trace every' + echo "trace-out >>${TMPDIR}/ag.log" + export VERBOSE + } + } > ${TMPDIR}/ag.ini + + opts="--load-opts=${TMPDIR}/ag.ini" + cmd=`echo ${AGexe} ${opts} ${TMPDIR}/${GEN_BASE}.def` + echo "${PS4:-+} " ${cmd} >&8 + + timeout ${timer}s ${cmd} || { + head -n999999 ${TMPDIR}/ag.ini ${TMPDIR}/*.log + die could not regenerate doc + } >&2 + + test -f ${GEN_BASE}.texi || die "MISSING: ${GEN_BASE}.texi" + + exec 2>&8 8>&- +} + +build_gnudocs() +{ + local sedcmd='/^@author @email/ { + s/.*{// + s/}.*// + s/@@*/@/g + p + q + }' + + case "X$-" in + *x* ) local dashx=-x ;; + * ) local dashx= ;; + esac + + title=`sed -n 's/^@title *//p' agdoc.texi` + email=--email' '`sed -n "$sedcmd" agdoc.texi` + opts="--texi2html ${email}" + PS4='+gd=${FUNCNAME:-=}-$LINENO> ' ${SHELL} ${dashx} \ + ${top_srcdir}/config/gendocs.sh $opts autogen "$title" +} + +mk_autogen_texi() { + tfile=autogen.texi + page_style=\ +'\internalpagesizes{46\baselineskip}{6in}{-.25in}{-.25in}{\bindingoffset}{36pt}%' + + cat > ${tfile}$$ <<- _EOF_ + \\input texinfo + @ignore + ${page_style} + @end ignore + @c %**start of header + @setfilename ${tfile%.texi}.info + @include ${GEN_BASE}.texi + _EOF_ + + if test -f ${tfile} && cmp -s ${tfile} ${tfile}$$ + then rm -f ${tfile}$$ + else mv -f ${tfile}$$ ${tfile} + fi +} + +PS4='+agt=${FUNCNAME:-=}-$LINENO> ' +set -x +GEN_BASE=agdoc +test "X$1" = X--force && { + rm -f agdoc.texi + shift +} +test -f agdoc.texi || build_agdoc +mk_autogen_texi + +case "$1" in +gnudocs | gnudoc ) build_gnudocs ;; +* ) +esac + +exit 0 + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: diff --git a/doc/snprintfv.texi b/doc/snprintfv.texi new file mode 100644 index 0000000..380641c --- /dev/null +++ b/doc/snprintfv.texi @@ -0,0 +1,74 @@ +@node snprintfv +@section Replacement for Stdio Formatting Library + + Using the `printf' formatting routines in a portable fashion has +always been a pain, and this package has been way more pain than anyone +ever imagined. Hopefully, with this release of snprintfv, the pain is +now over for all time. + + The issues with portable usage are these: + +@enumerate +@item +Argument number specifiers are often either not implemented or are +buggy. Even GNU libc, version 1 got it wrong. + +@item +ANSI/ISO "forgot" to provide a mechanism for computing argument +lists for vararg procedures. + +@item +The argument array version of printf (`printfv()') is not +generally available, does not work with the native printf, and +does not have a working argument number specifier in the format +specification. (Last I knew, anyway.) + +@item +You cannot fake varargs by calling `vprintf()' with an array of +arguments, because ANSI does not require such an implementation +and some vendors play funny tricks because they are allowed to. +@end enumerate + + These four issues made it impossible for AutoGen to ship without its +own implementation of the `printf' formatting routines. Since we were +forced to do this, we decided to make the formatting routines both +better and more complete :-). We addressed these issues and added the +following features to the common printf API: + +@enumerate 5 +@item +The formatted output can be written to + +@itemize @bullet +@item +a string allocated by the formatting function (`asprintf()'). +@item +a file descriptor instead of a file stream (`dprintf()'). +@item +a user specified stream (`stream_printf()'). +@end itemize + +@item +The formatting functions can be augmented with your own functions. +These functions are allowed to consume more than one character +from the format, but must commence with a unique character. For +example, + +@example +"%@{struct stat@}\n" +@end example + +might be used with '@{' registered to a procedure that would look +up "struct stat" in a symbol table and do appropriate things, +consuming the format string through the '@}' character. +@end enumerate + + Gary V. Vaughan was generous enough to supply this implementation. +Many thanks!! + + For further details, the reader is referred to the snprintfv +documentation. These functions are also available in the template +processing as@: `sprintf' (@pxref{SCM sprintf}), `printf' +(@pxref{SCM printf}), `fprintf' (@pxref{SCM fprintf}), and `shellf' +(@pxref{SCM shellf}). + diff --git a/getdefs/Makefile.am b/getdefs/Makefile.am new file mode 100644 index 0000000..4322223 --- /dev/null +++ b/getdefs/Makefile.am @@ -0,0 +1,102 @@ +## -*- Mode: Makefile -*- +## --------------------------------------------------------------------- +## Makefile.am -- process this file with automake to produce Makefile.in +## +## Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . +## --------------------------------------------------------------------- +TARG = getdefs + +bin_PROGRAMS = getdefs +getdefs_LDFLAGS = -no-install +gdsrcs = getdefs.h proto.h gdemit.c gdinit.c getdefs.c +getdefs_SOURCES = proto.h +BUILT_SOURCES = gd.c +nodist_getdefs_SOURCES = $(BUILT_SOURCES) + +SUBDIRS = test +EXTRA_DIST = opts.def $(gdsrcs) +AG_ENV = top_builddir="$(top_builddir)" top_srcdir="$(top_srcdir)" \ + VERBOSE="$(V)" +RUN_AG = $(AG_ENV) $(SHELL) "${top_srcdir}/build-aux/run-ag.sh" + +all : gen +gen : $(BUILT_SOURCES) $(DOCFILES) + +if AMDEP +DEPFL_OPTS = $(DEPDIR)/opts-dep.mk +DEPFL_TEXI = $(DEPDIR)/info-dep.mk +DEPFL_MAN = $(DEPDIR)/man-dep.mk + +$(DEPFL_OPTS) : + $(RUN_AG) "$@" +include $(DEPFL_OPTS) + +$(DEPFL_MAN) : + $(RUN_AG) "$@" +include $(DEPFL_MAN) + +$(DEPFL_INFO) : + $(RUN_AG) "$@" +include $(DEPFL_INFO) +else +DEPFL_OPTS = $@ +DEPFL_TEXI = $@ +DEPFL_MAN = $@ +endif + +AGARG_OPTS = -MF$(DEPFL_OPTS) -MT$@ -MP +AGARG_TEXI = -MF$(DEPFL_TEXI) -MT$@ -MP -Tagtexi-cmd +AGARG_MAN = -MF$(DEPFL_MAN) -MT$@ -MP -Tagman-cmd + +getdefs_LDADD = $(top_builddir)/autoopts/libopts.la +man_MANS = $(TARG).1 +TEXI_FILES = $(TARG).texi $(TARG).menu +DOCFILES = $(TEXI_FILES) $(man_MANS) +DISTCLEANFILES = $(DOCFILES) $(nodist_getdefs_SOURCES) *-stamp +AM_CPPFLAGS = @INCLIST@ +AM_CFLAGS = @WARN_CFLAGS@ + +gd.c : $(gdsrcs) + exec > $@ ; \ + echo '#undef PKGDATADIR' ; \ + echo '#define PKGDATADIR "$(pkgdatadir)"' ; \ + echo ; echo '#define DEFINING 1' ; \ + echo '#include "autoopts/project.h"' ; \ + for f in opts.c $(gdsrcs) ; \ + do echo "#include \"$$f\"" ; done + +$(getdefs_OBJECTS) opts.h opts.c : stamp-opts +stamp-opts : opts.def + $(RUN_AG) $(AGARG_OPTS) $(srcdir)/opts.def + +$(man_MANS) : stamp-man +stamp-man : $(TARG)$(EXEEXT) + $(RUN_AG) $(AGARG_MAN) $(srcdir)/opts.def + +$(TEXI_FILES) : stamp-doc +stamp-doc : $(TARG)$(EXEEXT) + $(RUN_AG) $(AGARG_TEXI) -DLEVEL=section $(srcdir)/opts.def + +.NOTPARALLEL: + +.PHONY : local-maintainer-clean stamp-man +local-maintainer-clean : clean-stamp-opts clean-stamp-doc clean-stamp-man + rm -f *~ + +# end of getdefs/Makefile.am diff --git a/getdefs/Makefile.in b/getdefs/Makefile.in new file mode 100644 index 0000000..f6423b4 --- /dev/null +++ b/getdefs/Makefile.in @@ -0,0 +1,976 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 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. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +bin_PROGRAMS = getdefs$(EXEEXT) +subdir = getdefs +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/ag_macros.m4 \ + $(top_srcdir)/config/asm-underscore.m4 \ + $(top_srcdir)/config/extensions.m4 \ + $(top_srcdir)/config/guile.m4 \ + $(top_srcdir)/config/host-cpu-c-abi.m4 \ + $(top_srcdir)/config/lib-ld.m4 \ + $(top_srcdir)/config/lib-link.m4 \ + $(top_srcdir)/config/lib-prefix.m4 \ + $(top_srcdir)/config/libopts.m4 \ + $(top_srcdir)/config/libtool.m4 \ + $(top_srcdir)/config/ltoptions.m4 \ + $(top_srcdir)/config/ltsugar.m4 \ + $(top_srcdir)/config/ltversion.m4 \ + $(top_srcdir)/config/lt~obsolete.m4 \ + $(top_srcdir)/config/onceonly.m4 $(top_srcdir)/config/pkg.m4 \ + $(top_srcdir)/config/snprintfv.m4 \ + $(top_srcdir)/config/stdnoreturn.m4 \ + $(top_srcdir)/config/unlocked-io.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" +PROGRAMS = $(bin_PROGRAMS) +am_getdefs_OBJECTS = +am__objects_1 = gd.$(OBJEXT) +nodist_getdefs_OBJECTS = $(am__objects_1) +getdefs_OBJECTS = $(am_getdefs_OBJECTS) $(nodist_getdefs_OBJECTS) +getdefs_DEPENDENCIES = $(top_builddir)/autoopts/libopts.la +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +getdefs_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(getdefs_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/config/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/gd.Po +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(getdefs_SOURCES) $(nodist_getdefs_SOURCES) +DIST_SOURCES = $(getdefs_SOURCES) +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +man1dir = $(mandir)/man1 +NROFF = nroff +MANS = $(man_MANS) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir distdir-am +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/config/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +AGEN5_TESTS = @AGEN5_TESTS@ +AG_LDFLAGS = @AG_LDFLAGS@ +AG_MAJOR_VERSION = @AG_MAJOR_VERSION@ +AG_MINOR_VERSION = @AG_MINOR_VERSION@ +AG_STATIC_AUTOGEN = @AG_STATIC_AUTOGEN@ +AG_TIMEOUT = @AG_TIMEOUT@ +AG_VERSION = @AG_VERSION@ +AG_XML2 = @AG_XML2@ +AGexe = @AGexe@ +AGnam = @AGnam@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AO_AGE = @AO_AGE@ +AO_CURRENT = @AO_CURRENT@ +AO_REVISION = @AO_REVISION@ +AO_TEMPLATE_VERSION = @AO_TEMPLATE_VERSION@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLexe = @CLexe@ +CLnam = @CLnam@ +CONFIG_SHELL = @CONFIG_SHELL@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBUG_ENABLED = @DEBUG_ENABLED@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +DYNAMIC_AG = @DYNAMIC_AG@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_STATIC = @ENABLE_STATIC@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GDexe = @GDexe@ +GDnam = @GDnam@ +GO_AGE = @GO_AGE@ +GO_CURRENT = @GO_CURRENT@ +GO_REVISION = @GO_REVISION@ +GREP = @GREP@ +GUILE_CFLAGS = @GUILE_CFLAGS@ +GUILE_EFFECTIVE_VERSION = @GUILE_EFFECTIVE_VERSION@ +GUILE_LDFLAGS = @GUILE_LDFLAGS@ +GUILE_LIBS = @GUILE_LIBS@ +GUILE_LTLIBS = @GUILE_LTLIBS@ +HOST_CPU = @HOST_CPU@ +HOST_CPU_C_ABI = @HOST_CPU_C_ABI@ +INCLIST = @INCLIST@ +INCSNPRINTFV = @INCSNPRINTFV@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSNPRINTFV = @LIBSNPRINTFV@ +LIBTOOL = @LIBTOOL@ +LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ +LIBXML2_LIBS = @LIBXML2_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +M4_SRC = @M4_SRC@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPTS_TESTDIR = @OPTS_TESTDIR@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSIX_SHELL = @POSIX_SHELL@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STDNORETURN_H = @STDNORETURN_H@ +STRIP = @STRIP@ +TEXI2HTML = @TEXI2HTML@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_aux_dir = @ac_aux_dir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +TARG = getdefs +getdefs_LDFLAGS = -no-install +gdsrcs = getdefs.h proto.h gdemit.c gdinit.c getdefs.c +getdefs_SOURCES = proto.h +BUILT_SOURCES = gd.c +nodist_getdefs_SOURCES = $(BUILT_SOURCES) +SUBDIRS = test +EXTRA_DIST = opts.def $(gdsrcs) +AG_ENV = top_builddir="$(top_builddir)" top_srcdir="$(top_srcdir)" \ + VERBOSE="$(V)" + +RUN_AG = $(AG_ENV) $(SHELL) "${top_srcdir}/build-aux/run-ag.sh" +@AMDEP_FALSE@DEPFL_OPTS = $@ +@AMDEP_TRUE@DEPFL_OPTS = $(DEPDIR)/opts-dep.mk +@AMDEP_FALSE@DEPFL_TEXI = $@ +@AMDEP_TRUE@DEPFL_TEXI = $(DEPDIR)/info-dep.mk +@AMDEP_FALSE@DEPFL_MAN = $@ +@AMDEP_TRUE@DEPFL_MAN = $(DEPDIR)/man-dep.mk +AGARG_OPTS = -MF$(DEPFL_OPTS) -MT$@ -MP +AGARG_TEXI = -MF$(DEPFL_TEXI) -MT$@ -MP -Tagtexi-cmd +AGARG_MAN = -MF$(DEPFL_MAN) -MT$@ -MP -Tagman-cmd +getdefs_LDADD = $(top_builddir)/autoopts/libopts.la +man_MANS = $(TARG).1 +TEXI_FILES = $(TARG).texi $(TARG).menu +DOCFILES = $(TEXI_FILES) $(man_MANS) +DISTCLEANFILES = $(DOCFILES) $(nodist_getdefs_SOURCES) *-stamp +AM_CPPFLAGS = @INCLIST@ +AM_CFLAGS = @WARN_CFLAGS@ +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu getdefs/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu getdefs/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p \ + || test -f $$p1 \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' \ + `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +getdefs$(EXEEXT): $(getdefs_OBJECTS) $(getdefs_DEPENDENCIES) $(EXTRA_getdefs_DEPENDENCIES) + @rm -f getdefs$(EXEEXT) + $(AM_V_CCLD)$(getdefs_LINK) $(getdefs_OBJECTS) $(getdefs_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gd.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-man1: $(man_MANS) + @$(NORMAL_INSTALL) + @list1=''; \ + list2='$(man_MANS)'; \ + test -n "$(man1dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.1[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ + done; } + +uninstall-man1: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man1dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.1[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) + +# 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. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-recursive +all-am: Makefile $(PROGRAMS) $(MANS) +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +clean: clean-recursive + +clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f ./$(DEPDIR)/gd.Po + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: install-man + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: install-binPROGRAMS + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: install-man1 + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f ./$(DEPDIR)/gd.Po + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-man + +uninstall-man: uninstall-man1 + +.MAKE: $(am__recursive_targets) all check install install-am \ + install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ + am--depfiles check check-am clean clean-binPROGRAMS \ + clean-generic clean-libtool cscopelist-am ctags ctags-am \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-binPROGRAMS \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-man1 \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-binPROGRAMS uninstall-man \ + uninstall-man1 + +.PRECIOUS: Makefile + + +all : gen +gen : $(BUILT_SOURCES) $(DOCFILES) + +@AMDEP_TRUE@$(DEPFL_OPTS) : +@AMDEP_TRUE@ $(RUN_AG) "$@" +@AMDEP_TRUE@include $(DEPFL_OPTS) + +@AMDEP_TRUE@$(DEPFL_MAN) : +@AMDEP_TRUE@ $(RUN_AG) "$@" +@AMDEP_TRUE@include $(DEPFL_MAN) + +@AMDEP_TRUE@$(DEPFL_INFO) : +@AMDEP_TRUE@ $(RUN_AG) "$@" +@AMDEP_TRUE@include $(DEPFL_INFO) + +gd.c : $(gdsrcs) + exec > $@ ; \ + echo '#undef PKGDATADIR' ; \ + echo '#define PKGDATADIR "$(pkgdatadir)"' ; \ + echo ; echo '#define DEFINING 1' ; \ + echo '#include "autoopts/project.h"' ; \ + for f in opts.c $(gdsrcs) ; \ + do echo "#include \"$$f\"" ; done + +$(getdefs_OBJECTS) opts.h opts.c : stamp-opts +stamp-opts : opts.def + $(RUN_AG) $(AGARG_OPTS) $(srcdir)/opts.def + +$(man_MANS) : stamp-man +stamp-man : $(TARG)$(EXEEXT) + $(RUN_AG) $(AGARG_MAN) $(srcdir)/opts.def + +$(TEXI_FILES) : stamp-doc +stamp-doc : $(TARG)$(EXEEXT) + $(RUN_AG) $(AGARG_TEXI) -DLEVEL=section $(srcdir)/opts.def + +.NOTPARALLEL: + +.PHONY : local-maintainer-clean stamp-man +local-maintainer-clean : clean-stamp-opts clean-stamp-doc clean-stamp-man + rm -f *~ + +# end of getdefs/Makefile.am + +# 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/getdefs/gdemit.c b/getdefs/gdemit.c new file mode 100644 index 0000000..6d991d7 --- /dev/null +++ b/getdefs/gdemit.c @@ -0,0 +1,586 @@ + +/** + * @file gdemit.c + * @addtogroup columns + * @{ + */ +/* + * getdefs Copyright (C) 1999-2018 by Bruce Korb - all rights reserved + * + * Author: Bruce Korb + * This file is part of AutoGen. + * AutoGen Copyright (C) 1992-2017 by Bruce Korb - all rights reserved + * + * AutoGen is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AutoGen is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +/* + * compress_def + * + * Compress the definition text. Each input line has some prefix + * stuff to ensure it is a comment as seen by the normal processor + * of the file. In "C", the entire block is surrounded by the + * '/'-'*' and '*'-'/' pairs. In shell, every line would start + * with a hash character ('#'). Etc. To make life easy, we require + * that every line be prefixed with something that matches the + * pattern: + * + * "^[^*]*\*+" + * + * and any line that does not is ignored. So, here we strip off + * that prefix before we go ahead and try to parse it. + */ +static void +compress_def(char * pz) +{ + char * pzStrt = pz; + char * pzDest = pz; + char * pzSrc = pz; + int nlCt = 0; + + /* + * Search until we find a line that contains an asterisk + * and is followed by something other than whitespace. + */ + nlCt = 0; + + skip_leading_space: + while (isspace( *pzSrc )) { + if (*(pzSrc++) == '\n') { + nlCt++; + for (;;) { + switch (*(pzSrc++)) { + case '*': + while (*pzSrc == '*') pzSrc++; + goto skip_leading_space; + + case NUL: + *pzStrt = NUL; + return; + + case '\n': + nlCt++; + } + } + } + } + + if (*pzSrc == NUL) { + *pzStrt = NUL; + return; + } + + /* + * FOR as long as we still have more text, ... + */ + for (;;) { + /* + * IF we passed over one or more newlines while looking for + * an asterisk, then insert one extra newline into the output + */ + if (nlCt > 0) { + *pzDest++ = '\n'; + nlCt = 0; + } + + /* + * FOR all the data on the current input line, ... + */ + for (;;) { + /* + * Move the source to destination until we find + * either a new-line or a NUL. + */ + switch (*pzDest++ = *pzSrc++) { + case '\n': + if (*pzSrc != NUL) + goto lineDone; + /* FALLTHROUGH */ + + case NUL: + pzDest--; + goto compressDone; + + default: + ; + } + } lineDone:; + + /* + * Trim trailing white space off the end of the line. + */ + if ((pzDest[-2] == ' ') || (pzDest[-2] == '\t')) { + do { + pzDest--; + } while ((pzDest[-2] == ' ') || (pzDest[-2] == '\t')); + pzDest[-1] = '\n'; + } + + /* + * We found a new-line. Skip forward to an asterisk. + */ + foundNewline: + while (*pzSrc != '*') { + if (*pzSrc == NUL) + goto compressDone; + if (*pzSrc == '\n') + nlCt++; + pzSrc++; + } + + /* + * Skip over the asterisk we found and all the ones that follow + */ + while (*pzSrc == '*') pzSrc++; + while (isspace( *pzSrc )) { + /* + * IF we stumble into another newline, + * THEN we go back to look for an asterisk. + */ + if (*pzSrc == '\n') + goto foundNewline; + pzSrc++; + } + } compressDone:; + + /* + * Trim off all the trailing white space, including newlines + */ + while ((pzDest > pzStrt) && isspace( pzDest[-1] )) pzDest--; + *pzDest = NUL; +} + + +/* + * emitDefinition + */ +MOD_LOCAL char * +emitDefinition(char * pzDef, char * pzOut) +{ + char sep_char; + char zEntryName[ MAXNAMELEN ]; + + /* + * Indent attribute definitions four spaces + */ + { + char * p = zEntryName; + *pzOut++ = ' '; *pzOut++ = ' '; *pzOut++ = ' '; *pzOut++ = ' '; + + while (AG_NAME_CHAR(*pzDef)) + *p++ = *pzOut++ = *pzDef++; + + if (p >= zEntryName + sizeof(zEntryName)) + die(GETDEFS_EXIT_USAGE_ERROR, "names are constrained to %d bytes\n", + MAXNAMELEN); + + *p = NUL; + } + + /* + * Strip the prefixes from all the definition lines + * (viz., the "^.*\*" text, except that it is a shortest match + * instead of longest match). Skip the ':' before starting. + */ + compress_def(++pzDef); + + if (HAVE_OPT( SUBBLOCK )) { + int ct = STACKCT_OPT( SUBBLOCK ); + char const ** ppz = STACKLST_OPT( SUBBLOCK ); + + do { + char const * pz = *ppz++; + if (strcmp(pz, zEntryName) == 0) + return emit_subblock(pz, pzDef, pzOut); + } while (--ct > 0); + } + + if (HAVE_OPT( LISTATTR )) { + int ct = STACKCT_OPT( LISTATTR ); + char const ** ppz = STACKLST_OPT( LISTATTR ); + + do { + if (strcmp(*ppz++, zEntryName) == 0) + return list_attrib(pzDef, pzOut); + } while (--ct > 0); + } + + if (isspace(*pzDef)) + sep_char = *pzDef++; + else sep_char = ' '; + + switch (*pzDef) { + case NUL: + *pzOut++ = ';'; *pzOut++ = '\n'; + break; + + case '"': + case '\'': + case '{': + /* + * Quoted entries or subblocks do their own stringification + * sprintf is safe because we are copying strings around + * and *always* making the result smaller than the original + */ + pzOut += sprintf(pzOut, " =%c%s;\n", sep_char, pzDef); + break; + + default: + *pzOut++ = ' '; *pzOut++ = '='; *pzOut++ = sep_char; + *pzOut++ = '\''; + + for (;;) { + switch (*pzOut++ = *pzDef++) { + case '\\': + *pzOut++ = '\\'; + break; + + case '\'': + pzOut[-1] = '\\'; + *pzOut++ = '\''; + break; + + case NUL: + goto unquotedDone; + } + } unquotedDone:; + pzOut[-1] = '\''; *pzOut++ = ';'; *pzOut++ = '\n'; + break; + } + return pzOut; +} + + +/* + * list_attrib + */ +static char * +list_attrib(char * pzText, char * pzOut) +{ + static char const zStart[] = " = "; + + uint_t sepChar = ','; + int FirstAttr = 1; + + strcpy(pzOut, zStart); + pzOut += sizeof(zStart) - 1; + + /* + * See if there is an alternate separator character. + * It must be a punctuation character that is not also + * a quote character. + */ + if (ispunct(*pzText) && (*pzText != '"') && (*pzText != '\'')) + sepChar = (uint_t)*(pzText++); + while (isspace(*pzText)) pzText++; + + /* + * Loop for as long as we have text entries + */ + while (*pzText != NUL) { + + if (FirstAttr) + FirstAttr = 0; + else + *(pzOut++) = ','; + + /* + * If the first thing we find is the separator char, + * then emit the empty string. + */ + if ((uint_t)*pzText == sepChar) { + *(pzOut++) = '\''; *(pzOut++) = '\''; + pzText++; + continue; + } + + /* + * Emit whatever we have. The call will consume any trailing + * separator character. + */ + pzOut = subblock_str(&pzText, sepChar, pzOut); + } + + /* + * IF there were no definitions, THEN emit an empty one + */ + if (FirstAttr) + pzOut -= sizeof(zStart) - 1; + + *(pzOut++) = ';'; + *(pzOut++) = '\n'; + + return pzOut; +} + + +/* + * The text is quoted, so copy it as is, ensuring that escaped + * characters are not used to end the quoted text. + */ +static char * +emit_quote(char ** ppzText, char * pzOut) +{ + char * pzText = *ppzText; + char svch = (*pzOut++ = *pzText++); + + for (;;) { + switch (*pzOut++ = *pzText++) { + + case '\\': + if ((*pzOut++ = *pzText++) != NUL) + break; + /* FALLTHROUGH */ + + case NUL: + pzText--; + pzOut[-1] = svch; + svch = NUL; + /* FALLTHROUGH */ + + case '"': + case '\'': + if (pzOut[-1] == svch) + goto quoteDone; + + break; + } + } + +quoteDone: + *ppzText = pzText; + return pzOut; +} + +static void +next_def_entry(char ** txt_pp, char const ** def_pp) +{ + char const * p = *def_pp; + (*txt_pp)++; + for (;;) { + switch (*++p) { + case ' ': p++; /* FALLTHROUGH */ + case NUL: + *def_pp = p; + return; + } + } +} + +static void +emit_attribute(char const ** def_pp, char ** out_pp) +{ + static char const pfx[] = "\n "; + + char * out = *out_pp; + char const * def = *def_pp; + + memcpy(out, pfx, sizeof(pfx) - 1); + out += sizeof(pfx) - 1; + + for (;;) { + *out++ = *def++; + switch (*def) { + case ' ': def++; /* FALLTHROUGH */ + case NUL: + goto leave_emit_attribute; + } + } + + leave_emit_attribute: + + *out++ = ';'; + *out_pp = out; + *def_pp = def; +} + +/* + * emit_subblock + */ +static char * +emit_subblock(char const * pzDefList, char * pzText, char * pzOut) +{ + static char const zStart[] = " = {"; + static char const zEnd[] = "\n };\n"; + + uint_t sepChar = ','; + int FirstAttr = 1; + + /* + * Advance past subblock name to the entry name list + */ + pzDefList += strlen(pzDefList) + 1; + strcpy(pzOut, zStart); + pzOut += sizeof(zStart) - 1; + + /* + * See if there is an alternate separator character. + * It must be a punctuation character that is not also + * a quote character. + */ + if (ispunct(*pzText) && (*pzText != '"') && (*pzText != '\'')) + sepChar = (uint_t)*(pzText++); + + /* + * Loop for as long as we have text entries and subblock + * attribute names, ... + */ + do { + /* + * IF the first character is the separator, + * THEN this entry is skipped. + */ + if ((uint_t)*pzText == sepChar) { + next_def_entry(&pzText, &pzDefList); + continue; + } + + /* + * Skip leading white space in the attribute and check for done. + */ + while (isspace(*pzText)) pzText++; + if (*pzText == NUL) { + /* + * IF there were no definitions, THEN emit one anyway + */ + if (FirstAttr) + emit_attribute(&pzDefList, &pzOut); + + break; + } + + /* + * Copy out the attribute name + */ + emit_attribute(&pzDefList, &pzOut); + FirstAttr = 0; + + /* + * IF there are no data for this attribute, + * THEN we leave the definition empty. + */ + if ((uint_t)*pzText == sepChar) { + pzText++; + continue; + } + + /* + * Copy out the assignment operator and emit the string + */ + pzOut[-1] = ' '; *pzOut++ = '='; *pzOut++ = ' '; + pzOut = subblock_str(&pzText, sepChar, pzOut); + *pzOut++ = ';'; + + } while (isalpha(*pzDefList)); + + memcpy(pzOut, zEnd, sizeof(zEnd)); + return pzOut + sizeof(zEnd) - 1; +} + + +/* + * Emit a string in a fashion that autogen will be able to + * correctly reconstruct it. + */ +static char * +subblock_str(char ** ppzText, uint_t sepChar, char * pzOut) +{ + char * pzText = *ppzText; + char * pcComma; + char * pcEnd; + + /* + * Skip leading space + */ + while (isspace(*pzText)) pzText++; + + /* + * IF the text is already quoted, + * THEN call the quoted text emitting routine + */ + if ((*pzText == '"') || (*pzText == '\'')) { + pzOut = emit_quote(&pzText, pzOut); + + /* + * Make sure we strip off trailing white space and any + * separation character. + */ + while (isspace(*pzText)) pzText++; + if ((uint_t)*pzText == sepChar) { + pzText++; + while (isspace(*pzText)) pzText++; + } + *ppzText = pzText; + return pzOut; + } + + /* + * Look for the character that separates this entry text + * from the entry text for the next attribute. Leave 'pcComma' + * pointing to the character _before_ the character where we + * are to resume our text scan. (i.e. at the comma, or the + * last character in the string) + */ + pcComma = strchr(pzText, (int)sepChar); + if (pcComma == (char *)NULL) { + pcEnd = pzText + strlen(pzText); + pcComma = pcEnd-1; + } else { + pcEnd = pcComma; + } + + /* + * Clean off trailing white space. + */ + while ((pcEnd > pzText) && isspace(pcEnd[-1])) pcEnd--; + + /* + * Copy the text, surrounded by single quotes + */ + *pzOut++ = '\''; + { + char svch = *pcEnd; + *pcEnd = NUL; + for (;;) { + char ch = *pzText++; + switch (ch) { + case '\'': + *pzOut++ = '\\'; + /* FALLTHROUGH */ + default: + *pzOut++ = ch; + break; + case NUL: + goto copyDone; + } + } copyDone: ; + + pzText = pcComma+1; + *pcEnd = svch; + } + + *pzOut++ = '\''; + while (isspace(*pzText)) pzText++; + *ppzText = pzText; + return pzOut; +} + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of getdefs/gdemit.c */ diff --git a/getdefs/gdinit.c b/getdefs/gdinit.c new file mode 100644 index 0000000..0ad9c9a --- /dev/null +++ b/getdefs/gdinit.c @@ -0,0 +1,456 @@ + +/** + * @file gdinit.c + * @addtogroup columns + * @{ + */ +/* + * getdefs Copyright (C) 1999-2018 by Bruce Korb - all rights reserved + * + * Author: Bruce Korb + * This file is part of AutoGen. + * AutoGen Copyright (C) 1992-2017 by Bruce Korb - all rights reserved + * + * AutoGen is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AutoGen is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +MOD_LOCAL char const zNoList[] = "ERROR: block attr must have name list:\n\t%s\n"; + +/* + * compressOptionText + */ +static char * +compressOptionText(char * pzS, char * pzE) +{ + char * pzR = pzS; /* result */ + char * pzD = pzS; /* destination */ + + for (;;) { + char ch; + + if (pzS >= pzE) + break; + + ch = (*(pzD++) = *(pzS++)); + + /* + * IF At end of line, skip to next '*' + */ + if (ch == '\n') { + while (*pzS != '*') { + pzS++; + if (pzS >= pzE) + goto compressDone; + } + } + } compressDone:; + + { + size_t len = (size_t)(pzD - pzR); + pzD = malloc(len + 1); + if (pzD == NULL) + nomem_err(len + 1, "new option string"); + + memcpy(pzD, pzR, len); + pzD[ len ] = NUL; + } + + /* + * Blank out trailing data. + */ + while (pzS < pzE) *(pzS++) = ' '; + return pzD; +} + + +/* + * fixupSubblockString + */ +static char * +fixupSubblockString(char const * pzSrc) +{ + char * pzString; + char * pzDest; + char * pzCopy; + + pzString = strdup(pzSrc); + + /* + * Make sure we find the '=' separator + */ + { + char * p = strchr(pzString, '='); + if (p == NULL) + die(GETDEFS_EXIT_INVALID_INPUT, zNoList, pzString); + + /* + * Trim the name + */ + pzDest = p++; + while ((pzDest > pzString) && IS_HORIZ_WHITE_CHAR(pzDest[-1])) pzDest--; + *(pzDest++) = NUL; + + /* + * Make sure at least one attribute name is defined + */ + while (IS_WHITESPACE_CHAR(*p)) p++; + if (*p == NUL) + die(GETDEFS_EXIT_INVALID_INPUT, zNoList, pzString); + + pzCopy = p; + } + + for (;;) { + /* + * Attribute names must start with an alpha + */ + if (! IS_ALPHABETIC_CHAR(*pzCopy)) { + fprintf(stderr, "ERROR: attribute names must start " + "with an alphabetic character:\n\t%s\n", + pzString); + USAGE(EXIT_FAILURE); + } + + /* + * Copy the name. + */ + while (IS_OPTION_NAME_CHAR(*pzCopy)) + *pzDest++ = *pzCopy++; + + /* + * Skip over one comma (optional) and any white space. + * If there is a newline, it must be after the comma. + */ + while (IS_HORIZ_WHITE_CHAR(*pzCopy)) pzCopy++; + if (*pzCopy == ',') + pzCopy++; + + while (IS_WHITESPACE_CHAR(*pzCopy)) pzCopy++; + if (*pzCopy == NUL) + break; + /* + * The final string contains only one space between attributes + */ + *pzDest++ = ' '; + } + + *pzDest = NUL; + + return pzString; +} + + +/* + * loadStdin + * + * The input file list is from stdin. + * + * We make some simplifying assumptions: + * *ALL* input lines are less than 4096 bytes. If this is not true, + * we may strip some white space in the middle of a line and presume + * a comment begins in the middle of a line or we only comment out + * the first 4096 bytes of a comment line. So, rather than all these + * problems, we just choke on it. + */ +static void +loadStdin(void) +{ + char z[ 4096 ]; + int ct = 0; + char const ** ppz = STACKLST_OPT(INPUT); + + if (isatty(STDIN_FILENO)) { + fputs("getdefs error: no inputs were specified and stdin is a tty\n", + stderr); + USAGE(EXIT_FAILURE); + } + + while (fgets(z, (int)sizeof(z), stdin) != NULL) { + char * pz = z + strlen(z); + + if (pz[-1] != '\n') { + static char const zErr[] = + "getdefs error: input line not newline terminated\n"; + fputs(zErr, stderr); + exit(EXIT_FAILURE); + } + + while ((pz > z) && isspace(pz[-1])) pz--; + *pz = '\0'; + pz = z; + while (isspace(*pz)) pz++; + if ((*pz == '\0') || (*pz == '#')) continue; + if (access(pz, R_OK) != 0) continue; + + if (ct++ == 0) + *ppz = strdup(z); /* replace the "-" */ + else + SET_OPT_INPUT(strdup(z)); /* if 'strdup' fails, we die later */ + } +} + + +/* + * processEmbeddedOptions + * + * This routine processes the text contained within "/\*==--" + * and "=\*\/" as a single option. If that option is the SUBBLOCK + * option, it will need to be massaged for use. + */ +MOD_LOCAL void +processEmbeddedOptions(char * pzText) +{ + static char const zStStr[] = "/*=--"; + static char const zEndSt[] = "=*/"; + + for (;;) { + char * pzStart = strstr(pzText, zStStr); + char * pzEnd; + int sblct = 0; + + if (pzStart == NULL) + return; + + if (HAVE_OPT(SUBBLOCK)) + sblct = STACKCT_OPT(SUBBLOCK); + + pzEnd = strstr(pzStart, zEndSt); + if (pzEnd == NULL) + return; + + pzStart = compressOptionText(pzStart + sizeof(zStStr)-1, pzEnd); + + optionLoadLine(&getdefsOptions, pzStart); + + if (HAVE_OPT(SUBBLOCK) && (sblct != STACKCT_OPT(SUBBLOCK))) { + char const ** ppz = STACKLST_OPT(SUBBLOCK); + ppz[ sblct ] = fixupSubblockString(ppz[sblct]); + } + pzText = pzEnd + sizeof(zEndSt); + } +} + +/** + * set up the regular expression we search for + */ +static void +set_define_re(void) +{ + static char const default_pat[] = + "/\\*=(\\*|" + "([a-z][a-z0-9_]*(\\[[0-9]+\\]){0,1}|\\*)[ \t]+[a-z])"; + static char const pat_wrapper[] = "/\\*=(%s)"; + + char const * def_pat; + bool free_pat = false; + + /* + * Our default pattern is to accept all names following + * the '/' '*' '=' character sequence. We ignore case. + */ + if ((! HAVE_OPT(DEFS_TO_GET)) || (*OPT_ARG(DEFS_TO_GET) == NUL)) { + def_pat = default_pat; + + } else if (strncmp(OPT_ARG(DEFS_TO_GET), default_pat, 4) == 0) { + def_pat = OPT_ARG(DEFS_TO_GET); + + } else { + char const * pz = OPT_ARG(DEFS_TO_GET); + size_t len = strlen((char *)pz) + 16; + char * bf = malloc(len); + + if (bf == NULL) + nomem_err(len, "definition pattern"); + + /* + * IF a pattern has been supplied, enclose it with + * the '/' '*' '=' part of the pattern. + */ + snprintf(bf, len, pat_wrapper, pz); + def_pat = bf; + free_pat = true; + } + + /* + * Compile the regular expression that we are to search for + * to find each new definition in the source files. + */ + { + char zRER[MAXNAMELEN]; + static char const regex_err[] = + "Regex error %d (%s): Cannot compile reg expr:\n\t%s\n"; + + int rerr = regcomp(&define_re, def_pat, REG_EXTENDED | REG_ICASE); + if (rerr != 0) { + regerror(rerr, &define_re, zRER, sizeof(zRER)); + die(GETDEFS_EXIT_INVALID_INPUT, regex_err, rerr, zRER, def_pat); + } + + if (free_pat) + free(VOIDP(def_pat)); + + rerr = regcomp(&attrib_re, zAttribRe, REG_EXTENDED | REG_ICASE); + if (rerr != 0) { + regerror(rerr, &attrib_re, zRER, sizeof(zRER)); + die(GETDEFS_EXIT_INVALID_INPUT, regex_err, rerr, zRER, zAttribRe); + } + } +} + +/** + * Make sure each of the input files is findable. + * Also, while we are at it, compute the output file mod time + * based on the mod time of the most recent file. + */ +static void +set_modtime(void) +{ + int ct = STACKCT_OPT(INPUT); + char const ** ppz = STACKLST_OPT(INPUT); + struct stat stb; + + if ((ct == 1) && (strcmp(*ppz, "-") == 0)) { + /* + * Read the list of input files from stdin. + */ + loadStdin(); + ct = STACKCT_OPT( INPUT); + ppz = STACKLST_OPT(INPUT); + } + + do { + if (stat(*ppz++, &stb) != 0) + break; + + if (! S_ISREG(stb.st_mode)) { + errno = EINVAL; + break; + } + + if (++(stb.st_mtime) > modtime) + modtime = stb.st_mtime; + } while (--ct > 0); + + if (ct > 0) + fserr(GETDEFS_EXIT_INVALID_INPUT, "stat", ppz[-1]); +} + +/** + * validate_opts + * + * - Sanity check the options + * - massage the SUBBLOCK options into something + * more easily used during the source text processing. + * - compile the regular expressions + * - make sure we can find all the input files and their mod times + * - Set up our entry ordering database (if specified) + * - Make sure we have valid strings for SRCFILE and LINENUM + * (if we are to use these things). + * - Initialize the user name characters array. + */ +static void +validate_opts(void) +{ + set_define_re(); + + /* + * Prepare each sub-block entry so we can parse easily later. + */ + if (HAVE_OPT(SUBBLOCK)) { + int ct = STACKCT_OPT( SUBBLOCK); + char const ** ppz = STACKLST_OPT(SUBBLOCK); + + /* + * FOR each SUBBLOCK argument, + * DO condense each name list to be a list of names + * separated by a single space and NUL terminated. + */ + do { + *ppz = fixupSubblockString(*ppz); + ppz++; + } while (--ct > 0); + } + + if (! HAVE_OPT(INPUT)) + SET_OPT_INPUT("-"); + + set_modtime(); + + /* + * IF the output is to have order AND it is to be based on a file, + * THEN load the contents of that file. + * IF we cannot load the file, + * THEN it must be new or empty. Allocate several K to start. + */ + if ( HAVE_OPT(ORDERING) + && (OPT_ARG(ORDERING) != NULL)) { + static char const preamble[] = + "# -*- buffer-read-only: t -*- vi: set ro:\n" + "#\n# DO NOT EDIT THIS FILE - it is auto-edited by getdefs\n"; + + pzIndexText = loadFile(OPT_ARG(ORDERING)); + if (pzIndexText == NULL) { + pzIndexText = pzEndIndex = pzIndexEOF = malloc((size_t)0x4000); + indexAlloc = 0x4000; + pzEndIndex += sprintf(pzEndIndex, "%s", preamble); + } else { + pzEndIndex = pzIndexEOF = pzIndexText + strlen(pzIndexText); + indexAlloc = (size_t)(pzEndIndex - pzIndexText) + 1; + } + + /* + * We map the name entries to a connonical form. + * By default, everything is mapped to lower case already. + * This call will map these three characters to '_'. + */ + strequate("_-^"); + } + + { + char const * pz = OPT_ARG(SRCFILE); + if ((pz == NULL) || (*pz == NUL)) + OPT_ARG(SRCFILE) = "srcfile"; + + pz = OPT_ARG(LINENUM); + if ((pz == NULL) || (*pz == NUL)) + OPT_ARG(LINENUM) = "linenum"; + } + + { + static char const ag_nm_chars[] = + "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789" "_-^"; + static char const usr_nm_chars[] = ":.$%*!~<>&@"; + + char const * p = ag_nm_chars; + + while (*p) + zUserNameCh[(unsigned char)(*p++)] = 3; + + p = usr_nm_chars; + while (*p) + zUserNameCh[(unsigned char)(*p++)] = 1; + } +} + + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of getdefs/gdinit.c */ diff --git a/getdefs/getdefs.c b/getdefs/getdefs.c new file mode 100644 index 0000000..3124cb0 --- /dev/null +++ b/getdefs/getdefs.c @@ -0,0 +1,1162 @@ + +/** + * @file getdefs.c + * @addtogroup getdefs + * @{ + */ +/* + * getdefs Copyright (C) 1999-2018 by Bruce Korb - all rights reserved + * + * Author: Bruce Korb + * + * This file is part of AutoGen. + * AutoGen Copyright (C) 1992-2017 by Bruce Korb - all rights reserved + * + * AutoGen is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AutoGen is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +MOD_LOCAL char const zBogusDef[] = "Bogus definition:\n%s\n"; + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * Forward procedure pointers + */ +typedef int (compar_func)(const void *, const void *); +MOD_LOCAL compar_func compar_text, compar_defname; + +#ifndef HAVE_STRSIGNAL +# include "compat/strsignal.c" +#endif + +#ifndef HAVE_CHMOD +# include "compat/chmod.c" +#endif + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * Main + */ +int +main(int argc, char ** argv) +{ + FILE * outFp; + + optionProcess(&getdefsOptions, argc, argv); + validate_opts(); + + outFp = startAutogen(); + + doPreamble(outFp); + + /* + * Process each input file + */ + { + int ct = STACKCT_OPT(INPUT); + char const ** ppz = STACKLST_OPT(INPUT); + + do { + processFile(*ppz++); + } while (--ct > 0); + } + + /* + * IF we don't have an ordering file, but we do have a "first index", + * THEN alphabetize by definition name. + */ + if ((pzIndexText == NULL) && HAVE_OPT(FIRST_INDEX)) { + qsort(VOIDP(papzBlocks), blkUseCt, sizeof(char *), compar_defname); + set_first_idx(); + } + + else if (ENABLED_OPT(ORDERING) && (blkUseCt > 1)) + qsort(VOIDP(papzBlocks), blkUseCt, sizeof(char *), &compar_text); + + printEntries(outFp); +#ifdef HAVE_FCHMOD + fchmod(fileno(outFp), S_IRUSR|S_IRGRP|S_IROTH); +#endif + fclose(outFp); + + /* + * IF output is to a file + * THEN set the permissions and modification times + */ + if ( (WHICH_IDX_AUTOGEN == INDEX_OPT_OUTPUT) + && (outFp != stdout) ) { + struct utimbuf tbuf; + tbuf.actime = time((time_t *)NULL); + tbuf.modtime = modtime + 1; + utime(OPT_ARG(OUTPUT), &tbuf); +#ifndef HAVE_CHMOD + chmod(OPT_ARG(OUTPUT), S_IRUSR|S_IRGRP|S_IROTH); +#endif + } + + /* + * IF we are keeping a database of indexes + * AND we have augmented the contents, + * THEN append the new entries to the file. + */ + if ((pzIndexText != NULL) && (pzEndIndex != pzIndexEOF)) + update_db(); + + if (agPid != -1) + return awaitAutogen(); + + return EXIT_SUCCESS; +} + + +/* + * assignIndex + */ +static char * +assignIndex(char * pzOut, char * pzDef) +{ + char * pzMatch; + size_t len = strlen(pzDef); + int idx; + + /* + * Make the source text all lower case and map + * '-', '^' and '_' characters to '_'. + */ + strtransform(pzDef, pzDef); + + /* + * IF there is already an entry, + * THEN put the index into the output. + */ + pzMatch = strstr(pzIndexText, pzDef); + if (pzMatch != NULL) { + pzMatch += len; + while (isspace(*pzMatch)) pzMatch++; + while ((*pzOut++ = *pzMatch++) != ']') ; + return pzOut; + } + + /* + * We have a new entry. Make sure we have room for it + * in our in-memory string + */ + if (((size_t)(pzEndIndex - pzIndexText) + len + 64 ) > indexAlloc) { + char * pz; + indexAlloc += 0x1FFF; + indexAlloc &= (unsigned long)~0x0FFFUL; + pz = (char *)realloc(VOIDP(pzIndexText), indexAlloc); + if (pz == NULL) { + fputs("Realloc of index text failed\n", stderr); + exit(EXIT_FAILURE); + } + + /* + * IF the allocation moved, + * THEN adjust all our pointers. + */ + if (pz != pzIndexText) { + pzIndexEOF = pz + (pzIndexEOF - pzIndexText); + pzEndIndex = pz + (pzEndIndex - pzIndexText); + pzIndexText = pz; + } + } + + /* + * IF there are no data in our text database, + * THEN use default index. + */ + if (pzEndIndex == pzIndexText) + idx = (int)OPT_VALUE_FIRST_INDEX; + else do { + char * pz = strrchr(pzDef, ' '); + *pz = NUL; + len = strlen(pzDef); + + /* + * Find the last entry for the current category of entries + */ + pzMatch = strstr(pzIndexText, pzDef); + if (pzMatch == NULL) { + /* + * No entries for this category. Use default index. + */ + idx = (int)OPT_VALUE_FIRST_INDEX; + *pz = ' '; + break; + } + + for (;;) { + char * pzn = strstr(pzMatch + len, pzDef); + if (pzn == NULL) + break; + pzMatch = pzn; + } + + /* + * Skip forward to the '[' character and convert the + * number that follows to a long. + */ + *pz = ' '; + pzMatch = strchr(pzMatch + len, '['); + idx = (int)strtol(pzMatch+1, (char **)NULL, 0)+1; + } while (false); + + /* + * Add the new entry to our text database and + * place a copy of the value into our output. + */ + pzEndIndex += sprintf(pzEndIndex, "%-40s [%d]\n", pzDef, idx); + pzOut += sprintf(pzOut, "[%d]", idx); + + return pzOut; +} + + +/* + * awaitAutogen + */ +static int +awaitAutogen(void) +{ + int status; + waitpid(agPid, &status, 0); + if (WIFEXITED(status)) { + status = WEXITSTATUS(status); + if (status != EXIT_SUCCESS) { + fprintf(stderr, "ERROR: %s exited with status %d\n", + pzAutogen, status); + } + return status; + } + + if (WIFSIGNALED( status )) { + status = WTERMSIG( status ); + fprintf(stderr, "ERROR: %s exited due to %d signal (%s)\n", + pzAutogen, status, strsignal(status)); + } + else + fprintf(stderr, "ERROR: %s exited due to unknown reason %d\n", + pzAutogen, status); + + return EXIT_FAILURE; +} + + +/* + * buildDefinition + */ +static void +buildDefinition(char * pzDef, char const * pzFile, int line, char * pzOut) +{ + static char const zSrcFile[] = " %s = '%s';\n"; + static char const zLineNum[] = " %s = '%d';\n"; + + bool these_are_global_defs; + tSuccess preamble; + int re_res; + char * pzNextDef = NULL; + regmatch_t match[2]; + + if (*pzDef == '*') { + these_are_global_defs = true; + strcpy(pzOut, zGlobal); + pzOut += sizeof(zGlobal)-1; + pzOut += sprintf(pzOut, zLineId, line, pzFile); + + pzDef = strchr(pzDef, '\n'); + preamble = PROBLEM; + + } else { + these_are_global_defs = false; + preamble = buildPreamble(&pzDef, &pzOut, pzFile, line); + if (FAILED(preamble)) { + *pzOut = NUL; + return; + } + } + + /* + * FOR each attribute for this entry, ... + */ + for (;;) { + /* + * Find the next attribute regular expression + */ + re_res = regexec(&attrib_re, pzDef, COUNT(match), match, 0); + switch (re_res) { + case 0: + /* + * NUL-terminate the current attribute. + * Set the "next" pointer to the start of the next attribute name. + */ + pzDef[ match[0].rm_so ] = NUL; + if (pzNextDef != NULL) + pzOut = emitDefinition(pzNextDef, pzOut); + pzNextDef = pzDef = pzDef + match[1].rm_so; + break; + + case REG_NOMATCH: + /* + * No more attributes. + */ + if (pzNextDef == NULL) { + *pzOut++ = '\n'; *pzOut++ = '#'; + sprintf(pzOut, zNoData, pzFile, line); + fputs(pzOut, stderr); + pzOut += strlen(pzOut); + return; + } + + pzOut = emitDefinition(pzNextDef, pzOut); + goto eachAttrDone; + break; + + default: + { + char zRER[ MAXNAMELEN ]; + static char const zErr[] = "error %d (%s) finding '%s' in\n%s\n\n"; + regerror(re_res, &attrib_re, zRER, sizeof(zRER)); + *pzOut++ = '\n'; + *pzOut++ = '#'; + sprintf(pzOut, zErr, re_res, zRER, zAttribRe, pzDef); + fprintf(stderr, "getdefs: %s", zErr); + return; + } + } + } eachAttrDone:; + + if (these_are_global_defs) { + *pzOut = NUL; + return; + } + + if (HAVE_OPT(COMMON_ASSIGN)) { + int ct = STACKCT_OPT(COMMON_ASSIGN); + char const ** ppz = STACKLST_OPT(COMMON_ASSIGN); + do { + pzOut += sprintf(pzOut, " %s;\n", *ppz++); + } while (--ct > 0); + } + + if (HAVE_OPT(SRCFILE)) + pzOut += sprintf(pzOut, zSrcFile, OPT_ARG(SRCFILE), pzFile); + + if (HAVE_OPT(LINENUM)) + pzOut += sprintf(pzOut, zLineNum, OPT_ARG(LINENUM), line); + + /* + * IF the preamble had a problem, it is because it could not + * emit the final "#endif\n" directive. Do that now. + */ + if (HADGLITCH(preamble)) + strcpy(pzOut, "};\n#endif\n"); + else strcpy(pzOut, "};\n"); +} + + +/* + * buildPreamble + */ +static tSuccess +buildPreamble(char ** ppzDef, char ** ppzOut, char const * fname, int line) +{ + char * pzDef = *ppzDef; + char * pzOut = *ppzOut; + + char def_bf[ MAXNAMELEN ]; + char name_bf[ MAXNAMELEN ]; + char * def_str = def_bf; + char * pzIfText = NULL; + + /* + * Copy out the name of the entry type + */ + *def_str++ = '`'; + while (isalnum(*pzDef) || (*pzDef == '_') || (*pzDef == '.') + || (*pzDef == '[') || (*pzDef == ']')) + *def_str++ = *pzDef++; + + *def_str = NUL; + + pzDef += (int)strspn(pzDef, "* \t"); + + /* + * Copy out the name for this entry of the above entry type. + */ + { + char * name_str = name_bf; + while (isalnum(*pzDef) || (*pzDef == '_')) + *name_str++ = *pzDef++; + *name_str = NUL; + } + + if ( (def_bf[1] == NUL) + || (name_bf[0] == NUL) ) { + fprintf(stderr, zNoData, fname, line); + return FAILURE; + } + + pzDef += (int)strspn(pzDef, " \t"); + + /* + * IF these names are followed by a comma and an "if" clause, + * THEN we emit the definition with "#if..."/"#endif" around it + */ + if (*pzDef == ',') { + pzDef++; + pzDef += strspn(pzDef, " \t"); + if ((pzDef[0] == 'i') && (pzDef[1] == 'f')) + pzIfText = pzDef; + } + + pzDef = strchr(pzDef, '\n'); + if (pzDef == NULL) { + fprintf(stderr, zNoData, fname, line); + return FAILURE; + } + + *pzDef = NUL; + + /* + * Now start the output. First, the "#line" directive, + * then any "#ifdef..." line and finally put the + * entry type name into the output. + */ + pzOut += sprintf(pzOut, zLineId, line, fname); + if (pzIfText != NULL) + pzOut += sprintf(pzOut, "#%s\n", pzIfText); + { + char * pz = def_bf+1; + while (*pz != NUL) + *pzOut++ = *pz++; + } + + /* + * IF we are indexing the entries, + * THEN build the string by which we are indexing + * and insert the index into the output. + */ + if (pzIndexText != NULL) { + sprintf(def_str, " %s'", name_bf); + pzOut = assignIndex(pzOut, def_bf); + } + + /* + * Now insert the name with a consistent name string prefix + * that we use to locate the sort key later. + */ + pzOut += sprintf(pzOut, "%s%s';\n", zNameTag, name_bf); + *ppzOut = pzOut; + *ppzDef = pzDef; + *pzDef = '\n'; /* restore the newline. Used in pattern match */ + + /* + * Returning "PROBLEM" means the caller must emit the "#endif\n" + * at the end of the definition. + */ + return (pzIfText != NULL) ? PROBLEM : SUCCESS; +} + + +/* + * compar_defname + */ +static int +compar_defname(const void * p1, const void * p2) +{ + char const * pzS1 = *(char const * const *)p1; + char const * pz1 = strstr(pzS1, zNameTag); + char const * pzS2 = *(char const * const *)p2; + char const * pz2 = strstr(pzS2, zNameTag); + + if (pz1 == NULL) { + if (strncmp(*(char const * const *)p1, zGlobal, sizeof(zGlobal)-1) == 0) + return -1; + + die(GETDEFS_EXIT_USAGE_ERROR, zBogusDef, *(char const * const *)p1); + } + + if (pz2 == NULL) { + if (strncmp(*(char const * const *)p2, zGlobal, sizeof(zGlobal)-1) == 0) + return 1; + + die(GETDEFS_EXIT_USAGE_ERROR, zBogusDef, *(char const * const *)p2); + } + + /* + * Back up to the name of the definition + */ + while ((pz1 > pzS1) && (*--pz1 != '\n')) ; + while ((pz2 > pzS2) && (*--pz2 != '\n')) ; + + return strcmp(pz1, pz2); +} + + +/* + * compar_text + * + * merely returns the relative ordering of two input strings. + * The arguments are pointers to pointers to NUL-terminated strings. + * IF the definiton was mal-formed, an error message was printed + * earlier. When we get here, we wil fail to find the "zNameTag" + * string and EXIT_FAILURE. + */ +static int +compar_text(const void * p1, const void * p2) +{ + char * pz1 = strstr(*(char const * const *)p1, zNameTag); + char * pe1; + char * pz2 = strstr(*(char const * const *)p2, zNameTag); + char * pe2; + int res; + + if (pz1 == NULL) { + if (strncmp(*(char const * const *)p1, zGlobal, sizeof(zGlobal)-1) == 0) + return -1; + + die(GETDEFS_EXIT_USAGE_ERROR, zBogusDef, *(char const * const *)p1); + } + + if (pz2 == NULL) { + if (strncmp(*(char const * const *)p2, zGlobal, sizeof(zGlobal)-1) == 0) + return 1; + + die(GETDEFS_EXIT_USAGE_ERROR, zBogusDef, *(char const * const *)p2); + } + + pz1 += sizeof(zNameTag)-1; + pe1 = strchr(pz1, '\''); + + if (pe1 == NULL) + die(GETDEFS_EXIT_USAGE_ERROR, zBogusDef, *(char const * const *)p1); + + pz2 += sizeof(zNameTag)-1; + pe2 = strchr(pz2, '\''); + + if (pe2 == NULL) + die(GETDEFS_EXIT_USAGE_ERROR, zBogusDef, *(char const * const *)p2); + + *pe1 = *pe2 = NUL; + + /* + * We know ordering is enabled because we only get called when + * it is enabled. If the option was also specified, then + * we sort without case sensitivity (and we compare '-', '_' + * and '^' as being equal as well). Otherwise, we do a + * strict string comparison. + */ + if (HAVE_OPT(ORDERING)) + res = streqvcmp(pz1, pz2); + else res = strcmp(pz1, pz2); + *pe1 = *pe2 = '\''; + return res; +} + + +/* + * doPreamble + */ +static void +doPreamble(FILE * outFp) +{ + /* + * Emit the "autogen definitions xxx;" line + */ + fprintf(outFp, zAgDef, OPT_ARG(TEMPLATE)); + + if (HAVE_OPT(FILELIST)) { + static char const zFmt[] = "%-12s = '%s';\n"; + char const * pzName = OPT_ARG(FILELIST); + + if ((pzName == NULL) || (*pzName == NUL)) + pzName = "infile"; + + if (HAVE_OPT(INPUT)) { + int ct = STACKCT_OPT(INPUT); + char const ** ppz = STACKLST_OPT(INPUT); + + do { + fprintf(outFp, zFmt, pzName, *ppz++); + } while (--ct > 0); + } + + if (HAVE_OPT(COPY)) { + int ct = STACKCT_OPT(COPY); + char const ** ppz = STACKLST_OPT(COPY); + + do { + fprintf(outFp, zFmt, pzName, *ppz++); + } while (--ct > 0); + } + fputc('\n', outFp); + } + + /* + * IF there are COPY files to be included, + * THEN emit the '#include' directives + */ + if (HAVE_OPT(COPY)) { + int ct = STACKCT_OPT(COPY); + char const ** ppz = STACKLST_OPT(COPY); + do { + fprintf(outFp, "#include %s\n", *ppz++); + } while (--ct > 0); + fputc('\n', outFp); + } + + /* + * IF there are global assignments, then emit them + * (these do not get sorted, so we write directly now.) + */ + if (HAVE_OPT(ASSIGN)) { + int ct = STACKCT_OPT(ASSIGN); + char const ** ppz = STACKLST_OPT(ASSIGN); + do { + fprintf(outFp, "%s;\n", *ppz++); + } while (--ct > 0); + fputc('\n', outFp); + } +} + + +/* + * loadFile + */ +static char * +loadFile(char const * pzFname) +{ + FILE * fp = fopen(pzFname, "r" FOPEN_BINARY_FLAG); + int res; + char * pzText; + char * pzRead; + size_t rdsz; + + if (fp == (FILE *)NULL) + return NULL; + /* + * Find out how much data we need to read. + * And make sure we are reading a regular file. + */ + { + struct stat stb; + res = fstat(fileno(fp), &stb); + if (res != 0) + fserr(GETDEFS_EXIT_INVALID_INPUT, "fstat", pzFname); + + if (! S_ISREG(stb.st_mode)) { + errno = EINVAL; + fserr(GETDEFS_EXIT_INVALID_INPUT, "fstat", pzFname); + } + + rdsz = (size_t)stb.st_size; + if (rdsz < 16) + die(GETDEFS_EXIT_USAGE_ERROR, + "Error file %s only contains %d bytes.\n" + "\tit cannot contain autogen definitions\n", + pzFname, (int)rdsz); + } + + /* + * Allocate the space we need for the ENTIRE file. + */ + pzRead = pzText = (char *)malloc(rdsz + 1); + if (pzText == NULL) + die(GETDEFS_EXIT_USAGE_ERROR, "Error: could not allocate %d bytes\n", + (int)rdsz + 1); + + /* + * Read as much as we can get until we have read the file. + */ + do { + size_t rdct = fread(VOIDP(pzRead), (size_t)1, rdsz, fp); + + if (rdct == 0) + fserr(GETDEFS_EXIT_INVALID_INPUT, "fread", pzFname); + + pzRead += rdct; + rdsz -= rdct; + } while (rdsz > 0); + + *pzRead = NUL; + fclose(fp); + return pzText; +} + + +/* + * printEntries + */ +static void +printEntries(FILE * fp) +{ + size_t ct = blkUseCt; + char ** ppz = papzBlocks; + + if (ct == 0) + exit(EXIT_FAILURE); + + for (;;) { + char * pz = *(ppz++); + fputs(pz, fp); + free(VOIDP(pz)); + if (--ct == 0) + break; + fputc('\n', fp); + } + free(VOIDP(papzBlocks)); +} + + +/* + * processFile + */ +static void +processFile(char const * fname) +{ + char * pzText = loadFile(fname); /* full text */ + char * pzScan; /* Scanning Pointer */ + char * pzDef; /* Def block start */ + char * pzNext; /* start next search */ + char * pzDta; /* data value */ + int lineNo = 1; + char * pzOut; + regmatch_t matches[MAX_SUBMATCH+1]; + + if (pzText == NULL) { + errno = ENOMEM; + fserr(GETDEFS_EXIT_INVALID_INPUT, "open+read", fname); + } + + processEmbeddedOptions(pzText); + pzNext = pzText; + + while (pzScan = pzNext, + regexec(&define_re, pzScan, COUNT(matches), matches, 0) == 0) { + + static char const zNoEnd[] = + "Error: definition in %s at line %d has no end\n"; + static char const zNoSubexp[] = + "Warning: entry type not found on line %d in %s:\n\t%s\n"; + + int linesInDef = 0; + + /* + * Make sure there is a subexpression match!! + */ + if (matches[1].rm_so == -1) { + char * pz = NULL; + char ch = NUL; + + pzDef = pzScan + matches[0].rm_so; + if (strlen(pzDef) > 30) { + pz = pzDef + 30; + ch = *pz; + *pz = NUL; + } + + fprintf(stderr, zNoSubexp, lineNo, fname, pzDef); + if (pz != NULL) + *pz = ch; + continue; + } + + pzDef = pzScan + matches[0].rm_so + sizeof("/*=") - 1; + pzNext = strstr(pzDef, "=*/"); + if (pzNext == NULL) + die(GETDEFS_EXIT_USAGE_ERROR, zNoEnd, fname, lineNo); + + *pzNext = NUL; + pzNext += 3; + /* + * Count the number of lines skipped to the start of the def. + */ + for (;;) { + pzScan = strchr(pzScan, '\n'); + if (pzScan++ == NULL) + break; + if (pzScan >= pzDef) + break; + lineNo++; + } + + pzOut = pzDta = (char *)malloc(2 * strlen(pzDef) + 8000); + + /* + * Count the number of lines in the definition itself. + * It will find and stop on the "=* /\n" line. + */ + pzScan = pzDef; + for (;;) { + pzScan = strchr(pzScan, '\n'); + if (pzScan++ == NULL) + break; + linesInDef++; + } + + /* + * OK. We are done figuring out where the boundaries of the + * definition are and where we will resume our processing. + */ + buildDefinition(pzDef, fname, lineNo, pzOut); + pzDta = (char *)realloc(VOIDP(pzDta), strlen(pzDta) + 1); + lineNo += linesInDef; + + if (++blkUseCt > blkAllocCt) { + blkAllocCt += 32; + papzBlocks = (char **)realloc(VOIDP(papzBlocks), + blkAllocCt * sizeof(char *)); + if (papzBlocks == (char **)NULL) + die(GETDEFS_EXIT_USAGE_ERROR, "Realloc error for %d pointers\n", + (int)blkAllocCt); + } + papzBlocks[ blkUseCt-1 ] = pzDta; + } + + free(VOIDP(pzText)); +} + + +/* + * set_first_idx + * + * Go through all our different kinds of defines. On the first occurrence + * of each different name, check for an index value. If not supplied, + * then insert ''[OPT_VALUE_FIRST_INDEX]'' after the object name. + */ +static void +set_first_idx(void) +{ + char zNm[ 128 ] = { NUL }; + size_t nmLn = 1; + int ct = (int)blkUseCt; + char ** ppz = papzBlocks; + + if (ct == 0) + exit(EXIT_FAILURE); + + for (; --ct >= 0; ppz++) { + char * pzOld = *ppz; + int changed = (strneqvcmp(pzOld, zNm, (int)nmLn) != 0); + char * pzNew; + + /* + * IF the name still matches, then check the following character. + * If it is whitespace or an open bracket, then + * it's the old type. Continue to the next entry. + */ + if (! changed) { + if (isspace(pzOld[ nmLn ]) || (pzOld[nmLn] == '[')) + continue; + } + + pzNew = zNm; + nmLn = 0; + while (isalnum(*pzOld) + || (*pzOld == '_') || (*pzOld == '-') || (*pzOld == '^')) { + nmLn++; + *(pzNew++) = *(pzOld++); + } + *pzNew = NUL; + + /* + * IF the source has specified its own index, then do not + * supply our own new one. + */ + if (*pzOld != '[') { + pzNew = (char *)malloc(strlen(pzOld) + nmLn + 10); + sprintf(pzNew, "%s[%d]%s", zNm, + (int)OPT_VALUE_FIRST_INDEX, pzOld); + free(VOIDP(*ppz)); + *ppz = pzNew; + } + } +} + +static FILE * +open_ag_file(char ** pzBase) +{ + switch (WHICH_IDX_AUTOGEN) { + case INDEX_OPT_OUTPUT: + { + static char const zFileFmt[] = " * %s\n"; + FILE * fp; + + if (*pzBase != NULL) + free(*pzBase); + + if (strcmp(OPT_ARG(OUTPUT), "-") == 0) + return stdout; + + unlink(OPT_ARG(OUTPUT)); + fp = fopen(OPT_ARG(OUTPUT), "w" FOPEN_BINARY_FLAG); + fprintf(fp, zDne, OPT_ARG(OUTPUT)); + + if (HAVE_OPT(INPUT)) { + int ct = STACKCT_OPT(INPUT); + char const ** ppz = STACKLST_OPT(INPUT); + do { + fprintf(fp, zFileFmt, *ppz++); + } while (--ct > 0); + } + + fputs(" */\n", fp); + return fp; + } + + case INDEX_OPT_AUTOGEN: + if (! ENABLED_OPT(AUTOGEN)) { + if (*pzBase != NULL) + free(*pzBase); + + return stdout; + } + + if ( ( OPT_ARG(AUTOGEN) != NULL) + && (*OPT_ARG(AUTOGEN) != NUL )) + pzAutogen = OPT_ARG(AUTOGEN); + + break; + } + + return NULL; +} + +static FILE * +open_ag_proc_pipe(char ** pzBase) +{ + FILE * agFp; + + int pfd[2]; + + if (pipe(pfd) != 0) + fserr(GETDEFS_EXIT_FAILURE, "pipe", "(2)"); + + agPid = fork(); + + switch (agPid) { + case 0: + /* + * We are the child. Close the write end of the pipe + * and force STDIN to become the read end. + */ + close(pfd[1]); + if (dup2(pfd[0], STDIN_FILENO) != 0) + fserr(GETDEFS_EXIT_FAILURE, "dup2", "STDIN_FILENO"); + break; + + case -1: + fserr(GETDEFS_EXIT_FAILURE, "fork", "(2)"); + /* FALLTHROUGH */ /* NOTREACHED */ + + default: + /* + * We are the parent. Close the read end of the pipe + * and get a FILE * pointer for the write file descriptor + */ + close(pfd[0]); + agFp = fdopen(pfd[1], "w" FOPEN_BINARY_FLAG); + if (agFp == (FILE *)NULL) + fserr(GETDEFS_EXIT_FAILURE, "fdopen", "pipe"); + free(*pzBase); + return agFp; + } + + return NULL; +} + +static void +exec_autogen(char ** pzBase) +{ + char const ** paparg; + char const ** pparg; + int argCt = 5; + + /* + * IF we don't have template search directories, + * THEN allocate the default arg counter of pointers and + * set the program name into it. + * ELSE insert each one into the arg list. + */ + if (! HAVE_OPT(AGARG)) { + paparg = pparg = malloc((size_t)argCt * sizeof(char *)); + *pparg++ = pzAutogen; + + } else { + int ct = STACKCT_OPT(AGARG); + char const ** ppz = STACKLST_OPT(AGARG); + + argCt += ct; + paparg = pparg = malloc((size_t)argCt * sizeof(char *)); + *pparg++ = pzAutogen; + + do { + *pparg++ = *ppz++; + } while (--ct > 0); + } + + *pparg++ = *pzBase; + *pparg++ = "--"; + *pparg++ = "-"; + *pparg++ = NULL; + +#ifdef DEBUG + fputc('\n', stderr); + pparg = paparg; + for (;;) { + fputs(*pparg++, stderr); + if (*pparg == NULL) + break; + fputc(' ', stderr); + } + fputc('\n', stderr); + fputc('\n', stderr); +#endif + + execvp(pzAutogen, (char **)VOIDP(paparg)); + die(GETDEFS_EXIT_FAILURE, "exec of %s %s %s %s\n", + paparg[0], paparg[1], paparg[2], paparg[3]); +} + +/* + * startAutogen + */ +static FILE * +startAutogen(void) +{ + char * pz; + FILE * agFp; + char * pzBase = NULL; + + /* + * Compute the base name. + * + * If an argument was specified, use that without question. + * IF a definition pattern is supplied, and it looks like + * a normal name, then use that. + * If neither of these work, then use the current directory name. + */ + if (HAVE_OPT(BASE_NAME)) { + pzBase = malloc(strlen(OPT_ARG(BASE_NAME)) + 3); + strcpy(pzBase, "-b"); + strcpy(pzBase+2, OPT_ARG(BASE_NAME)); + } + else { + /* + * IF we have a definition name pattern, + * THEN copy the leading part that consists of name-like characters. + */ + if (HAVE_OPT(DEFS_TO_GET)) { + char const * pzS = OPT_ARG(DEFS_TO_GET); + pzBase = malloc(strlen(pzS) + 3); + strcpy(pzBase, "-b"); + + pz = pzBase + 2; + while (isalnum(*pzS) || (*pzS == '_')) + *pz++ = *pzS++; + if (pz == pzBase + 2) { + free(pzBase); + pzBase = NULL; + } + else + *pz = NUL; + } + + /* + * IF no pattern or it does not look like a name, ... + */ + if (pzBase == NULL) { + char zSrch[ MAXPATHLEN ]; + if (getcwd(zSrch, sizeof(zSrch)) == NULL) + fserr(GETDEFS_EXIT_FAILURE, "getcwd", "."); + + pz = strrchr(zSrch, '/'); + if (pz == NULL) + pz = zSrch; + else pz++; + pzBase = malloc(strlen(pz) + 3); + strcpy(pzBase, "-b"); + strcpy(pzBase+2, pz); + } + } + + /* + * For our template name, we take the argument (if supplied). + * If not, then whatever we decided our base name was will also + * be our template name. + */ + if (! HAVE_OPT(TEMPLATE)) + SET_OPT_TEMPLATE(strdup(pzBase+2)); + + /* + * Now, what kind of output have we? + * If it is a file, open it up and return. + * If it is an alternate autogen program, + * then set it to whatever the argument said it was. + * If the option was not supplied, we default to + * whatever we set the "pzAutogen" pointer to above. + */ + if (HAVE_OPT(AUTOGEN)) { + agFp = open_ag_file(&pzBase); + if (agFp != NULL) + return agFp; + } + + agFp = open_ag_proc_pipe(&pzBase); + if (agFp != NULL) + return agFp; + + exec_autogen(&pzBase); + return (FILE *)NULL; +} + + +/* + * update_db + */ +static void +update_db(void) +{ + FILE * fp; + + if (chmod(OPT_ARG(ORDERING), 0666) == 0) { + fp = fopen(OPT_ARG(ORDERING), "a" FOPEN_BINARY_FLAG); + + } else { + unlink(OPT_ARG(ORDERING)); + fp = fopen(OPT_ARG(ORDERING), "w" FOPEN_BINARY_FLAG); + pzIndexEOF = pzIndexText; + } + + if (fp == (FILE *)NULL) + fserr(GETDEFS_EXIT_FAILURE, "fopen-w+", OPT_ARG(ORDERING)); + + fwrite(pzIndexEOF, (size_t)(pzEndIndex - pzIndexEOF), (size_t)1, fp); +#ifdef HAVE_FCHMOD + fchmod(fileno(fp), 0444); + fclose(fp); +#else + fclose(fp); + chmod(OPT_ARG(ORDERING), 0444); +#endif +} + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of getdefs/getdefs.c */ diff --git a/getdefs/getdefs.h b/getdefs/getdefs.h new file mode 100644 index 0000000..2c184ff --- /dev/null +++ b/getdefs/getdefs.h @@ -0,0 +1,125 @@ + +/** + * @file getdefs.h + * @group columns + * @{ + */ +/* -*- Mode: C -*- + * + * getdefs Copyright (C) 1999-2018 by Bruce Korb - all rights reserved + * + * Author: Bruce Korb + * + * This file is part of AutoGen. + * AutoGen Copyright (C) 1992-2017 by Bruce Korb - all rights reserved + * + * AutoGen is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AutoGen is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#ifndef GETDEFS_HEADER +#define GETDEFS_HEADER + +#include +#include +#include + +#include REGEX_HEADER +#include "ag-char-map.h" +#include "opts.h" + +#define EXPORT +#define MAXNAMELEN 256 +#define MAX_SUBMATCH 1 +#define COUNT(a) (sizeof(a)/sizeof(a[0])) +#define MARK_CHAR ':' + +#define AG_NAME_CHAR(c) (zUserNameCh[(unsigned char)(c)] & 2) +#define USER_NAME_CH(c) (zUserNameCh[(unsigned char)(c)] & 1) +char zUserNameCh[ 256 ] = { '\0' }; + +/* + * Index database string pointers. + */ +char * pzIndexText = NULL; /* all the text */ +char * pzEndIndex = NULL; /* end of current */ +char * pzIndexEOF = NULL; /* end of file */ +size_t indexAlloc = 0; /* allocation size */ + +/* + * Name of program to process output (normally ``autogen'') + */ +char const * pzAutogen = "autogen"; + +/* + * const global strings + */ +#define DEF_STRING(n,s) char const n[] = s +DEF_STRING( zGlobal, "\n/* GLOBALDEFS */\n" ); +DEF_STRING( zLineId, "\n#line %d \"%s\"\n" ); +DEF_STRING( zMallocErr, "Error: could not allocate %d bytes for %s\n" ); +DEF_STRING( zAttribRe, "\n[^*\n]*\\*[ \t]*([a-z][a-z0-9_-]*):"); +DEF_STRING( zNameTag, " = {\n name = '" ); +DEF_STRING( zMemberLine, " member = " ); +DEF_STRING( zNoData, "error no data for definition in file %s line %d\n" ); +DEF_STRING( zAgDef, "autogen definitions %s;\n"); +DEF_STRING( zDne, + "/* -*- buffer-read-only: t -*- vi: set ro:\n *\n" + " *\n * DO NOT EDIT THIS FILE (%s)\n *\n" + " * It has been extracted by getdefs from the following files:\n" + " *\n" ); + +/* + * ptr to zero (NUL) terminated definition pattern string. + * + * The pattern we look for starts with the three characters + * '/', '*' and '=' and is followed by two names: + * the name of a group and the name of the entry within the group. + * + * The patterns we accept for output may specify a particular group, + * certain members within certain groups or all members of all groups + */ +regex_t define_re; +regex_t attrib_re; + +/* + * The output file pointer. It may be "stdout". + * It gets closed when we are done. + */ +FILE * evtFp = (FILE *)NULL; + +/* + * The output file modification time. Only used if we + * have specified a real file for output (not stdout). + */ +time_t modtime = 0; + +/* + * The array of pointers to the output blocks. + * We build them first, then sort them, then print them out. + */ +char ** papzBlocks = (char **)NULL; +size_t blkUseCt = 0; +size_t blkAllocCt = 0; +pid_t agPid = -1; + +#endif /* GETDEFS_HEADER */ + +/** @} + * + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of getdefs/getdefs.h */ diff --git a/getdefs/opts.def b/getdefs/opts.def new file mode 100644 index 0000000..045e888 --- /dev/null +++ b/getdefs/opts.def @@ -0,0 +1,479 @@ +/* -*- Mode: conf -*- */ + +AutoGen definitions options; +addtogroup = getdefs; + +/* opts.def: option definitons for getdefs + * + * This file is part of AutoGen. + * AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoGen is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AutoGen is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +copyright = { + date = "1999-2018"; + type = gpl; + owner = "Bruce Korb"; + eaddr = 'autogen-users@lists.sourceforge.net'; +}; + +prog-name = "getdefs"; +prog-title = "AutoGen Definition Extraction Tool"; +package = 'GNU AutoGen'; +version = "1.5"; version-type = copyright; +homerc = /dev/null; +no-xlate = anything; +die-code; + +explain = <<- EndExplanation + If no @code{input} argument is provided or is set to simply "-", and if + @code{stdin} is not a @code{tty}, then the list of input files will be + read from @code{stdin}. + EndExplanation; +guard-option-names; + +flag = { + name = def-selection; + documentation; + descrip = 'Specify which definitions are of interest and ' + 'what to say about them'; +}; + +flag = { + name = "defs_to_get"; + arg-type = string; + arg-name = reg-ex; + descrip = 'Regexp to look for after the "/*="'; + doc = <<- _EOF_ + If you want definitions only from a particular category, or even + with names matching particular patterns, then specify this regular + expression for the text that must follow the @code{/*=}. + _EOF_; // */ +}; + +flag = { + name = subblock; + arg-type = string; + arg-name = sub-def; + max = NOLIMIT; + stack_arg; + descrip = "subblock definition names"; + doc = <<- _EOF_ + This option is used to create shorthand entries for nested definitions. + For example, with: + @table @r + @item using subblock thus + @code{--subblock=arg=argname,type,null} + @item and defining an @code{arg} thus + @code{arg: this, char *} + @item will then expand to: + @code{arg = @{ argname = this; type = "char *"; @};} + @end table + The "this, char *" string is separated at the commas, with the + white space removed. You may use characters other than commas by + starting the value string with a punctuation character other than + a single or double quote character. You may also omit intermediate + values by placing the commas next to each other with no intervening + white space. For example, "+mumble++yes+" will expand to: + @* + @code{arg = @{ argname = mumble; null = "yes"; @};}. + _EOF_; +}; + +flag = { + name = listattr; + arg-type = string; + arg-name = def; + max = NOLIMIT; + stack_arg; + descrip = "attribute with list of values"; + doc = <<- _EOF_ + This option is used to create shorthand entries for definitions + that generally appear several times. That is, they tend to be + a list of values. For example, with: + @* + @code{listattr=foo} defined, the text: + @* + @code{foo: this, is, a, multi-list} will then expand to: + @* + @code{foo = 'this', 'is', 'a', 'multi-list';} + @* + The texts are separated by the commas, with the + white space removed. You may use characters other than commas by + starting the value string with a punctuation character other than + a single or double quote character. + _EOF_; +}; + +flag = { + name = enumerating; + documentation; + descrip = 'specify how to number the definitions'; +}; + +flag = { + name = ordering; + arg-type = string; + arg-optional; + arg-name = file-name; + disable = no; + enabled; + descrip = "Alphabetize or use named file"; + doc = <<- _EOF_ + By default, ordering is alphabetical by the entry name. Use, + @code{no-ordering} if order is unimportant. Use @code{ordering} + with no argument to order without case sensitivity. Use + @code{ordering=} if chronological order is important. + getdefs will maintain the text content of @code{file-name}. + @code{file-name} need not exist. + _EOF_; +}; + +flag = { + name = first_index; + arg_type = number; + arg-default = 0; + arg-name = first-index; + descrip = "The first index to apply to groups"; + doc = <<- _EOF_ + By default, the first occurrence of a named definition will have an + index of zero. Sometimes, that needs to be a reserved value. Provide + this option to specify a different starting point. + _EOF_; +}; + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * Definition Insertion Options: + */ +flag = { + name = doc_insert; + descrip = "Definition insertion options"; + documentation; +}; + +flag = { + name = filelist; + arg-type = string; + arg-optional; + arg-name = file; + descrip = "Insert source file names into defs"; + doc = <<- _EOF_ + Inserts the name of each input file into the output definitions. + If no argument is supplied, the format will be: + @example + infile = '%s'; + @end example + If an argument is supplied, that string will be used for the entry + name instead of @var{infile}. + _EOF_; +}; + +flag = { + name = assign; + arg-type = string; + arg-name = ag-def; + max = NOLIMIT; + stack_arg; + descrip = "Global assignments"; + doc = <<- _EOF_ + The argument to each copy of this option will be inserted into + the output definitions, with only a semicolon attached. + _EOF_; + +}; + +flag = { + name = common_assign; + arg-type = string; + arg-name = ag-def; + max = NOLIMIT; + stack_arg; + descrip = "Assignments common to all blocks"; + doc = <<- _EOF_ + The argument to each copy of this option will be inserted into + each output definition, with only a semicolon attached. + _EOF_; + +}; + +flag = { + name = copy; + arg-type = string; + arg-name = file; + max = NOLIMIT; + stack_arg; + descrip = "File(s) to copy into definitions"; + doc = <<- _EOF_ + The content of each file named by these options will be inserted into + the output definitions. + _EOF_; + +}; + +flag = { + name = srcfile; + arg-type = string; + arg-optional; + arg-name = file; + descrip = "Insert source file name into each def"; + doc = <<- _EOF_ + Inserts the name of the input file where a definition was found + into the output definition. + If no argument is supplied, the format will be: + @example + srcfile = '%s'; + @end example + If an argument is supplied, that string will be used for the entry + name instead of @var{srcfile}. + _EOF_; + +}; + +flag = { + name = linenum; + arg-type = string; + arg-optional; + arg-name = def-name; + descrip = "Insert source line number into each def"; + doc = <<- _EOF_ + Inserts the line number in the input file where a definition + was found into the output definition. + If no argument is supplied, the format will be: + @example + linenum = '%s'; + @end example + If an argument is supplied, that string will be used for the entry + name instead of @var{linenum}. + _EOF_; + +}; + +flag = { + name = input-files; + documentation; + descrip = 'specify which files to search for markers'; +}; + +flag = { + name = input; + arg-type = string; + arg-name = src-file; + max = NOLIMIT; + settable; + stack_arg; + default; + descrip = "Input file to search for defs"; + + doc = <<- _EOF_ + All files that are to be searched for definitions must be named on + the command line or read from @code{stdin}. If there is only one + @code{input} option and it is the string, "-", then the input file + list is read from @code{stdin}. If a command line argument is not + an option name and does not contain an assignment operator + (@code{=}), then it defaults to being an input file name. + At least one input file must be specified. + _EOF_; +}; + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * Definition Output Disposition Options: + */ +flag = { + name = doc_output; + descrip = "Definition output disposition options:"; + documentation; +}; + +flag = { + name = output; + equivalence = "autogen"; + arg-type = string; + arg-name = file; + descrip = "Output file to open"; + doc = <<- _EOF_ + If you are not sending the output to an AutoGen process, + you may name an output file instead. + _EOF_; + +}; + +flag = { + name = "autogen"; + equivalence = "autogen"; + arg-type = string; + arg-optional; + arg-name = ag-cmd; + disable = "no"; + enabled; + descrip = "Invoke AutoGen with defs"; + doc = <<- _EOF_ + This is the default output mode. Specifying @code{no-autogen} is + equivalent to @code{output=-}. If you supply an argument to this + option, that program will be started as if it were AutoGen and + its standard in will be set to the output definitions of this program. + _EOF_; + +}; + +flag = { + name = template; + arg-type = string; + arg-name = file; + settable; + descrip = "Template Name"; + doc = + "Specifies the template name to be used for generating the final output."; +}; + +flag = { + name = agarg; + arg-type = string; + arg-name = ag-opt; + max = NOLIMIT; + stack_arg; + descrip = "AutoGen Argument"; + flags_cant = output; + doc = <<- _EOF_ + This is a pass-through argument. It allows you to specify any + arbitrary argument to be passed to AutoGen. + _EOF_; + +}; + +flag = { + name = base_name; + arg-type = string; + arg-name = name; + descrip = "Base name for output file(s)"; + flags_cant = output; + doc = <<- _EOF_ + When output is going to AutoGen, a base name must either be supplied + or derived. If this option is not supplied, then it is taken from + the @code{template} option. If that is not provided either, then + it is set to the base name of the current directory. + _EOF_; + +}; + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * Program Documentation + */ + +exit-name[2] = invalid-input; +exit-desc[2] = 'An input file was specified that is not a file'; + +exit-name[3] = no-mem; +exit-desc[3] = 'Insufficient memory for operation'; + +/* * * * * MAN PAGE DESCRIPTION * * * * * * * * * * * * * * * * * * * */ + +doc-section = { + ds-type = "SEE ALSO"; + ds-format = texi; + ds-text = <<- _EndOfMan_ + This program is documented more fully in the Getdefs section + of the Add-On chapter in the @code{AutoGen} Info system documentation. + _EndOfMan_; +}; + +/* * * * * DOC DESCRIPTION * * * * * * * * * * * * * * * * * * * */ + +option-doc-format = texi; + +detail = <<- _EOF_ + This program extracts AutoGen definitions from a list of source files. + Definitions are delimited by @code{/*= \n} and + @code{=*/\n}. + _EOF_; + +prog-descrip = <<_EOF_ +This program extracts AutoGen definitions from a list of source files. +Definitions are delimited by @code{/*= \n} and +@code{=*/\n}. From that, this program creates a definition of the following +form: + +@example + #line nnn "source-file-name" + entry_type = @{ + name = entry_name; + ... + @}; +@end example + +@enumerate +@item +The ellipsis @code{...} is filled in by text found between the two +delimiters. Each line of text is stripped of anything before the first +asterisk, then leading asterisks, then any leading or trailing white space. + +@item +If what is left starts with what looks like a name followed by a colon, then +it is interpreted as a name followed by a value. + +@item +If the first character of the value is either a single or double quote, then +you are responsible for quoting the text as it gets inserted into the output +definitions. So, if you want whitespace at the beginnings of the lines of +text, you must do something like this: + +@example + * mumble: + * " this is some\n" + * " indented text." +@end example + +@item +If the @code{} is followed by a comma, the word @code{ifdef} (or +@code{ifndef}) and a name @code{if_name}, then the above entry will be under +@code{ifdef} control. + +@example +/*=group entry_name, ifdef FOO + * attr: attribute value +=*/ +@end example + +Will produce the following: + +@example +#ifdef FOO +#line nnn "source-file-name" +group = @{ + name = entry_name; + attr = 'attribute value'; +@}; +#endif +@end example + +@item +If you use of the @code{subblock} option, you can specify a nested +value, @xref{getdefs subblock}. That is, this text: + +@example + * arg: int, this, what-it-is +@end example + +with the @code{--subblock=arg=type,name,doc} option would yield: + +@example +arg = @{ type = int; name = this; doc = what-it-is; @}; +@end example +@end enumerate +_EOF_; + +/* end of opts.def */ diff --git a/getdefs/proto.h b/getdefs/proto.h new file mode 100644 index 0000000..1c8505b --- /dev/null +++ b/getdefs/proto.h @@ -0,0 +1,85 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * Prototypes for getdefs + * Generated Sun Aug 26 10:44:48 PDT 2018 + */ +#ifndef GETDEFS_PROTO_H_GUARD +#define GETDEFS_PROTO_H_GUARD 1 + + +/* + * Static declarations from gdemit.c + */ +static void +compress_def(char * pz); + +static char * +list_attrib(char * pzText, char * pzOut); + +static char * +emit_quote(char ** ppzText, char * pzOut); + +static void +next_def_entry(char ** txt_pp, char const ** def_pp); + +static void +emit_attribute(char const ** def_pp, char ** out_pp); + +static char * +emit_subblock(char const * pzDefList, char * pzText, char * pzOut); + +static char * +subblock_str(char ** ppzText, uint_t sepChar, char * pzOut); + +/* + * Static declarations from getdefs.c + */ +static char * +assignIndex(char * pzOut, char * pzDef); + +static int +awaitAutogen(void); + +static void +buildDefinition(char * pzDef, char const * pzFile, int line, char * pzOut); + +static tSuccess +buildPreamble(char ** ppzDef, char ** ppzOut, char const * fname, int line); + +static int +compar_defname(const void * p1, const void * p2); + +static int +compar_text(const void * p1, const void * p2); + +static void +doPreamble(FILE * outFp); + +static char * +loadFile(char const * pzFname); + +static void +printEntries(FILE * fp); + +static void +processFile(char const * fname); + +static void +set_first_idx(void); + +static FILE * +open_ag_file(char ** pzBase); + +static FILE * +open_ag_proc_pipe(char ** pzBase); + +static void +exec_autogen(char ** pzBase); + +static FILE * +startAutogen(void); + +static void +update_db(void); + +#endif /* GETDEFS_PROTO_H_GUARD */ diff --git a/getdefs/test/Makefile.am b/getdefs/test/Makefile.am new file mode 100644 index 0000000..cceea6d --- /dev/null +++ b/getdefs/test/Makefile.am @@ -0,0 +1,47 @@ +## -*- Mode: Makefile -*- +## +## Makefile.am -- process this file with automake to produce Makefile.in +## +## Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . + +TESTS = cfg.test index.test option.test subblock.test +EXTRA_DIST = defs $(TESTS) + +TESTS_ENVIRONMENT = top_srcdir=$(top_srcdir) \ + srcdir=$(srcdir) top_builddir=$(top_builddir) \ + GDexe=$(GDexe) AGexe=$(AGexe) CLexe=$(CLexe) + +distclean-local: + -rm -rf *-testd FAILURES defs + +$(TESTS) : defs + +defs : ${top_builddir}/autoopts/test/defs + $(TESTS_ENVIRONMENT) $(SHELL) \ + $(top_srcdir)/config/install-defs.sh \ + $(top_builddir)/autoopts/test/defs + +${top_builddir}/autoopts/test/defs : + cd ${top_builddir}/autoopts/test ; $(MAKE) defs + +verbose : defs + rm -rf FAILURES *-testd ; \ + VERBOSE=true $(MAKE) check TESTS="$(TESTS)" + +# end of Makefile.am diff --git a/getdefs/test/Makefile.in b/getdefs/test/Makefile.in new file mode 100644 index 0000000..e9c1948 --- /dev/null +++ b/getdefs/test/Makefile.in @@ -0,0 +1,894 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 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. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = getdefs/test +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/ag_macros.m4 \ + $(top_srcdir)/config/asm-underscore.m4 \ + $(top_srcdir)/config/extensions.m4 \ + $(top_srcdir)/config/guile.m4 \ + $(top_srcdir)/config/host-cpu-c-abi.m4 \ + $(top_srcdir)/config/lib-ld.m4 \ + $(top_srcdir)/config/lib-link.m4 \ + $(top_srcdir)/config/lib-prefix.m4 \ + $(top_srcdir)/config/libopts.m4 \ + $(top_srcdir)/config/libtool.m4 \ + $(top_srcdir)/config/ltoptions.m4 \ + $(top_srcdir)/config/ltsugar.m4 \ + $(top_srcdir)/config/ltversion.m4 \ + $(top_srcdir)/config/lt~obsolete.m4 \ + $(top_srcdir)/config/onceonly.m4 $(top_srcdir)/config/pkg.m4 \ + $(top_srcdir)/config/snprintfv.m4 \ + $(top_srcdir)/config/stdnoreturn.m4 \ + $(top_srcdir)/config/unlocked-io.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red=''; \ + grn=''; \ + lgn=''; \ + blu=''; \ + mgn=''; \ + brg=''; \ + std=''; \ + fi; \ +} +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__recheck_rx = ^[ ]*:recheck:[ ]* +am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* +am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* +# A command that, given a newline-separated list of test names on the +# standard input, print the name of the tests that are to be re-run +# upon "make recheck". +am__list_recheck_tests = $(AWK) '{ \ + recheck = 1; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + { \ + if ((getline line2 < ($$0 ".log")) < 0) \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ + { \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ + { \ + break; \ + } \ + }; \ + if (recheck) \ + print $$0; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# A command that, given a newline-separated list of test names on the +# standard input, create the global log from their .trs and .log files. +am__create_global_log = $(AWK) ' \ +function fatal(msg) \ +{ \ + print "fatal: making $@: " msg | "cat >&2"; \ + exit 1; \ +} \ +function rst_section(header) \ +{ \ + print header; \ + len = length(header); \ + for (i = 1; i <= len; i = i + 1) \ + printf "="; \ + printf "\n\n"; \ +} \ +{ \ + copy_in_global_log = 1; \ + global_test_result = "RUN"; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".trs"); \ + if (line ~ /$(am__global_test_result_rx)/) \ + { \ + sub("$(am__global_test_result_rx)", "", line); \ + sub("[ ]*$$", "", line); \ + global_test_result = line; \ + } \ + else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ + copy_in_global_log = 0; \ + }; \ + if (copy_in_global_log) \ + { \ + rst_section(global_test_result ": " $$0); \ + while ((rc = (getline line < ($$0 ".log"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".log"); \ + print line; \ + }; \ + printf "\n"; \ + }; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# Restructured Text title. +am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } +# Solaris 10 'make', and several other traditional 'make' implementations, +# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it +# by disabling -e (using the XSI extension "set +e") if it's set. +am__sh_e_setup = case $$- in *e*) set +e;; esac +# Default flags passed to test drivers. +am__common_driver_flags = \ + --color-tests "$$am__color_tests" \ + --enable-hard-errors "$$am__enable_hard_errors" \ + --expect-failure "$$am__expect_failure" +# To be inserted before the command running the test. Creates the +# directory for the log if needed. Stores in $dir the directory +# containing $f, in $tst the test, in $log the log. Executes the +# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and +# passes TESTS_ENVIRONMENT. Set up options for the wrapper that +# will run the test scripts (or their associated LOG_COMPILER, if +# thy have one). +am__check_pre = \ +$(am__sh_e_setup); \ +$(am__vpath_adj_setup) $(am__vpath_adj) \ +$(am__tty_colors); \ +srcdir=$(srcdir); export srcdir; \ +case "$@" in \ + */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ + *) am__odir=.;; \ +esac; \ +test "x$$am__odir" = x"." || test -d "$$am__odir" \ + || $(MKDIR_P) "$$am__odir" || exit $$?; \ +if test -f "./$$f"; then dir=./; \ +elif test -f "$$f"; then dir=; \ +else dir="$(srcdir)/"; fi; \ +tst=$$dir$$f; log='$@'; \ +if test -n '$(DISABLE_HARD_ERRORS)'; then \ + am__enable_hard_errors=no; \ +else \ + am__enable_hard_errors=yes; \ +fi; \ +case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ + am__expect_failure=yes;; \ + *) \ + am__expect_failure=no;; \ +esac; \ +$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) +# A shell command to get the names of the tests scripts with any registered +# extension removed (i.e., equivalently, the names of the test logs, with +# the '.log' extension removed). The result is saved in the shell variable +# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, +# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", +# since that might cause problem with VPATH rewrites for suffix-less tests. +# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. +am__set_TESTS_bases = \ + bases='$(TEST_LOGS)'; \ + bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ + bases=`echo $$bases` +RECHECK_LOGS = $(TEST_LOGS) +AM_RECURSIVE_TARGETS = check recheck +TEST_SUITE_LOG = test-suite.log +TEST_EXTENSIONS = @EXEEXT@ .test +am__test_logs1 = $(TESTS:=.log) +am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) +TEST_LOGS = $(am__test_logs2:.test.log=.log) +TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/config/test-driver +TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ + $(TEST_LOG_FLAGS) +am__set_b = \ + case '$@' in \ + */*) \ + case '$*' in \ + */*) b='$*';; \ + *) b=`echo '$@' | sed 's/\.log$$//'`; \ + esac;; \ + *) \ + b='$*';; \ + esac +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/config/test-driver +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AGEN5_TESTS = @AGEN5_TESTS@ +AG_LDFLAGS = @AG_LDFLAGS@ +AG_MAJOR_VERSION = @AG_MAJOR_VERSION@ +AG_MINOR_VERSION = @AG_MINOR_VERSION@ +AG_STATIC_AUTOGEN = @AG_STATIC_AUTOGEN@ +AG_TIMEOUT = @AG_TIMEOUT@ +AG_VERSION = @AG_VERSION@ +AG_XML2 = @AG_XML2@ +AGexe = @AGexe@ +AGnam = @AGnam@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AO_AGE = @AO_AGE@ +AO_CURRENT = @AO_CURRENT@ +AO_REVISION = @AO_REVISION@ +AO_TEMPLATE_VERSION = @AO_TEMPLATE_VERSION@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLexe = @CLexe@ +CLnam = @CLnam@ +CONFIG_SHELL = @CONFIG_SHELL@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBUG_ENABLED = @DEBUG_ENABLED@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +DYNAMIC_AG = @DYNAMIC_AG@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_STATIC = @ENABLE_STATIC@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GDexe = @GDexe@ +GDnam = @GDnam@ +GO_AGE = @GO_AGE@ +GO_CURRENT = @GO_CURRENT@ +GO_REVISION = @GO_REVISION@ +GREP = @GREP@ +GUILE_CFLAGS = @GUILE_CFLAGS@ +GUILE_EFFECTIVE_VERSION = @GUILE_EFFECTIVE_VERSION@ +GUILE_LDFLAGS = @GUILE_LDFLAGS@ +GUILE_LIBS = @GUILE_LIBS@ +GUILE_LTLIBS = @GUILE_LTLIBS@ +HOST_CPU = @HOST_CPU@ +HOST_CPU_C_ABI = @HOST_CPU_C_ABI@ +INCLIST = @INCLIST@ +INCSNPRINTFV = @INCSNPRINTFV@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSNPRINTFV = @LIBSNPRINTFV@ +LIBTOOL = @LIBTOOL@ +LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ +LIBXML2_LIBS = @LIBXML2_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +M4_SRC = @M4_SRC@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPTS_TESTDIR = @OPTS_TESTDIR@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSIX_SHELL = @POSIX_SHELL@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STDNORETURN_H = @STDNORETURN_H@ +STRIP = @STRIP@ +TEXI2HTML = @TEXI2HTML@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_aux_dir = @ac_aux_dir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +TESTS = cfg.test index.test option.test subblock.test +EXTRA_DIST = defs $(TESTS) +TESTS_ENVIRONMENT = top_srcdir=$(top_srcdir) \ + srcdir=$(srcdir) top_builddir=$(top_builddir) \ + GDexe=$(GDexe) AGexe=$(AGexe) CLexe=$(CLexe) + +all: all-am + +.SUFFIXES: +.SUFFIXES: .log .test .test$(EXEEXT) .trs +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu getdefs/test/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu getdefs/test/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: + + +# Recover from deleted '.trs' file; this should ensure that +# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create +# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells +# to avoid problems with "make -n". +.log.trs: + rm -f $< $@ + $(MAKE) $(AM_MAKEFLAGS) $< + +# Leading 'am--fnord' is there to ensure the list of targets does not +# expand to empty, as could happen e.g. with make check TESTS=''. +am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) +am--force-recheck: + @: + +$(TEST_SUITE_LOG): $(TEST_LOGS) + @$(am__set_TESTS_bases); \ + am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ + redo_bases=`for i in $$bases; do \ + am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ + done`; \ + if test -n "$$redo_bases"; then \ + redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ + redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ + if $(am__make_dryrun); then :; else \ + rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ + fi; \ + fi; \ + if test -n "$$am__remaking_logs"; then \ + echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ + "recursion detected" >&2; \ + elif test -n "$$redo_logs"; then \ + am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ + fi; \ + if $(am__make_dryrun); then :; else \ + st=0; \ + errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ + for i in $$redo_bases; do \ + test -f $$i.trs && test -r $$i.trs \ + || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ + test -f $$i.log && test -r $$i.log \ + || { echo "$$errmsg $$i.log" >&2; st=1; }; \ + done; \ + test $$st -eq 0 || exit 1; \ + fi + @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ + ws='[ ]'; \ + results=`for b in $$bases; do echo $$b.trs; done`; \ + test -n "$$results" || results=/dev/null; \ + all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ + pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ + fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ + skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ + xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ + xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ + error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ + if test `expr $$fail + $$xpass + $$error` -eq 0; then \ + success=true; \ + else \ + success=false; \ + fi; \ + br='==================='; br=$$br$$br$$br$$br; \ + result_count () \ + { \ + if test x"$$1" = x"--maybe-color"; then \ + maybe_colorize=yes; \ + elif test x"$$1" = x"--no-color"; then \ + maybe_colorize=no; \ + else \ + echo "$@: invalid 'result_count' usage" >&2; exit 4; \ + fi; \ + shift; \ + desc=$$1 count=$$2; \ + if test $$maybe_colorize = yes && test $$count -gt 0; then \ + color_start=$$3 color_end=$$std; \ + else \ + color_start= color_end=; \ + fi; \ + echo "$${color_start}# $$desc $$count$${color_end}"; \ + }; \ + create_testsuite_report () \ + { \ + result_count $$1 "TOTAL:" $$all "$$brg"; \ + result_count $$1 "PASS: " $$pass "$$grn"; \ + result_count $$1 "SKIP: " $$skip "$$blu"; \ + result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ + result_count $$1 "FAIL: " $$fail "$$red"; \ + result_count $$1 "XPASS:" $$xpass "$$red"; \ + result_count $$1 "ERROR:" $$error "$$mgn"; \ + }; \ + { \ + echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ + $(am__rst_title); \ + create_testsuite_report --no-color; \ + echo; \ + echo ".. contents:: :depth: 2"; \ + echo; \ + for b in $$bases; do echo $$b; done \ + | $(am__create_global_log); \ + } >$(TEST_SUITE_LOG).tmp || exit 1; \ + mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ + if $$success; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ + fi; \ + echo "$${col}$$br$${std}"; \ + echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ + echo "$${col}$$br$${std}"; \ + create_testsuite_report --maybe-color; \ + echo "$$col$$br$$std"; \ + if $$success; then :; else \ + echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ + if test -n "$(PACKAGE_BUGREPORT)"; then \ + echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ + fi; \ + echo "$$col$$br$$std"; \ + fi; \ + $$success || exit 1 + +check-TESTS: + @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list + @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + trs_list=`for i in $$bases; do echo $$i.trs; done`; \ + log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ + exit $$?; +recheck: all + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + bases=`for i in $$bases; do echo $$i; done \ + | $(am__list_recheck_tests)` || exit 1; \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + log_list=`echo $$log_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ + am__force_recheck=am--force-recheck \ + TEST_LOGS="$$log_list"; \ + exit $$? +.test.log: + @p='$<'; \ + $(am__set_b); \ + $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +@am__EXEEXT_TRUE@.test$(EXEEXT).log: +@am__EXEEXT_TRUE@ @p='$<'; \ +@am__EXEEXT_TRUE@ $(am__set_b); \ +@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ +@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ +@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ +@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) + -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) + -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-local + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: check-am install-am install-strip + +.PHONY: all all-am check check-TESTS check-am clean clean-generic \ + clean-libtool cscopelist-am ctags-am distclean \ + distclean-generic distclean-libtool distclean-local distdir \ + dvi dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am recheck tags-am \ + uninstall uninstall-am + +.PRECIOUS: Makefile + + +distclean-local: + -rm -rf *-testd FAILURES defs + +$(TESTS) : defs + +defs : ${top_builddir}/autoopts/test/defs + $(TESTS_ENVIRONMENT) $(SHELL) \ + $(top_srcdir)/config/install-defs.sh \ + $(top_builddir)/autoopts/test/defs + +${top_builddir}/autoopts/test/defs : + cd ${top_builddir}/autoopts/test ; $(MAKE) defs + +verbose : defs + rm -rf FAILURES *-testd ; \ + VERBOSE=true $(MAKE) check TESTS="$(TESTS)" + +# end of Makefile.am + +# 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/getdefs/test/cfg.test b/getdefs/test/cfg.test new file mode 100755 index 0000000..932bceb --- /dev/null +++ b/getdefs/test/cfg.test @@ -0,0 +1,108 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# cfg.test --- test config file processing +# +# Author: Bruce Korb +# +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . + +. ./defs + +# Create the files we need in the test environment +cat > ${testname}.c <<- _EOSource_ + + /*=* global + * + * test: subblock + * doc: we want to see + * just what happens + =*/ + + /*=gfunc in_p + * + * exparg: test-string , string to look for + + arg-name + arg-desc + arg-opt + arg-list + + * exparg: @ string-list @ list of strings to check,, @@ list + * + * opt: 1 + * doc: + * Return SCM_BOOL_T if the first argument is duplicated + * in the second (list) argument. + =*/ + SCM + ag_scm_in_p( SCM obj, SCM list ) + { + } + _EOSource_ + +cat > ${testname}.cfg <<- _EOCfg_ + output ${testname}.out + common-assign stumble = grumble + assign mumble = stumble ; mumble = grumble + template test${testname} + subblock exparg=arg_name,arg_desc,arg_optional,arg_list + _EOCfg_ + +cat > ${testname}.test <<- _EOTestOut_ + /* -*- buffer-read-only: t -*- vi: set ro: + * + * + * DO NOT EDIT THIS FILE (cfg.out) + * + * It has been extracted by getdefs from the following files: + * + * cfg.c + */ + autogen definitions testcfg; + mumble = stumble ; mumble = grumble; + + + /* GLOBALDEFS */ + + #line 2 "cfg.c" + test = 'subblock'; + doc = 'we want to see + just what happens'; + + + #line 9 "cfg.c" + gfunc = { + name = 'in_p'; + exparg = { + arg_name = 'test-string'; + arg_desc = 'string to look for'; + }; + exparg = { + arg_name = 'string-list'; + arg_desc = 'list of strings to check,,'; + arg_list = 'list'; + }; + opt = '1'; + doc = + 'Return SCM_BOOL_T if the first argument is duplicated + in the second (list) argument.'; + stumble = grumble; + }; + _EOTestOut_ + +set -x +${GDexe} load=${testname}.cfg ${testname}.c || \ + failure running ${GDexe} +cmp -s ${testname}.test ${testname}.out || \ + failure "`diff ${testname}.test ${testname}.out`" + +# end of cfg.test diff --git a/getdefs/test/defs b/getdefs/test/defs new file mode 100644 index 0000000..5057fac --- /dev/null +++ b/getdefs/test/defs @@ -0,0 +1,392 @@ +#! /bin/echo this_file_should_be_sourced,_not_executed +# -*- Mode: Shell-script -*- +# +# defs --- define the environment for autogen tests. +# +# Author: Bruce Korb +# +## This file is part of AutoOpts, a companion to AutoGen. +## AutoOpts is free software. +## AutoOpts is Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoOpts is available under any one of two licenses. The license +## in use must be one of these two and the choice is under the control +## of the user of the license. +## +## The GNU Lesser General Public License, version 3 or later +## See the files "COPYING.lgplv3" and "COPYING.gplv3" +## +## The Modified Berkeley Software Distribution License +## See the file "COPYING.mbsd" +## +## These files have the following sha256 sums: +## +## 8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95 COPYING.gplv3 +## 4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b COPYING.lgplv3 +## 13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239 COPYING.mbsd + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# C O N F I G U R E D V A L U E S +# +# Make sure srcdir is an absolute path. Supply the variable +# if it does not exist. We want to be able to run the tests +# stand-alone!! +# +cfg_vals() +{ + case `uname -s` in + SunOS ) + if test "X$BASH_VERSION" = X + then + # On Solaris, make certain we do not use /bin/sh + sh=`which bash` + test "X$sh" = X && sh=/usr/xpg4/bin/sh + BASH_VERSION=not-good-enough + export BASH_VERSION + exec $sh "$0" "$@" + fi + ;; + esac + + set -a + TESTS='' + builddir=`pwd` + progpid=$$ + : ${top_builddir=/u/bkorb/tools/ag/autogen-bld} + top_builddir=`cd ${top_builddir} >/dev/null ; pwd` + : ${top_srcdir=/u/bkorb/tools/ag/autogen-bld} + top_srcdir=`cd ${top_srcdir} >/dev/null ; pwd` + : ${srcdir=/u/bkorb/tools/ag/autogen-bld/getdefs/test} + srcdir=`cd $srcdir >/dev/null && pwd` + . ${top_builddir}/config/shdefs "${builddir}/` + echo $0|${SED:-sed} 's@.*/@@'`" + progname=`echo "$1" | ${SED} 's,^.*/,,'` + testname=`echo "$progname" | ${SED} 's,\..*$,,'` + testsubdir=${testname}-testd + tstdir=${builddir}/${testsubdir} + PS4=">${testname}-\${FUNCNAME}> " + test_name=`echo ${testname} | ${SED} 's/-/_/g'` + ( exec 2>/dev/null; ulimit -c unlimited ) && \ + ulimit -c unlimited + + CFLAGS="${CFLAGS} ${DEFS}" + : ${PAGER=more} + + stdopts=${top_srcdir}/autoopts/test/stdopts.def + test_main=yes + use_flags=true + sed_omit_license="/-\*- buffer-read-only:/,/^ \*\//d" + TERM='' + set +a + + ( + test_local() { + local local_works=yes + } + test_local + ) || eval 'local() { : ; }' + + vars=`set | ${SED} -n '/^\(LANG\|LC_[A-Z_]*\)=/s/=.*//p'` 2>/dev/null + unset AUTOOPTS_USAGE $vars CONTENT_LENGTH REQUEST_METHOD QUERY_STRING +} + +# If only the "rm(1)" command could be relied upon.... +# +purge() +{ + rm -rf ${*} 2>/dev/null + bad='' + for f + do test -f ${f} -o -d ${f} && bad="${bad} ${f}" + done + test -z "$bad" && return 0 + + # NFS "busy" files and MS-DOS fs sometimes fail. + # + set -- $bad + test "x${RANDOM}" = "x${RANDOM}" && RANDOM=`expr 0${RANDOM} + 1 2>/dev/null` + + f=zzPURGE-${1}-${RANDOM}-${progpid} + if test $# -gt 1 + then mkdir "${f}" + mv $* "${f}/." + else mv $1 "${f}" + fi +} + +init_tests() +{ + exec 8>&2 + BASH_XTRACEFD=8 + + TMPDIR="${tstdir}/${testname}-tmpd" + mkdir -p ${TMPDIR} + CFLAGS=`echo ${CFLAGS} | \ + ${SED} "s/-Werror[^ ${ht}]*//g;s/-Wextra//g"` + + lo_dir=${top_builddir}/autoopts + lo_lib=`find ${lo_dir} -type f -name "*libopts.${OBJEXT}" | head -n1` + test -f "$lo_lib" || { + lo_lib=`find ${lo_dir} -type f -name "*libopts.lo" | head -n1` + test -f "$lo_lib" || die "no libopts lib" + } + lo_dir=${lo_lib%/*} + test "X${LD_LIBRARY_PATH}" = X || \ + LD_LIBRARY_PATH=:${LD_LIBRARY_PATH} + LD_LIBRARY_PATH=${lo_dir}:${LIBGUILE_PATH}${LD_LIBRARY_PATH} + + case ${AG_VERSION} in + *pre* ) GUILE_WARN_DEPRECATED=detailed ;; + * ) GUILE_WARN_DEPRECATED=no ;; + esac + + case "$LIB" in + *-lgen* ) : ;; + * ) + for f in /usr/lib*/libgen.so /lib*/libgen.so + do + test -f $f && { + LIB="${LIB} -lgen" + break + } + done + ;; + esac + LIB="${lo_lib} ${LIB}" + + AG_L=run_ag\ ao + agl_opts="-L${top_builddir}/autoopts/tpl" + test "L${top_builddir}" = "L${top_srcdir}" || \ + agl_opts="$agl_opts -L${top_srcdir}/autoopts/tpl" + export TMPDIR PATH LD_LIBRARY_PATH \ + GUILE_WARN_DEPRECATED LIB AG_L agl_opts \ + CC LIBGUILE AG_VERSION +} + +be_silent() +{ + setx=: + msg=echo + VERBOSE=false + purge ${testsubdir} + + run_ag() + { + local opts= + opts='' + shift + + case " $* " in + *' -L'* ) : ;; + * ) opts="${agl_opts}" ;; + esac + + ${AGexe} ${opts} "$@" + } + + init_tests +} + +be_verbose() +{ + set -x + setx='set -x' + msg=: + VERBOSE=true + test -d ${testsubdir} || mkdir ${testsubdir} || exit 1 + + run_ag() + { + local opts= tfile=${testname}-aglog-${1}-${progpid}.log + ${verb_ok:-true} && { + case " $* " in + *' --trace'* ) : ;; + * ) + opts="--trace=every --trace-out=>>${tfile}" + ;; + esac + AUTOGEN_TRACE=every + AUTOGEN_TRACE_OUT=">>`pwd`/${tfile}" + export AUTOGEN_TRACE_OUT AUTOGEN_TRACE + } + shift + + case " $* " in + *' -L'* ) : ;; + * ) opts="${opts} ${agl_opts}" ;; + esac + + MALLOC_CHECK_=3 ${AGexe} ${opts} "$@" + } + + init_tests +} + +cfg_inc() +{ + test_src=$srcdir/${testname}.test + cd ${testsubdir} || { + echo "Cannot make or change into ${testsubdir}" + exit 1 + } + + dirs=` + for f in ${top_builddir} ${top_srcdir} + do + for d in . autoopts agen5 + do + cd $f/$d + pwd >&9 + cd - + done 9>&1 1>/dev/null + done | sort -u | ${SED} 's/^/-I/'` + + INC=`echo ${dirs} ${CPPFLAGS}` + + : "=== Running $progname for ${testname} using ${SHELL} ===" + chmod +w * > /dev/null 2>&1 || : + ${VERBOSE} && SHELLX="${SHELL} -x" || SHELLX="${SHELL}" +} + +# # # # +# +# "clean_help" -- remove variable parts so results can be compared +# +nl=' +' +ht=' ' +basic_help_clean="/^Packaged by/d +/^Report .* bugs to/d +/[Pp]lease send bug reports/d +/^exit [0-9]/d +/^[ ${ht}]*\$/d" +TR=`command -v tr` +test -x "$TR" || die "cannot run tests without 'tr' program" + +export nl ht basic_help_clean TR +readonly nl ht basic_help_clean TR + +clean_help() { + test -z "$sedcmd" && \ + s=${basic_help_clean} || \ + s="${sedcmd}${nl}${basic_help_clean}" + + ${SED} "${s}" ${1+"$@"} +} + +compile() +{ + ${setx} + test "X${Csrc}" = "X" && Csrc="${testname}" + test "X${Cexe}" = "X" && Cexe="${Csrc}" + test "X${Dnam}" = "X" && Dnam="${testname}" + + d=`echo TEST_TEST_${Dnam}_OPTS | ${TR} '[a-z]-' '[A-Z]_'` + cc_cmd="${CC} ${CFLAGS} -D$d ${INC} -o ${Cexe} ${Csrc}.c ${LIB}" + eval ${cc_cmd} || \ + failure cannot compile ${Csrc}.c + if test $# -gt 0 + then + ( set +xe + exec 2>&1 + ./${Cexe} ${*} ${dosed} + ) || failure cannot obtain help output for ${Csrc} + fi > ${Cexe}.RAW-HELP + clean_help ${Cexe}.RAW-HELP > ${Csrc}.help + Csrc='' Cexe='' Dnam='' +} + +cleanup() +{ + kill -9 $THUMPER_PID + trap '' 15 + ${setx} + ${VERBOSE} || { + cd ${builddir} + purge ${testsubdir} + } + ${msg} ${testname} done + exit 0 +} + +# A standard failure function +# +failure() +{ + kill -9 $THUMPER_PID + trap '' 15 + set -x + cd ${tstdir}/.. + if test -d FAILURES + then test -d "FAILURES/${testsubdir}" && \ + purge "FAILURES/${testsubdir}" + else mkdir FAILURES + fi + + mv "${testsubdir}" "FAILURES/${testsubdir}" + test -f "${testname}.log" && { + mv "${testname}.log" "FAILURES/${testsubdir}/amtest-${testname}.log" + ln -s "FAILURES/${testsubdir}/amtest-${testname}.log" "${testname}.log" + } + echo FAILURE: "$*" + exit 1 +} + +thumper() +{ + exec > /dev/null 2>&1 /dev/null ; pwd` + cd / + rpid=${progpid} + test -z "${kill_delay}" && kill_delay=3 + kill_delay=`expr $kill_delay '*' $AG_TIMEOUT` + while test ${kill_delay} -gt 0 + do sleep 1 + ps -p ${rpid} || exit 0 + kill_delay=`expr $kill_delay - 1` + done + kill -15 ${rpid} + sleep 1 + ps -p ${rpid} || exit + test -d "$bdir" && { + test -d ${bdir}/FAILURES || \ + mkdir ${bdir}/FAILURES + mv -f "${tstdir}" "${bdir}/FAILURES/." + } + kill -9 ${rpid} +} + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +cfg_vals $0 + +case "${VERBOSE}" in +'' | [Nn]* | 0 | [Ff]* ) + be_silent ;; + +[Yy]* | [0-9] | [Tt]* ) + be_verbose ;; + +* ) + case "$-" in + *x* ) be_verbose ;; + * ) be_silent ;; + esac +esac + +thumper & +THUMPER_PID=$! +cfg_inc + +trap "failure 'test ${testname} killed on timeout'" 15 + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +# defs.in ends here diff --git a/getdefs/test/index.test b/getdefs/test/index.test new file mode 100755 index 0000000..c382b9e --- /dev/null +++ b/getdefs/test/index.test @@ -0,0 +1,122 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# +# index.test --- test the subblock parameter to getdefs +# +# Author: Bruce Korb +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . + +# Common definitions + +. ./defs + +# Create the files we need in the test environment +cat > ${testname}.c < ${testname}.test <<_EOF_ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * + * DO NOT EDIT THIS FILE (index.out) + * + * It has been extracted by getdefs from the following files: + * + * index.c + */ +autogen definitions index-testd; + +#line 14 "index.c" +gfunc[2] = { + name = 'in_p'; + exparg = { + arg_name = 'test-string'; + arg_desc = 'string to look for'; + }; + exparg = { + arg_name = 'string-list'; + arg_desc = 'list of strings to check,,'; + arg_list = 'list'; + }; + opt = '1'; + doc = 'Return SCM_BOOL_T if the first argument is duplicated +in the second (list) argument.'; + foo = 'bar','','baz'; +}; + + +#line 4 "index.c" +gfunc = { + name = 'xtract'; + what = 'extract text from another file'; + general_use; + exparg = { + arg_name = 'file-name'; + arg_desc = 'name of file with text'; + }; + exparg = { + arg_name = 'marker-fmt'; + arg_desc = 'format for marker text'; + }; + exparg = { + arg_name = 'caveat'; + arg_desc = 'warn about changing marker'; + arg_optional = 'opt'; + }; + exparg = { + arg_name = 'default'; + arg_desc = 'default initial text'; + arg_optional = 'opt'; + }; +}; +_EOF_ + +set -x +${GDexe} output=$testname.out $testname.c || \ + failure running ${GDexe} +cmp -s $testname.test $testname.out || \ + failure "`diff $testname.test $testname.out`" + +# end of index.test diff --git a/getdefs/test/option.test b/getdefs/test/option.test new file mode 100755 index 0000000..33d9621 --- /dev/null +++ b/getdefs/test/option.test @@ -0,0 +1,100 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# +# option.test --- test option extraction +# +# Author: Bruce Korb +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . + +# Common definitions + +. ./defs + +# Create the files we need in the test environment +cat > ${testname}.c < ${testname}.test <<_EOF_ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * + * DO NOT EDIT THIS FILE (option.out) + * + * It has been extracted by getdefs from the following files: + * + * option.c + */ +autogen definitions option-testd; + +/* GLOBALDEFS */ + +#line 2 "option.c" + test = 'subblock'; + doc = 'we want to see +just what happens'; + + +#line 11 "option.c" +gfunc = { + name = 'in_p'; + exparg = { + arg_name = 'test-string'; + arg_desc = 'string to look for'; + }; + exparg = { + arg_name = 'string-list'; + arg_desc = 'list of strings to check,,'; + arg_list = 'list'; + }; + opt = '1'; + doc = +'Return SCM_BOOL_T if the first argument is duplicated +in the second (list) argument.'; +}; +_EOF_ +set -x +${GDexe} output=${testname}.out ${testname}.c || \ + failure running ${GDexe} +cmp -s ${testname}.test ${testname}.out || \ + failure "`diff ${testname}.test ${testname}.out`" + +# end of option.test diff --git a/getdefs/test/subblock.test b/getdefs/test/subblock.test new file mode 100755 index 0000000..d4fab2d --- /dev/null +++ b/getdefs/test/subblock.test @@ -0,0 +1,98 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# +# subblock.test --- test the subblock parameter to getdefs +# +# Author: Bruce Korb +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . + +# Common definitions + +. ./defs + + +# Create the files we need in the test environment +cat > $testname.c < $testname.test <<_EOF_ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * + * DO NOT EDIT THIS FILE (subblock.out) + * + * It has been extracted by getdefs from the following files: + * + * subblock.c + */ +autogen definitions subblock-testd; + +/* GLOBALDEFS */ + +#line 2 "subblock.c" + test = 'subblock'; + doc = 'we want to see +just what happens'; + + +#line 9 "subblock.c" +gfunc = { + name = 'in_p'; + exparg = { + arg_name = 'test-string'; + arg_desc = 'string to look for'; + }; + exparg = { + arg_name = 'string-list'; + arg_desc = 'list of strings to check,,'; + arg_list = 'list'; + }; + opt = '1'; + doc = 'Return SCM_BOOL_T if the first argument is duplicated +in the second (list) argument.'; +}; +_EOF_ + +${GDexe} subblock=exparg=arg_name,arg_desc,arg_optional,arg_list \ + output=$testname.out $testname.c || \ + failure running ${GDexe} +cmp -s $testname.test $testname.out || \ + failure "`diff $testname.test $testname.out`" + +# end of subblock.test diff --git a/pkg/Makefile.am b/pkg/Makefile.am new file mode 100644 index 0000000..0e2a807 --- /dev/null +++ b/pkg/Makefile.am @@ -0,0 +1,51 @@ +## -*- Mode: Makefile -*- +## Makefile.am --- process this file with automake to produce Makefile.in +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2017 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . + +DISTCLEANFILES = autogen.lsm +LIBOPTS_FILES = \ + libopts/libopts-add.m4 libopts/mklibsrc.sh libopts/README \ + libopts/COPYING.mbsd libopts/COPYING.lgplv3 libopts/stdnoreturn.mk \ + libopts/COPYING.gplv3 + +TPL_FILES = lsm.tpl spec.tpl gnudir.tpl gnudoc.tpl +PKG_FILES = mkpkg.linux mkpkg.sh mkpkg.sun pkg-env.in +EXTRA_DIST = $(TPL_FILES) $(LIBOPTS_FILES) $(PKG_FILES) +DOCENV = MAKE="$(MAKE)" + +all : $(DISTCLEANFILES) + +autogen.lsm : $(top_srcdir)/VERSION lsm.tpl + top_builddir=$(top_builddir) top_srcdir=$(top_srcdir) \ + $(AGexe) -L$(top_srcdir)/autoopts -T $(srcdir)/lsm.tpl \ + $(top_srcdir)/agen5/opts.def + +autogen.spec : $(top_srcdir)/VERSION spec.tpl + top_builddir=$(top_builddir) top_srcdir=$(top_srcdir) \ + $(AGexe) -T $(srcdir)/spec.tpl $(top_srcdir)/agen5/opts.def + +package : + pkgtype=$(pkgtype) \ + DESTDIR=`cd $(top_builddir) > /dev/null ; pwd`/stage-pkg \ + $(DOCENV) $(POSIX_SHELL) $(srcdir)/mkpkg.sh + +pkg : package + +.NOTPARALLEL: + +## pkg/Makefile.am ends here diff --git a/pkg/Makefile.in b/pkg/Makefile.in new file mode 100644 index 0000000..7ad0924 --- /dev/null +++ b/pkg/Makefile.in @@ -0,0 +1,537 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 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. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = pkg +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/ag_macros.m4 \ + $(top_srcdir)/config/asm-underscore.m4 \ + $(top_srcdir)/config/extensions.m4 \ + $(top_srcdir)/config/guile.m4 \ + $(top_srcdir)/config/host-cpu-c-abi.m4 \ + $(top_srcdir)/config/lib-ld.m4 \ + $(top_srcdir)/config/lib-link.m4 \ + $(top_srcdir)/config/lib-prefix.m4 \ + $(top_srcdir)/config/libopts.m4 \ + $(top_srcdir)/config/libtool.m4 \ + $(top_srcdir)/config/ltoptions.m4 \ + $(top_srcdir)/config/ltsugar.m4 \ + $(top_srcdir)/config/ltversion.m4 \ + $(top_srcdir)/config/lt~obsolete.m4 \ + $(top_srcdir)/config/onceonly.m4 $(top_srcdir)/config/pkg.m4 \ + $(top_srcdir)/config/snprintfv.m4 \ + $(top_srcdir)/config/stdnoreturn.m4 \ + $(top_srcdir)/config/unlocked-io.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = pkg-env +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/pkg-env.in +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AGEN5_TESTS = @AGEN5_TESTS@ +AG_LDFLAGS = @AG_LDFLAGS@ +AG_MAJOR_VERSION = @AG_MAJOR_VERSION@ +AG_MINOR_VERSION = @AG_MINOR_VERSION@ +AG_STATIC_AUTOGEN = @AG_STATIC_AUTOGEN@ +AG_TIMEOUT = @AG_TIMEOUT@ +AG_VERSION = @AG_VERSION@ +AG_XML2 = @AG_XML2@ +AGexe = @AGexe@ +AGnam = @AGnam@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AO_AGE = @AO_AGE@ +AO_CURRENT = @AO_CURRENT@ +AO_REVISION = @AO_REVISION@ +AO_TEMPLATE_VERSION = @AO_TEMPLATE_VERSION@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLexe = @CLexe@ +CLnam = @CLnam@ +CONFIG_SHELL = @CONFIG_SHELL@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBUG_ENABLED = @DEBUG_ENABLED@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +DYNAMIC_AG = @DYNAMIC_AG@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_STATIC = @ENABLE_STATIC@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GDexe = @GDexe@ +GDnam = @GDnam@ +GO_AGE = @GO_AGE@ +GO_CURRENT = @GO_CURRENT@ +GO_REVISION = @GO_REVISION@ +GREP = @GREP@ +GUILE_CFLAGS = @GUILE_CFLAGS@ +GUILE_EFFECTIVE_VERSION = @GUILE_EFFECTIVE_VERSION@ +GUILE_LDFLAGS = @GUILE_LDFLAGS@ +GUILE_LIBS = @GUILE_LIBS@ +GUILE_LTLIBS = @GUILE_LTLIBS@ +HOST_CPU = @HOST_CPU@ +HOST_CPU_C_ABI = @HOST_CPU_C_ABI@ +INCLIST = @INCLIST@ +INCSNPRINTFV = @INCSNPRINTFV@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSNPRINTFV = @LIBSNPRINTFV@ +LIBTOOL = @LIBTOOL@ +LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ +LIBXML2_LIBS = @LIBXML2_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +M4_SRC = @M4_SRC@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPTS_TESTDIR = @OPTS_TESTDIR@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSIX_SHELL = @POSIX_SHELL@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STDNORETURN_H = @STDNORETURN_H@ +STRIP = @STRIP@ +TEXI2HTML = @TEXI2HTML@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_aux_dir = @ac_aux_dir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +DISTCLEANFILES = autogen.lsm +LIBOPTS_FILES = \ + libopts/libopts-add.m4 libopts/mklibsrc.sh libopts/README \ + libopts/COPYING.mbsd libopts/COPYING.lgplv3 libopts/stdnoreturn.mk \ + libopts/COPYING.gplv3 + +TPL_FILES = lsm.tpl spec.tpl gnudir.tpl gnudoc.tpl +PKG_FILES = mkpkg.linux mkpkg.sh mkpkg.sun pkg-env.in +EXTRA_DIST = $(TPL_FILES) $(LIBOPTS_FILES) $(PKG_FILES) +DOCENV = MAKE="$(MAKE)" +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu pkg/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu pkg/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +pkg-env: $(top_builddir)/config.status $(srcdir)/pkg-env.in + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: + + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + cscopelist-am ctags-am distclean distclean-generic \ + distclean-libtool distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +all : $(DISTCLEANFILES) + +autogen.lsm : $(top_srcdir)/VERSION lsm.tpl + top_builddir=$(top_builddir) top_srcdir=$(top_srcdir) \ + $(AGexe) -L$(top_srcdir)/autoopts -T $(srcdir)/lsm.tpl \ + $(top_srcdir)/agen5/opts.def + +autogen.spec : $(top_srcdir)/VERSION spec.tpl + top_builddir=$(top_builddir) top_srcdir=$(top_srcdir) \ + $(AGexe) -T $(srcdir)/spec.tpl $(top_srcdir)/agen5/opts.def + +package : + pkgtype=$(pkgtype) \ + DESTDIR=`cd $(top_builddir) > /dev/null ; pwd`/stage-pkg \ + $(DOCENV) $(POSIX_SHELL) $(srcdir)/mkpkg.sh + +pkg : package + +.NOTPARALLEL: + +# 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/pkg/gnudir.tpl b/pkg/gnudir.tpl new file mode 100644 index 0000000..8dc6f3a --- /dev/null +++ b/pkg/gnudir.tpl @@ -0,0 +1,142 @@ +%%comments: +Copyright (C) 2001-2018 by Bruce Korb - all rights reserved + +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.1 or +any later version published by the Free Software Foundation; with no +Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. +A copy of the license is included in the file COPYING. + +%%name: Autogen + +%%short-description: Automated program and text generation + +%%full-description: Autogen is a tool designed for generating program +files that contain repetitive text with varied substitutions. its +goal is to simplify the maintenance of programs that have large +amounts of repetitive text. This is particularly valuable +if there are several blocks of such text that must be kept +synchronized. The follwing programs and libraries are also included: + +

AutoOpts- This is a link library that can be redistributed with any +project. It completely automates the process of parsing command line +options, configuration files, environment variables, usage text, man +pages, and the invoking section of an info doc. It currently produces +option processing code for C, C++, Guile inner-main programs and shell +scripts. + +

AutoFSM- Where it is possible to determine a state transition type +(token code) largely without reference to the current state, this +template will produce a transition table and prototype finite state +machine. If you must know current state to determine the transition +type, this is not useful. + +

getdefs- Extracts AutoGen definitions from stylized commentes +embedded in source code. + +

columns- tabularizes lists for improved output appearance. +See also ls(1). + +

AutoXDR- is an affiliated download. +NFSv4 specifies that its remote procedure calls be batched. Using +an enhanced XDR specification and the AutoXDR templates, AutoGen +generates all the grunge code for marshalling and unmarshalling +the arguments on both sides of the RPC request. + +%%category: software development, program build automation + +%%license: GPL, LGPL, BSD, public domain + +%%license verified by: Janet Casey + +%%license verified on: 2001-01-31 + +%%maintainer: Bruce Korb + +%%updated: 2005-02-01 + +%%keywords: RPC, rpcgen, NFSv4, finite state machine, FSM, Guile, M4 + +%%interface: Command line + +%%programs: autogen, getdefs, columns + +%%libraries: AutoOpts, AutoXDR, AutoFSM + +%%GNU: yes + +%%web-page: http://www.gnu.org/software/autogen + +%%support: + +%%doc: Developer's reference manual available from +http://www.gnu.org/manual/autogen/autogen.html + +%%developers: Bruce Korb , Gary V. Vaughan + +%%contributors: + +%%sponsors: + +%%source-tarball: ftp://ftp.gnu.org/pub/gnu/autogen/autogen-5.3.2.tar.gz + +%%source-info: http://prdownloads.sourceforge.net/autogen/ + +%%source-template: + +%%debian: http://packages.debian.org/unstable/devel/autogen.html + +%%rpm: + +%%repository: cvs.AutoGen.sourceforge.net:/cvsroot/AutoGen + +%%related: Guile + +%%source-language: C, Guile, Bourne shell + +%%supported-languages: + +%%use-requirements: Guile, Bourne-like shell, POSIX environment + +%%build-prerequisites: Guile, ANSI C, Bourne-like shell, POSIX environment + +%%weak-prerequisites: + +%%source-prerequisites: + +%%version: 5.3.2 stable released 2002-02-25 + +%%announce-list: + +%%announce-news: + +%%help-list: + +%%help-news: + +%%irc-help-channel: + +%%dev-list: + +%%dev-news: + +%%irc-dev-channel: + +%%bug-list: + +%%bug-database: + +%%Entry Written By: Janet Casey + + + + + + + + + + + + + diff --git a/pkg/gnudoc.tpl b/pkg/gnudoc.tpl new file mode 100644 index 0000000..f74662c --- /dev/null +++ b/pkg/gnudoc.tpl @@ -0,0 +1,142 @@ +[= AutoGen5 Template -*- Mode: html -*- + +html =][= +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . + +=] + +[=(dne " == " " +[= title =] - GNU Project - Free Software Foundation (FSF) + + + +

[= project =] version [= version =] - Table of Contents

+ +
Free Software Foundation
+
last updated [=`date '+%B %e, %Y'`=]
+ +

The manual for the [= project =] project is available in the following formats:

[= + +(define fnam "") +(define fsiz 0) + +(define (compute-size dir sfx) + (begin + (set! fnam (string-append dir "/" package sfx)) + (set! fsiz (if (access? fnam R_OK) (stat:size (stat fnam)) 0 )) + (shellf "fsiz='%d' + if test ${fsiz} -lt 4096 + then echo ${fsiz} + else + fsiz=`expr ${fsiz} / 1024` + if test ${fsiz} -lt 2048 + then echo ${fsiz}K + else + fsiz=`expr ${fsiz} / 1024` + echo ${fsiz}M + fi + fi" fsiz) +) ) + +=] + + +

(This page generated by the autogen program in conjunction with a fairly simple template.)

+ + + + + diff --git a/pkg/libopts/COPYING.gplv3 b/pkg/libopts/COPYING.gplv3 new file mode 100644 index 0000000..7718bd1 --- /dev/null +++ b/pkg/libopts/COPYING.gplv3 @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) by Bruce Korb - all rights reserved + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) by Bruce Korb - all rights reserved + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/pkg/libopts/COPYING.lgplv3 b/pkg/libopts/COPYING.lgplv3 new file mode 100644 index 0000000..f7b8c63 --- /dev/null +++ b/pkg/libopts/COPYING.lgplv3 @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + 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 that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser 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 as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/pkg/libopts/COPYING.mbsd b/pkg/libopts/COPYING.mbsd new file mode 100644 index 0000000..b74eb00 --- /dev/null +++ b/pkg/libopts/COPYING.mbsd @@ -0,0 +1,27 @@ +Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + 3. The name of the author may not be used to endorse or promote + products derived from this software without specific prior + written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/pkg/libopts/README b/pkg/libopts/README new file mode 100644 index 0000000..5c8b9d7 --- /dev/null +++ b/pkg/libopts/README @@ -0,0 +1,122 @@ + THIS TARBALL IS NOT A FULL DISTRIBUTION. + +The contents of this tarball is designed to be incorporated into +software packages that utilize the AutoOpts option automation package +and are intended to be installed on systems that may not have libopts +installed. It is redistributable under the terms of either the LGPL +(see COPYING.lgpl) or under the terms of the advertising clause free BSD +license (see COPYING.mbsd). + +Usage Instructions for autoconf/automake/libtoolized projects: + +1. Install the unrolled tarball into your package source tree, + copying ``libopts.m4'' to your autoconf macro directory. + + In your bootstrap (pre-configure) script, you can do this: + + rm -rf libopts libopts-* + gunzip -c `autoopts-config libsrc` | tar -xvf - + mv -f libopts-*.*.* libopts + cp -fp libopts/m4/*.m4 m4/. + + I tend to put my configure auxiliary files in "m4". + Whatever directory you choose, if it is not ".", then + be sure to tell autoconf about it with: + + AC_CONFIG_AUX_DIR(m4) + + This is one macro where you *MUST* remember to *NOT* quote + the argument. If you do, automake will get lost. + +2. Add an invocation of either LIBOPTS_CHECK or LIBOPTS_CHECK_NOBUILD + to your configure.ac file. See LIBOPTS_CHECK: below for details. + +3. Add the following to your top level ``Makefile.am'' file: + + if NEED_LIBOPTS + SUBDIRS += $(LIBOPTS_DIR) + endif + + where ``<...>'' can be whatever other files or directories you may + need. The SUBDIRS must be properly ordered. *PLEASE NOTE* it is + crucial that the SUBDIRS be set under the control of an automake + conditional. To work correctly, automake has to know the range of + possible values of SUBDIRS. It's a magical name with magical + properties. ``NEED_LIBOPTS'' will be correctly set by the + ``LIBOPTS_CHECK'' macro, above. + +4. Add ``$(LIBOPTS_CFLAGS)'' to relevant compiler flags and + ``$(LIBOPTS_LDADD)'' to relevant link options whereever + you need them in your build tree. + +5. Make sure your object files explicitly depend upon the + generated options header file. e.g.: + + $(prog_OBJECTS) : prog-opts.h + prog-opts.h : prog-opts.c + prog-opts.c : prog-opts.def + autogen prog-opts.def + +6. *OPTIONAL* -- + If you are creating man pages and texi documentation from + the program options, you will need these rules somewhere, too: + + man_MANS = prog.1 + prog.1 : prog-opts.def + autogen -Tagman-cmd.tpl -bprog prog-opts.def + + invoke-prog.texi : prog-opts.def + autogen -Tagtexi-cmd.tpl prog-opts.def + +If your package does not utilize the auto* tools, then you +will need to hand craft the rules for building the library. + +LIBOPTS_CHECK: + +The arguments to both macro are a relative path to the directory with +the libopts source code. It is optional and defaults to "libopts". +These macros work as follows: + +1. LIBOPTS_CHECK([libopts/rel/path/optional]) + + Adds two command-line options to the generated configure script, + --enable-local-libopts and --disable-libopts-install. AC_SUBST's + LIBOPTS_CFLAGS, LIBOPTS_LDADD, and LIBOPTS_DIR for use in + Makefile.am files. Adds Automake conditional NEED_LIBOPTS which + will be true when the local copy of libopts should be built. Uses + AC_CONFIG_FILES([$libopts-dir/Makefile]) to cause the local libopts + into the package build. If the optional relative path to libopts is + not provided, it defaults to simply "libopts". + +2. LIBOPTS_CHECK_NOBUILD([libopts/rel/path/optional]) + + This variant of LIBOPTS_CHECK is useful when multiple configure.ac + files in a package make use of a single libopts tearoff. In that + case, only one of the configure.ac files should build libopts and + others should simply use it. Consider this package arrangment: + + all-tools/ + configure.ac + common-tools/ + configure.ac + libopts/ + + The parent package all-tools contains a subpackage common-tools + which can be torn off and used independently. Programs configured + by both configure.ac files link against the common-tools/libopts + tearoff, when not using the system's libopts. The top-level + configure.ac uses LIBOPTS_CHECK_NOBUILD([common-tools/libopts]), + while common-tools/configure.ac uses LIBOPTS_CHECK. The difference + is LIBOPTS_CHECK_NOBUILD will never build the libopts tearoff, + leaving that to the subpackage configure.ac's LIBOPTS_CHECK. + Specifically, LIBOPTS_CHECK_NOBUILD always results in the + NEED_LIBOPTS Automake conditional being false, and does not invoke + AC_CONFIG_FILES(path-to-libopts/Makefile). + +LICENSING: + +This material is Copyright (C) 1992-2018 by Bruce Korb. You are +licensed to use this under the terms of either the GNU Lesser General +Public License (see: COPYING.lgpl), or, at your option, the modified +Berkeley Software Distribution License (see: COPYING.mbsd). Both of +these files should be included with this tarball. diff --git a/pkg/libopts/libopts-add.m4 b/pkg/libopts/libopts-add.m4 new file mode 100644 index 0000000..4e11ec8 --- /dev/null +++ b/pkg/libopts/libopts-add.m4 @@ -0,0 +1,138 @@ + +dnl @synopsis LIBOPTS_CHECK +dnl +dnl If autoopts-config works, add the linking information to LIBS. +dnl Otherwise, add ``libopts-${ao_rev}'' to SUBDIRS and run all +dnl the config tests that the library needs. Invoke the +dnl "INVOKE_LIBOPTS_MACROS" macro iff we are building libopts. +dnl +dnl This file is part of AutoGen. +dnl AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +dnl +dnl AutoGen is free software: you can redistribute it and/or modify it +dnl under the terms of the GNU General Public License as published by the +dnl Free Software Foundation, either version 3 of the License, or +dnl (at your option) any later version. +dnl +dnl AutoGen is distributed in the hope that it will be useful, but +dnl WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +dnl See the GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License along +dnl with this program. If not, see . +dnl +dnl Default to system libopts +dnl +AC_DEFUN([LIBOPTS_CHECK_COMMON],[ + AC_REQUIRE([INVOKE_LIBOPTS_MACROS_FIRST]) + [NEED_LIBOPTS_DIR=''] + m4_pushdef([AO_Libopts_Dir], + [ifelse($1, , [libopts], [$1])]) + AC_ARG_ENABLE([local-libopts], + AC_HELP_STRING([--enable-local-libopts], + [Use the supplied libopts tearoff code]),[ + if test x$enableval = xyes ; then + AC_MSG_NOTICE([Using supplied libopts tearoff]) + LIBOPTS_CFLAGS='-I$(top_srcdir)/AO_Libopts_Dir' + NEED_LIBOPTS_DIR=true + LIBOPTS_LDADD='$(top_builddir)/AO_Libopts_Dir/libopts.la' + fi]) + + AC_ARG_ENABLE([libopts-install], + AC_HELP_STRING([--enable-libopts-install], + [Install libopts with client installation])) + AM_CONDITIONAL([INSTALL_LIBOPTS],[test "X${enable_libopts_install}" = Xyes]) + + [if test -z "${NEED_LIBOPTS_DIR}" ; then] + AC_MSG_CHECKING([whether autoopts-config can be found]) + AC_ARG_WITH([autoopts-config], + AC_HELP_STRING([--with-autoopts-config], + [specify the config-info script]), + [lo_cv_with_autoopts_config=${with_autoopts_config}], + AC_CACHE_CHECK([whether autoopts-config is specified], + [lo_cv_with_autoopts_config], + [if autoopts-config --help 2>/dev/null 1>&2 + then lo_cv_with_autoopts_config=autoopts-config + elif libopts-config --help 2>/dev/null 1>&2 + then lo_cv_with_autoopts_config=libopts-config + else lo_cv_with_autoopts_config=no ; fi]) + ) # end of AC_ARG_WITH + + AC_CACHE_VAL([lo_cv_test_autoopts],[ + if test -z "${lo_cv_with_autoopts_config}" \ + -o X"${lo_cv_with_autoopts_config}" = Xno + then + if autoopts-config --help 2>/dev/null 1>&2 + then lo_cv_with_autoopts_config=autoopts-config + elif libopts-config --help 2>/dev/null 1>&2 + then lo_cv_with_autoopts_config=libopts-config + else lo_cv_with_autoopts_config=false ; fi + fi + lo_cv_test_autoopts=` + ${lo_cv_with_autoopts_config} --libs` 2> /dev/null + if test $? -ne 0 -o -z "${lo_cv_test_autoopts}" + then lo_cv_test_autoopts=no ; fi + ]) # end of CACHE_VAL + AC_MSG_RESULT([${lo_cv_test_autoopts}]) + + [if test "X${lo_cv_test_autoopts}" != Xno + then + LIBOPTS_LDADD="${lo_cv_test_autoopts}" + LIBOPTS_CFLAGS="`${lo_cv_with_autoopts_config} --cflags`" + else + LIBOPTS_LDADD='$(top_builddir)/]AO_Libopts_Dir[/libopts.la' + LIBOPTS_CFLAGS='-I$(top_srcdir)/]AO_Libopts_Dir[' + NEED_LIBOPTS_DIR=true + fi + fi # end of if test -z "${NEED_LIBOPTS_DIR}" + if test -n "${LIBOPTS_BUILD_BLOCKED}" ; then + NEED_LIBOPTS_DIR='' + fi] + AM_CONDITIONAL([NEED_LIBOPTS], [test -n "${NEED_LIBOPTS_DIR}"]) + AC_SUBST(LIBOPTS_LDADD) + AC_SUBST(LIBOPTS_CFLAGS) + AC_SUBST(LIBOPTS_DIR, AO_Libopts_Dir) + m4_popdef([AO_Libopts_Dir]) +[# end of AC_DEFUN of LIBOPTS_CHECK_COMMON] +]) +dnl +dnl AC_CONFIG_FILES conditionalization requires using AM_COND_IF, however +dnl AM_COND_IF is new to Automake 1.11. To use it on new Automake without +dnl requiring same, a fallback implementation for older Automake is provided. +dnl Note that disabling of AC_CONFIG_FILES requires Automake 1.11, this code +dnl is correct only in terms of m4sh generated script. +dnl +m4_ifndef([AM_COND_IF], + [AC_DEFUN([AM_COND_IF], [ + if test -z "$$1_TRUE"; then : + m4_n([$2])[]dnl + m4_ifval([$3],[ + else + $3 + ])dnl + fi[]dnl + ])dnl +]) +dnl +AC_DEFUN([LIBOPTS_CHECK_NOBUILD], [ + m4_pushdef([AO_Libopts_Dir], + [ifelse($1, , [libopts], [$1])]) + LIBOPTS_BUILD_BLOCKED=true + LIBOPTS_CHECK_COMMON(AO_Libopts_Dir) + m4_popdef([AO_Libopts_Dir])dnl +# end of AC_DEFUN of LIBOPTS_CHECK_NOBUILD +]) +dnl +AC_DEFUN([LIBOPTS_CHECK], [ + m4_pushdef([AO_Libopts_Dir], + [ifelse($1, , [libopts], [$1])]) + LIBOPTS_BUILD_BLOCKED='' + LIBOPTS_CHECK_COMMON(AO_Libopts_Dir) + AM_COND_IF([NEED_LIBOPTS], [ + INVOKE_LIBOPTS_MACROS + ]) + AC_CONFIG_FILES(AO_Libopts_Dir/Makefile) + m4_popdef([AO_Libopts_Dir])dnl +# end of AC_DEFUN of LIBOPTS_CHECK +]) diff --git a/pkg/libopts/mklibsrc.sh b/pkg/libopts/mklibsrc.sh new file mode 100644 index 0000000..0cad4dc --- /dev/null +++ b/pkg/libopts/mklibsrc.sh @@ -0,0 +1,149 @@ +#! /bin/echo thils-file-should-not-be-directly-executed +## -*- Mode: shell-script -*- +## +## mklibsrc.sh -- make the libopts tear-off library source tarball +## +## This file is called via $(POSIX_SHELL) in autoopts/Makefile +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . + +test ${#CDPATH} -gt 0 && CDPATH='' +test -d "${top_builddir}" && test -d "${top_srcdir}" || { + echo top_builddir and top_srcdir must specify a directory >&2 + exit 1 +} +top_builddir=`cd $top_builddir ; pwd` +top_srcdir=`cd $top_srcdir ; pwd` + +test -x ${top_builddir}/agen5/autogen || exit 0 +test -x ${top_builddir}/columns/columns || exit 0 + +ao_rev=${AO_CURRENT}.${AO_REVISION}.${AO_AGE} +tag=libopts-${ao_rev} + +cd ${top_builddir}/pkg +[ ! -d ${tag} ] || rm -rf ${tag} +mkdir ${tag} ${tag}/compat ${tag}/autoopts ${tag}/m4 +tagd=`pwd`/${tag} + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# +# WORKING IN SOURCE DIRECTORY +# +cd ${top_builddir}/autoopts +files='libopts.c gettext.h parse-duration.c parse-duration.h + stdnoreturn.in.h _Noreturn.h '$( + fgrep '#include' libopts.c | \ + sed -e 's,"$,,;s,#.*",,' ) + +for f in ${files} intprops.h verify.h +do + test -f ${f} && + cp -f ${f} ${tagd}/${f} && continue + + test -f ${top_srcdir}/autoopts/${f} && + cp -f ${top_srcdir}/autoopts/${f} ${tagd}/${f} && continue + + test -f ${top_srcdir}/${f} && + cp -f ${top_srcdir}/${f} ${tagd}/${f} && continue + + die "could not locate ${f} to copy into tarball" +done + +cp -f ${top_srcdir}/pkg/libopts/COPYING.* ${tagd}/. + +cd ${top_srcdir}/compat +cp windows-config.h compat.h pathfind.c snprintf.c strdup.c strchr.c \ + ../config/snippet/_Noreturn.h ${tagd}/compat/. +# +# END WORK IN SOURCE DIRECTORY +# +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # + +cd ${tagd} + +cp ${top_srcdir}/config/libopts*.m4 ${top_srcdir}/config/stdnoret*.m4 m4/. +chmod u+w m4/libopts.m4 +cat ${top_srcdir}/pkg/libopts/libopts-add.m4 >> m4/libopts.m4 +test ! -f Makefile.am || rm -f Makefile.am + +sed s,'\${tag}',"${tag}",g ${top_srcdir}/pkg/libopts/README > README + +touch MakeDefs.inc + +vers=${AO_CURRENT}:${AO_REVISION}:${AO_AGE} +{ + cat <<- EOMakefile + ## LIBOPTS Makefile + MAINTAINERCLEANFILES = Makefile.in + if INSTALL_LIBOPTS + lib_LTLIBRARIES = libopts.la + else + noinst_LTLIBRARIES = libopts.la + endif + libopts_la_SOURCES = libopts.c + libopts_la_CPPFLAGS = -I\$(srcdir) + libopts_la_LDFLAGS = -version-info ${AM_LDFLAGS} ${vers} + EXTRA_DIST = + BUILT_SOURCES = + MOSTLYCLEANFILES = + + libopts.c: \$(BUILT_SOURCES) + @: do-nothing rule to avoid default SCCS get + + EOMakefile + + printf '\n# Makefile fragment from gnulib-s stdnoreturn module:\n#\n' + sed '/^#/d;/^$/d;s/top_srcdir/srcdir/' \ + ${top_srcdir}/pkg/libopts/stdnoreturn.mk + sed '1,/^Makefile.am:/d;/^[A-Z][a-z0-9-]*:/,$d' \ + ${top_srcdir}/pkg/libopts/_Noreturn + + printf '\nEXTRA_DIST += \\\n' + find $(ls -A) -type f \ + | env LC_COLLATE=C sort \ + | egrep -v '^(libopts\.c|Makefile\.am)$' \ + | ${CLexe} -I4 --spread=1 --line-sep=" \\" +} > Makefile.am + +gz='gzip --best -n' +sfx=tar.gz + +cd .. +echo ! cd `pwd` +echo ! tar cvf ${tag}.${sfx} ${tag} + +# If we have a SOURCE_DATE_EPOCH *and* tar supports a sort option, +# then add some fancy options to make tar output repeatable. +# +rbopts="" +[ -z "$SOURCE_DATE_EPOCH" ] \ + || ! tar --help|grep -q sort= \ + || rbopts="--sort=name --format=gnu --clamp-mtime --mtime @$SOURCE_DATE_EPOCH" + +tar cvf - $rbopts ${tag} | \ + $gz > ${top_builddir}/autoopts/${tag}.${sfx} +rm -rf ${tag} + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: + +## end of mklibsrc.sh diff --git a/pkg/libopts/stdnoreturn.mk b/pkg/libopts/stdnoreturn.mk new file mode 100644 index 0000000..ba5a80a --- /dev/null +++ b/pkg/libopts/stdnoreturn.mk @@ -0,0 +1,30 @@ + +# Because this Makefile snippet defines a variable used by other +# gnulib Makefile snippets, it must be present in all makefiles that +# need it. This is ensured by the applicability 'all' defined above. + +_NORETURN_H=$(srcdir)/_Noreturn.h + +EXTRA_DIST += _Noreturn.h + + +BUILT_SOURCES += $(STDNORETURN_H) + +# We need the following in order to create when the system +# doesn't have one that works. +if GL_GENERATE_STDNORETURN_H +stdnoreturn.h: stdnoreturn.in.h $(top_builddir)/config.status $(_NORETURN_H) + $(AM_V_GEN)rm -f $@-t $@ && \ + { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \ + sed -e '/definition of _Noreturn/r $(_NORETURN_H)' \ + < $(srcdir)/stdnoreturn.in.h; \ + } > $@-t && \ + mv $@-t $@ +else +stdnoreturn.h: $(top_builddir)/config.status + rm -f $@ +endif +MOSTLYCLEANFILES += stdnoreturn.h stdnoreturn.h-t + +EXTRA_DIST += stdnoreturn.in.h + diff --git a/pkg/lsm.tpl b/pkg/lsm.tpl new file mode 100644 index 0000000..7d4d973 --- /dev/null +++ b/pkg/lsm.tpl @@ -0,0 +1,68 @@ +[= AutoGen5 template + +lsm=autogen.lsm + +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . +=] +Begin4 +Title: AutoGen + +Version: [=version=] + +Entered-date: [=`date +%Y-%m-%d`=] + +Description: AutoGen - [=prog_title=] + + AutoGen is a tool for automatically generating + arbitrary text files that contain repetitive text + with varying substitutions. This is particularly + useful if you have several types of repetitive + text that all need to be kept in sync with each + other. The goal is to try to simplify the process + of maintaining repetitive program text. + +Keywords: macro, m4, preprocessor, source generator, + command line option parser + +Author: bkorb@gnu.org (Bruce Korb) + +Maintained-by: bkorb@gnu.org (Bruce Korb) + +Primary-site: sunsite.unc.edu /pub/Linux/devel + [= ` +cd $top_builddir +set -- autogen*.gz +if [ $# -gt 1 ] +then shift \`expr $# - 1\` ; fi +if [ ! -f $1 ] +then ct=1151 +else ct="\`expr \\\\( \\\`wc -c < $1\\\` + 1023 \\\\) / 1024\`" +fi +echo ${ct}K $1 +` =] + 1K autogen.lsm + +Alternate-site: ftp://ftp.gnu.org/pub/autogen + +Original-site: http://autogen.sourceforge.net + +Platforms: gunzip, Guile and ANSI-C + +Copying-policy: GPL and LGPL + +End diff --git a/pkg/mkpkg.linux b/pkg/mkpkg.linux new file mode 100644 index 0000000..3743dad --- /dev/null +++ b/pkg/mkpkg.linux @@ -0,0 +1,91 @@ +#! /bin/sh + +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . + +case "${VERBOSE}" in +"" | f* | F* | n* | N* ) + VERBOSE=false ;; +*) VERBOSE=true ; set -x ;; +esac +export VERBOSE + +eval "`egrep '^AG_' ${top_srcdir}/VERSION`" > /dev/null + +## Set directories in case they are relative paths +## +builddir=`pwd` +top_srcdir=`cd ${top_srcdir} > /dev/null ; pwd` +srcdir=`cd ${srcdir} > /dev/null ; pwd` + +cd ${top_builddir} +top_builddir=`pwd` + +rm -rf ./AGPKG +mkdir AGPKG +cd AGPKG +HOME=`pwd` + +mkdir -p BUILD SOURCES SPECS RPMS SRPMS + +[ -f ../autogen-${AG_VERSION}.tar.gz ] || ( + cd .. + ${MAKE} dist || exit 1 +) || exit 1 + +ln ../autogen-${AG_VERSION}.tar.gz SOURCES/. +printf "\n\nPACKAGING RPM FOR LINUX\n\n" + +cd ${builddir} +AG_VERSION=`echo ${AG_VERSION} | sed 's,\.,-,g'` +specfile=autogen-${AG_VERSION}.spec +agargs="-L ${srcdir} -L ${top_srcdir}/autoopts" +agargs="${agargs} -T spec.tpl -b autogen-${AG_VERSION} --writable" +${AGexe} ${agargs} ${top_srcdir}/agen5/opts.def || exit 1 + +cd ${HOME} + +echo "%_tmppath ${top_builddir}/AGPKG/BUILD +%_topdir $PWD" > .rpmmacros + +cat > .rpmrc <<- _EOF_ + + optflags: i386 -O3 -march=i486 -mcpu=i686 + optflags: i486 -O3 -march=i486 + optflags: i586 -O3 -march=i586 -mcpu=i686 -fmessage-length=0 + optflags: i686 -O3 -march=i686 -mcpu=i686 + optflags: athlon -O3 -march=athlon + optflags: ia64 -O3 + optflags: x86_64 -O3 + optflags: amd64 -O3 + optflags: ia32e -O3 + + _EOF_ + +RPM_OPT_FLAGS=-O3 rpmbuild -ba ${builddir}/${specfile} || exit 1 +ln `find . -type f -name '*.rpm'` ${builddir}/. +cd ${builddir} +rm -rf ${HOME} +${VERBOSE} || ls -l *.rpm +: + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: +## end of mkpkg.linux diff --git a/pkg/mkpkg.sh b/pkg/mkpkg.sh new file mode 100644 index 0000000..ff3527d --- /dev/null +++ b/pkg/mkpkg.sh @@ -0,0 +1,45 @@ +#! /bin/sh + +## mkpkg.sh -- create a native package +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . + +test -f pkg-env && . pkg-env + +if test -z "${pkgtype}" +then + pkgtype=`sh ${top_srcdir}/config/config.guess | \ + sed 's,-[^-]*$,,;s,.*-,,'` +fi + +if test ! -f ${srcdir}/mkpkg.${pkgtype} +then + pkgtype=`uname -s | tr '[A-Z]' '[a-z]'` + test -f ${srcdir}/mkpkg.${pkgtype} || { + echo "No mkpkg script for ${pkgtype}" >&2 + exit 1 + } +fi + +. ${srcdir}/mkpkg.${pkgtype} + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: +## mkpkg.sh ends here diff --git a/pkg/mkpkg.sun b/pkg/mkpkg.sun new file mode 100644 index 0000000..5b33413 --- /dev/null +++ b/pkg/mkpkg.sun @@ -0,0 +1,150 @@ +#! /bin/sh + +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . + +case "${VERBOSE}" in +"" | f* | F* | n* | N* ) + VERBOSE=false ;; +*) VERBOSE=true ; set -x ;; +esac +export VERBOSE + +set -e +pkgsrc=`pwd` +agdir=`cd ../agen5 > /dev/null 2>&1 ; pwd` + +[ ! -d ${DESTDIR} ] || rm -rf ${DESTDIR} || exit 1 +mkdir ${DESTDIR} || exit 1 +DESTDIR=`cd ${DESTDIR} > /dev/null && pwd` || exit 1 + +cd ${top_builddir} +${MAKE} install DESTDIR=${DESTDIR} + +cd ${DESTDIR} + +if [ ! -d reloc ] +then + mkdir reloc + case "${prefix}" in + /* ) : ;; + * ) prefix="/${prefix}" ;; + esac + mv .${prefix}/* reloc/. || exit 1 + p=${prefix} + while [ -n "$p" ] + do rmdir .${p} + p=`echo "$p" | sed 's,/[^/]*$,,'` + done +fi + +cp -f ${top_srcdir}/COPYING ./copyright + +pkgdst=`pwd` +[ -f prototype ] && rm -f prototype +exec 4> prototype +cat >&4 <<- EOF + # Prototype file for AutoGen + # + # derived by scanning the `pwd` directory + + i copyright + i pkginfo + i prototype + i checkinstall + ! default 0755 root sys + + # pt tp ???? obj-name + EOF + +cd reloc + +find * -type d | \ +while read d +do + case "$d" in + *autogen* ) mod="0775 root sys" ;; + * ) mod="? ? ?" ;; + esac + + echo " 1 d none ${d} ${mod}" +done >&4 + +echo "! default 0644 root sys" >&4 + +find * -type f | \ +while read f +do + if [ -x "$f" ] + then mod=0755 + else mod=0644 ; fi + echo " 1 f none ${f} $mod root sys" +done >&4 + +find * -type l | \ +while read l +do + f=`ls -l $l | sed 's,.* -> ,,'` + echo " 1 s none ${l}=${f}" +done >&4 + +exec 4>&- +cd ${pkgdst} + +cat > checkinstall <<- EOF + PATH=${PATH}:${prefix}/bin + guile-config compile > /dev/null 2>&1 && exit 0 + guile -c '(quit "bye")' && exit 0 + echo "The guile library does not seem to be present." + echo "I have searched the PATH ${PATH}" + echo "If it is, please ensure it is in the search path and retry." + exit 1 + EOF + +[ -f pkginfo.tpl ] && rm -f pkginfo.tpl +cat > pkginfo.tpl <<- EOF + [= AutoGen5 Template info=pkginfo =] + PKG="GNUagen" + NAME="AutoGen - [=prog-title=]" + VERSION="[= version =]" + BASEDIR="${prefix}" + DESC="AutoGen - [=prog-title=]" + VENDOR="[= copyright.owner =] http://autogen.sf.net" + ARCH="sparc" + CATEGORY="Development" + EMAIL="[= copyright.eaddr =]" + CONTACT="[= copyright.owner =]" + CLASSES=none + PSTAMP="[= version =] `date '+%Y-%m-%d %H:%M:%S'`" + EOF + +cd ${agdir} +${AGexe} --writable -L${pkgdst} -Tpkginfo.tpl ${top_srcdir}/agen5/opts.def +mv -f pkginfo ${pkgdst}/. +cd ${pkgdst} +rm -f pkginfo.tpl +cd .. +rm -rf GNUagen* +pkgmk -d. -r ${pkgdst}/reloc,${pkgdst} -f ${pkgdst}/prototype +pkgtrans -s . GNUagen.pkg GNUagen +gzip --best GNUagen.pkg +rm -rf ${pkgdst} + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## End: +## end of mkpkg.sun diff --git a/pkg/pkg-env.in b/pkg/pkg-env.in new file mode 100644 index 0000000..4fcbaac --- /dev/null +++ b/pkg/pkg-env.in @@ -0,0 +1,45 @@ +#! /bin/echo this_file_must_be_sourced,_not_executed + +## pkg-env.in -- create a native package +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . + +set -a + +prefix="@prefix@" +builddir="@abs_builddir@" +srcdir="@abs_srcdir@" +top_builddir="@abs_top_builddir@" +top_srcdir="@abs_top_srcdir@" +PACKAGE="@PACKAGE@" +PACKAGE_BUGREPORT="@PACKAGE_BUGREPORT@" +PACKAGE_NAME="@PACKAGE_NAME@" +PACKAGE_STRING="@PACKAGE_STRING@" +PACKAGE_TARNAME="@PACKAGE_TARNAME@" +PACKAGE_VERSION="@PACKAGE_VERSION@" +. ${top_srcdir}/VERSION +AGexe="@AGexe@" +CLexe="@CLexe@" + +set +a + +## Local Variables: +## mode: shell-script +## indent-tabs-mode: nil +## sh-indentation: 2 +## sh-basic-offset: 2 +## End: +## pkg-env.in ends here diff --git a/pkg/spec.tpl b/pkg/spec.tpl new file mode 100644 index 0000000..ec444b8 --- /dev/null +++ b/pkg/spec.tpl @@ -0,0 +1,149 @@ +[= AutoGen5 Template spec =] +[= # + * This file is part of AutoGen. + * AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoGen is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AutoGen is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . +\=] +Summary: AutoGen - [=prog-title=] +Name: [= prog-name =] +Version: [= version =] +Vendor: [= copyright.owner =] http://www.gnu.org/software/autogen +Release: [=`echo $AG_MAJOR_VERSION`=] +License: GPL +Group: Development/Tools +Source: ftp://ftp.gnu.org/gnu/autogen/rel[= version =]/autogen-[= version + =].tar.gz +BuildRoot: %{_tmppath}/%{name}-root + +%description +AutoGen is a tool designed for generating program files that contain +repetitive text with varied substitutions. Its goal is to simplify the +maintenance of programs that contain large amounts of repetitious text. +This is especially valuable if there are several blocks of such text +that must be kept synchronized in parallel tables. + +Some parts are released under different licensing: + +libopts LGPL This is a tear-off, redistributable option processing library +autofsm BSD This is a template for producing finite state machine programs + +The Copyright itself is privately held by Bruce Korb. +Copyright (C) [= copyright.date =] by [= copyright.owner + =]. All rights reserved. Licensed under GPL, [=# + =]version 2 or later. +%prep +%setup -q +chmod -R +rw * + +%build +%configure +make CFLAGS="$RPM_OPT_FLAGS" + +if [ `id -u` -eq 0 ] && grep -E -q '^nobody:' /etc/passwd +then + echo "switching to user nobody to run 'make check'" + chown -R nobody . + su -s /bin/bash -c "umask 002; make check || touch FAIL" nobody + test -f FAIL && exit 1 || : +else + make check +fi + +%install +[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf ${RPM_BUILD_ROOT} +mkdir -p ${RPM_BUILD_ROOT} +make install DESTDIR=${RPM_BUILD_ROOT} + +# IF we have a valid file list OR the build root is _the_ root, +# THEN skip the file list generation. +# +if test -s autogen-filelist -o ${#RPM_BUILD_ROOT} -le 1 +then : ; else + ( cd ${RPM_BUILD_ROOT} + rm -f usr/share/info/dir + find . -type f -o -type l | grep -v 'usr/share/doc' + ) | sed -e 's@^\./@/@' \ + -e'/usr\/share\/info/s,$,.gz,' \ + -e'/usr\/share\/man/s,$,.gz,' \ + | sort \ + > autogen-filelist +fi + +%post +/sbin/ldconfig +/sbin/install-info --info-dir=%{_infodir} %{_infodir}/autogen.info* + +%preun +/sbin/install-info --delete --info-dir=%{_infodir} %{_infodir}/autogen.info* + +%postun -p /sbin/ldconfig + +%clean +rm -rf ${RPM_BUILD_ROOT} + +%files -f autogen-filelist +%defattr(-,root,root) + +%doc[=` +for f in AUTHORS TODO COPYING NEWS THANKS README +do test -f ${top_builddir}/$f -o -f ${top_srcdir}/$f && printf " $f" ; done +`=] + +%changelog +[= + +;; Run the following script at spec creation time to insert the +;; "regenerated" change log entry +;; +(out-push-new) + +=] +test -z "${LOGNAME}" && { + LOGNAME=`logname` 2>/dev/null + case "${LOGNAME}" in + *"no login name" ) + LOGNAME=`id | sed 's,).*,,;s,^.*(,,'` ;; + esac +} +name=`grep ^${LOGNAME}: /etc/passwd | \ + sed 's,:/.*,,;s,.*:,,'` 2>/dev/null +date=`date '+%a %b %e %Y'` +domain=`dnsdomainname` 2>/dev/null + +echo \* ${date} ${name} \<${LOGNAME}@${domain}\> Regenerated +[= + +(shell (out-pop #t)) + +=] +* Sun May 6 2012 Install only existing files to doc directory. +- Omit NOTES and VERSION. +* Fri Dec 31 2004 Bruce Korb Restored the file list +* Wed Oct 27 2004 Ed Swierk fixed up for Fedora +* Tue Dec 16 2003 Richard Zidlicky 5.5.7pre5-5 +- fix %%doc +- add post/pre scriptlets +- change default prefix +* Sat Mar 15 2003 Bruce Korb +- Rework as a template to automatically produce a properly configured RPM +* Fri Aug 9 2002 Bruce Korb +- Pull stuff from Thomas Steudten's version of this file[= #' + +## Local Variables: +## mode: shell-script +## minor-mode: rpm +## indent-tabs-mode: nil +## End: +## end of spec.tpl =] diff --git a/snprintfv/AUTHORS b/snprintfv/AUTHORS new file mode 100644 index 0000000..d17456b --- /dev/null +++ b/snprintfv/AUTHORS @@ -0,0 +1,8 @@ +Authors of libsnprintfv. See individual files for their licenses. + +Gary V. Vaughan : + Designed, implemented and maintained libsnprintfv up to the 0.98h release. + +Paolo Bonzini and +Bruce Korb : + Are currently maintaining libsnprintfv (starting from Summer 2002). diff --git a/snprintfv/Makefile.am b/snprintfv/Makefile.am new file mode 100644 index 0000000..f86f008 --- /dev/null +++ b/snprintfv/Makefile.am @@ -0,0 +1,47 @@ +## -*- Mode: Makefile -*- +## --------------------------------------------------------------------- +## Makefile.am -- process this file with automake to produce Makefile.in +## Copyright (C) 1998, 1999, 2000, 2002 Gary V. Vaughan +## Originally by Gary V. Vaughan, 1998 +## This file is part of Snprintfv +## +## Snprintfv 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. +## +## Snprintfv program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program. If not, see . +## +## As a special exception to the GNU General Public License, if you +## distribute this file as part of a program that also links with and +## uses the libopts library from AutoGen, you may include it under +## the same distribution terms used by the libopts library. + +## Code: + +AM_CPPFLAGS = -I$(top_srcdir) +noinst_HEADERS = mem.h filament.h stream.h printf.h compat.h +dist_noinst_DATA = filament.stamp stream.stamp printf.stamp +noinst_LTLIBRARIES = libsnprintfv.la +libsnprintfv_la_LDFLAGS = -no-undefined +CSRC = filament.c format.c printf.c mem.c stream.c custom.c + +nodist_libsnprintfv_la_SOURCES = snv.c + +# These files are the raw sources used to generate similarly named +# header files after extracting the prototypes from the sources +# +EXTRA_DIST = filament.in printf.in stream.in $(CSRC) + +snv.c : $(CSRC) + for f in $(CSRC) ; do echo "#include \"$$f\"" ; done > $@ + +.NOTPARALLEL: + +# Makefile.am ends here diff --git a/snprintfv/Makefile.in b/snprintfv/Makefile.in new file mode 100644 index 0000000..4139804 --- /dev/null +++ b/snprintfv/Makefile.in @@ -0,0 +1,686 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 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. + +@SET_MAKE@ + + + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = snprintfv +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/ag_macros.m4 \ + $(top_srcdir)/config/asm-underscore.m4 \ + $(top_srcdir)/config/extensions.m4 \ + $(top_srcdir)/config/guile.m4 \ + $(top_srcdir)/config/host-cpu-c-abi.m4 \ + $(top_srcdir)/config/lib-ld.m4 \ + $(top_srcdir)/config/lib-link.m4 \ + $(top_srcdir)/config/lib-prefix.m4 \ + $(top_srcdir)/config/libopts.m4 \ + $(top_srcdir)/config/libtool.m4 \ + $(top_srcdir)/config/ltoptions.m4 \ + $(top_srcdir)/config/ltsugar.m4 \ + $(top_srcdir)/config/ltversion.m4 \ + $(top_srcdir)/config/lt~obsolete.m4 \ + $(top_srcdir)/config/onceonly.m4 $(top_srcdir)/config/pkg.m4 \ + $(top_srcdir)/config/snprintfv.m4 \ + $(top_srcdir)/config/stdnoreturn.m4 \ + $(top_srcdir)/config/unlocked-io.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(dist_noinst_DATA) \ + $(noinst_HEADERS) $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +libsnprintfv_la_LIBADD = +nodist_libsnprintfv_la_OBJECTS = snv.lo +libsnprintfv_la_OBJECTS = $(nodist_libsnprintfv_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libsnprintfv_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ + $(AM_CFLAGS) $(CFLAGS) $(libsnprintfv_la_LDFLAGS) $(LDFLAGS) \ + -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/config/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/snv.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(nodist_libsnprintfv_la_SOURCES) +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +DATA = $(dist_noinst_DATA) +HEADERS = $(noinst_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/config/depcomp \ + AUTHORS README THANKS +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AGEN5_TESTS = @AGEN5_TESTS@ +AG_LDFLAGS = @AG_LDFLAGS@ +AG_MAJOR_VERSION = @AG_MAJOR_VERSION@ +AG_MINOR_VERSION = @AG_MINOR_VERSION@ +AG_STATIC_AUTOGEN = @AG_STATIC_AUTOGEN@ +AG_TIMEOUT = @AG_TIMEOUT@ +AG_VERSION = @AG_VERSION@ +AG_XML2 = @AG_XML2@ +AGexe = @AGexe@ +AGnam = @AGnam@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AO_AGE = @AO_AGE@ +AO_CURRENT = @AO_CURRENT@ +AO_REVISION = @AO_REVISION@ +AO_TEMPLATE_VERSION = @AO_TEMPLATE_VERSION@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLexe = @CLexe@ +CLnam = @CLnam@ +CONFIG_SHELL = @CONFIG_SHELL@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBUG_ENABLED = @DEBUG_ENABLED@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +DYNAMIC_AG = @DYNAMIC_AG@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_STATIC = @ENABLE_STATIC@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GDexe = @GDexe@ +GDnam = @GDnam@ +GO_AGE = @GO_AGE@ +GO_CURRENT = @GO_CURRENT@ +GO_REVISION = @GO_REVISION@ +GREP = @GREP@ +GUILE_CFLAGS = @GUILE_CFLAGS@ +GUILE_EFFECTIVE_VERSION = @GUILE_EFFECTIVE_VERSION@ +GUILE_LDFLAGS = @GUILE_LDFLAGS@ +GUILE_LIBS = @GUILE_LIBS@ +GUILE_LTLIBS = @GUILE_LTLIBS@ +HOST_CPU = @HOST_CPU@ +HOST_CPU_C_ABI = @HOST_CPU_C_ABI@ +INCLIST = @INCLIST@ +INCSNPRINTFV = @INCSNPRINTFV@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSNPRINTFV = @LIBSNPRINTFV@ +LIBTOOL = @LIBTOOL@ +LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ +LIBXML2_LIBS = @LIBXML2_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +M4_SRC = @M4_SRC@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPTS_TESTDIR = @OPTS_TESTDIR@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSIX_SHELL = @POSIX_SHELL@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STDNORETURN_H = @STDNORETURN_H@ +STRIP = @STRIP@ +TEXI2HTML = @TEXI2HTML@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_aux_dir = @ac_aux_dir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AM_CPPFLAGS = -I$(top_srcdir) +noinst_HEADERS = mem.h filament.h stream.h printf.h compat.h +dist_noinst_DATA = filament.stamp stream.stamp printf.stamp +noinst_LTLIBRARIES = libsnprintfv.la +libsnprintfv_la_LDFLAGS = -no-undefined +CSRC = filament.c format.c printf.c mem.c stream.c custom.c +nodist_libsnprintfv_la_SOURCES = snv.c + +# These files are the raw sources used to generate similarly named +# header files after extracting the prototypes from the sources +# +EXTRA_DIST = filament.in printf.in stream.in $(CSRC) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu snprintfv/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu snprintfv/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libsnprintfv.la: $(libsnprintfv_la_OBJECTS) $(libsnprintfv_la_DEPENDENCIES) $(EXTRA_libsnprintfv_la_DEPENDENCIES) + $(AM_V_CCLD)$(libsnprintfv_la_LINK) $(libsnprintfv_la_OBJECTS) $(libsnprintfv_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/snv.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) $(DATA) $(HEADERS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/snv.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/snv.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-noinstLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +snv.c : $(CSRC) + for f in $(CSRC) ; do echo "#include \"$$f\"" ; done > $@ + +.NOTPARALLEL: + +# Makefile.am ends here + +# 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/snprintfv/README b/snprintfv/README new file mode 100644 index 0000000..9251106 --- /dev/null +++ b/snprintfv/README @@ -0,0 +1,30 @@ +This is libsnprintfv, a portable, extensible reimplementation of the +POSIX format printing API. libsnprintfv provides all the features +which should be present in a POSIX format printing implementation, +but which often are not, such as guaranteed return of number of +characters printed and support for %n$ format specifiers. + +In addition the the POSIX features, libsnprintfv also provides some +extensions to the API, and a GNU glibc-2 compatible printf custom +format specifier, all of which you can use with impunity if you link +with libsnprintfv, rather than worrying about whether the target C +library provides the extensions. See the info manual for details of +the API calls available, and an explanation of how to write custom +specifier handlers. + +The latest version of libsnprintfv is available from the author's +homepage: http://www.oranda.demon.co.uk. + +libsnprintfv is written in a very portable K&R compatible style, and +should build anywhere that provides a reasonable C compiler and runtime. +See the file INSTALL for instructions on how to build and install +libsnprintfv. + +See the file NEWS for a description of user visible changes to +libsnprintfv between releases. + +See the file TODO for a list of outstanding work. + +If you have any suggestions or bug reports, please send email to the +author at . + diff --git a/snprintfv/THANKS b/snprintfv/THANKS new file mode 100644 index 0000000..0480bbe --- /dev/null +++ b/snprintfv/THANKS @@ -0,0 +1,13 @@ +libsnprintfv would not be what it is without the invaluable help of +these people: + +Everybody who was kind enough to spend time testing libsnprintfv, +use it in their packages and report bugs. + +The following people made especially gracious contributions of their +time and energy in helping to track down bugs, port to new systems, +and generally assist in the maintainership process: + +Bruce Korb +Kaveh R. Ghazi +Robert Lipe diff --git a/snprintfv/compat.h b/snprintfv/compat.h new file mode 100644 index 0000000..e3fa52f --- /dev/null +++ b/snprintfv/compat.h @@ -0,0 +1,329 @@ +/* -*- Mode: C -*- + * -------------------------------------------------------------------- + * compat.h.in --- verbose but portable cpp defines for snprintfv + * Copyright (C) 1999 Gary V. Vaughan + * Originally by Gary V. Vaughan, 1999 + * This file is part of Snprintfv + * + * Snprintfv 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. + * + * Snprintfv program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * As a special exception to the GNU General Public License, if you + * distribute this file as part of a program that also links with and + * uses the libopts library from AutoGen, you may include it under + * the same distribution terms used by the libopts library. + * + * Code: */ + +#ifndef SNPRINTFV_COMPAT_H +#define SNPRINTFV_COMPAT_H 1 + +#define _GNU_SOURCE 1 /* for strsignal in GNU's libc */ +#define __USE_GNU 1 // likewise +#define __EXTENSIONS__ 1 /* and another way to call for it */ + +#ifdef __cplusplus +#define SNV_START_EXTERN_C extern "C" { +SNV_START_EXTERN_C +#define SNV_END_EXTERN_C } +#else +#define SNV_END_EXTERN_C +#endif /* __cplusplus */ + +#define NO_FLOAT_PRINTING + +#ifdef HAVE_SYS_TYPES_H +# include +#endif + +#include + +#ifdef HAVE_STDLIB_H +# include +#endif + +#ifdef HAVE_ERRNO_H +# include +# ifndef errno + /* Some sytems #define this! */ + extern int errno; +# endif +#endif + +#if defined( HAVE_LIMITS_H ) +# include + +#elif defined( HAVE_SYS_LIMITS_H ) +# include + +#elif defined( HAVE_VALUES_H ) +# ifndef MAXINT +# include +# endif /* MAXINT */ +#endif + +#if defined( HAVE_STRING_H ) +# include + +#elif defined( HAVE_STRINGS_H ) +# include +#endif + +#if defined( HAVE_MEMORY_H ) +# include +#endif + +#if defined( HAVE_INTTYPES_H ) +# include + +#elif defined( HAVE_STDINT_H ) +# include +#endif + +#ifndef HAVE_UINTMAX_T +# if defined( HAVE_LONG_LONG ) + typedef long long intmax_t; + typedef unsigned long long uintmax_t; +# else + typedef long intmax_t; + typedef unsigned long uintmax_t; +# endif +#endif + +#if defined( HAVE_STDARG_H ) +# include +# ifndef VA_START +# define VA_START(a, f) va_start(a, f) +# define VA_END(a) va_end(a) +# endif /* VA_START */ +# define SNV_USING_STDARG_H +#elif defined( HAVE_VARARGS_H ) +# include +# ifndef VA_START +# define VA_START(a, f) va_start(a) +# define VA_END(a) va_end(a) +# endif /* VA_START */ +# undef SNV_USING_STDARG_H +#else +# include "must-have-stdarg-or-varargs" +#endif + +#if HAVE_RUNETYPE_H +# include +#endif + +#ifdef HAVE_WCHAR_H +# include +#endif + +#ifdef HAVE_WCHAR_T +typedef wchar_t snv_wchar_t; +#else +typedef int snv_wchar_t; +#endif + +#ifdef HAVE_WINT_T +typedef wint_t snv_wint_t; +#else +typedef int snv_wint_t; +#endif + +/* inline and const keywords are (mostly) handled by config.h */ +#ifdef __GNUC__ + +# define GCC_VERSION (__GNUC__ * 10000 \ + + __GNUC_MINOR__ * 100 \ + + __GNUC_PATCHLEVEL__) + +# if GCC_VERSION > 40400 +# pragma GCC diagnostic ignored "-Wextra" +# pragma GCC diagnostic ignored "-Wconversion" +# pragma GCC diagnostic ignored "-Wsign-conversion" +# pragma GCC diagnostic ignored "-Wstrict-overflow" +# endif + +# ifndef const +# define const __const +# endif +# ifndef inline +# define inline __inline +# endif +# ifndef signed +# define signed __signed +# endif + +#else +# define GCC_VERSION 0 +# ifndef __STDC__ +# undef signed +# define signed +# endif +#endif + +#ifdef __STDC__ +# define _SNV_STR(x) #x + typedef void *snv_pointer; + typedef const void *snv_constpointer; +#else +# define _SNV_STR(x) "x" + typedef char *snv_pointer; + typedef char *snv_constpointer; +#endif + +#if defined(HAVE_FPUTC_UNLOCKED) && defined(HAVE_FLOCKFILE) +# define SNV_FPUTC_UNLOCKED fputc_unlocked +# define SNV_PUTC_UNLOCKED putc_unlocked +# define SNV_WITH_LOCKED_FP(fp, tmp_var) \ + for (flockfile (fp), tmp_var = 1; \ + tmp_var--; funlockfile (fp)) +#else +# define SNV_FPUTC_UNLOCKED fputc +# define SNV_PUTC_UNLOCKED putc +# define SNV_WITH_LOCKED_FP(fp, tmp_var) \ + for (tmp_var = 1; tmp_var--; ) +#endif + +/* + * Define macros for storing integers inside pointers. + * Be aware that it is only safe to use these macros to store `int' + * values in `char*' (or `void*') words, and then extract them later. + * Although it will work the other way round on many common + * architectures, it is not portable to assume a `char*' can be + * stored in an `int' and extracted later without loss of the msb's + */ +#define SNV_POINTER_TO_LONG(p) ((long)(p)) +#define SNV_POINTER_TO_ULONG(p) ((unsigned long)(p)) +#define SNV_LONG_TO_POINTER(i) ((snv_pointer)(long)(i)) +#define SNV_ULONG_TO_POINTER(u) ((snv_pointer)(unsigned long)(u)) + +#ifdef HAVE_STDBOOL_H +#include +#else +typedef enum { + false = 0, + true = 1 +} bool; +#endif + +#ifdef __CYGWIN32__ +# ifndef __CYGWIN__ +# define __CYGWIN__ +# endif +#endif +#ifdef __CYGWIN__ +# ifndef _WIN32 +# define _WIN32 +# endif +#endif + +#ifndef PARAMS +# define PARAMS(args) args +#endif + +#undef SNV_STMT_START +#undef SNV_STMT_END +#if defined (__GNUC__) && !defined (__STRICT_ANSI__) && !defined (__cplusplus) +# define SNV_STMT_START (void)( +# define SNV_STMT_END ) + +#elif (defined (sun) || defined (__sun__)) +# define SNV_STMT_START if (1) +# define SNV_STMT_END else (void)0 + +#else +# define SNV_STMT_START do +# define SNV_STMT_END while (false) +#endif + +#ifdef _WIN32 +# ifdef DLL_EXPORT +# define SNV_SCOPE extern __declspec(dllexport) +# else +# ifdef LIBSNPRINTFV_DLL_IMPORT +# define SNV_SCOPE extern __declspec(dllimport) +# endif +# endif +#endif +#ifndef SNV_SCOPE +# define SNV_SCOPE extern +#endif + +#undef SNV_GNUC_PRINTF +#undef SNV_GNUC_NORETURN +#if GCC_VERSION > 20400 +# define SNV_GNUC_PRINTF( args, format_idx, arg_idx ) \ + args __attribute__((format (printf, format_idx, arg_idx))) +# define SNV_GNUC_NORETURN \ + __attribute__((__noreturn__)) +# define SNV_ASSERT_FCN " (", __PRETTY_FUNCTION__, ")" +#else /* GCC_VERSION */ +# define SNV_GNUC_PRINTF( args, format_idx, arg_idx ) args +# define SNV_GNUC_NORETURN +# define SNV_ASSERT_FCN "", "", "" +#endif /* GCC_VERSION */ + +#define SNV_ASSERT_FMT "file %s: line %d%s%s%s: assertion \"%s\" failed.\n" + +#define snv_assert(expr) snv_fassert(stderr, expr) +#define snv_fassert(stream, expr) SNV_STMT_START { \ + if (!(expr)) { \ + fprintf (stream, SNV_ASSERT_FMT, __FILE__, __LINE__, \ + SNV_ASSERT_FCN, _SNV_STR(expr)); \ + exit(EXIT_FAILURE); \ + }; } SNV_STMT_END + +#define return_if_fail(expr) freturn_if_fail(stderr, expr) +#define freturn_if_fail(expr) SNV_STMT_START { \ + if (!(expr)) { \ + fprintf (stream, SNV_ASSERT_FMT, __FILE__, __LINE__, \ + SNV_ASSERT_FCN, _SNV_STR(expr)); \ + return; \ + }; } SNV_STMT_END + +#define return_val_if_fail(expr, val) freturn_val_if_fail(stderr, expr, val) +#define freturn_val_if_fail(stream, expr, val) SNV_STMT_START { \ + if (!(expr)) { \ + fprintf (stream, SNV_ASSERT_FMT, __FILE__, __LINE__, \ + SNV_ASSERT_FCN, _SNV_STR(expr)); \ + return val; \ + }; } SNV_STMT_END + +#ifndef MAX +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#endif + +#ifndef MIN +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif + +#ifndef ABS +#define ABS(a) ((a) < 0 ? -(a) : (a)) +#endif + +typedef SNV_LONG_DOUBLE snv_long_double; + +#ifndef HAVE_STRTOUL +extern unsigned long +strtoul( const char *nptrm, char **endptr, register int base ); +#endif + +SNV_END_EXTERN_C +#endif /* SNPRINTFV_COMPAT_H */ + +/* + * Local Variables: + * mode: C + * c-file-style: "gnu" + * indent-tabs-mode: nil + * End: + * end of snprintfv/compat.h */ diff --git a/snprintfv/custom.c b/snprintfv/custom.c new file mode 100644 index 0000000..b50a78b --- /dev/null +++ b/snprintfv/custom.c @@ -0,0 +1,181 @@ +/* -*- Mode: C -*- */ + +/* custom.c --- printf clone for argv arrays + * Copyright (C) 2003 Gary V. Vaughan + * Originally by Paolo Bonzini, 2002 + * This file is part of Snprintfv + * + * Snprintfv 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. + * + * Snprintfv program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * As a special exception to the GNU General Public License, if you + * distribute this file as part of a program that also links with and + * uses the libopts library from AutoGen, you may include it under + * the same distribution terms used by the libopts library. + */ + +/* Code: */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef WITH_DMALLOC +# include +#endif + +#include + +#if HAVE_RUNETYPE_H +# include +#endif + +#ifdef HAVE_WCHAR_H +# include +#endif + +#include "printf.h" + + + +/** + * printf_generic_info: + * @pinfo: the current state information for the format + * string parser. + * @n: the number of available slots in the @argtypes array + * @argtypes: the pointer to the first slot to be filled by the + * function + * + * An example implementation of a %printf_arginfo_function, which + * takes the basic type from the type given in the %spec_entry + * and adds flags depending on what was parsed (e.g. %PA_FLAG_SHORT + * is %pparser->is_short and so on). + * + * Return value: + * Always 1. + */ +int +printf_generic_info (struct printf_info *const pinfo, size_t n, int *argtypes) +{ + int type = pinfo->type; + + if (!n) + return 1; + + if ((type & PA_TYPE_MASK) == PA_POINTER) + type |= PA_FLAG_UNSIGNED; + + if (pinfo->is_char) + type = PA_CHAR; + + if (pinfo->is_short) + type |= PA_FLAG_SHORT; + + if (pinfo->is_long) + type |= PA_FLAG_LONG; + + if (pinfo->is_long_double) + type |= PA_FLAG_LONG_LONG; + + argtypes[0] = type; + return 1; +} + + +/** + * printf_generic: + * @stream: the stream (possibly a struct printfv_stream appropriately + * cast) on which to write output. + * @pinfo: the current state information for the format string parser. + * @args: the pointer to the first argument to be read by the handler + * + * An example implementation of a %printf_function, used to provide easy + * access to justification, width and precision options. + * + * Return value: + * The number of characters output. + **/ +int +printf_generic (STREAM *stream, struct printf_info *const pinfo, union printf_arg const *args) +{ + int len = 0, count_or_errorcode = SNV_OK; + char *p = NULL; + + /* Used to interface to the custom function. */ + STREAM *out; + Filament *fil; + printf_function *user_func = (printf_function *) pinfo->extra; + + return_val_if_fail (pinfo != NULL, SNV_ERROR); + + /* Read these now to advance the argument pointer appropriately */ + if (pinfo->prec == -1) + pinfo->prec = 0; + + /* Check for valid pre-state. */ + if (pinfo->prec <= -1) + { + PRINTF_ERROR (pinfo, "invalid flags"); + return -1; + } + + /* Print to a stream using a user-supplied function. */ + fil = filnew (NULL, (size_t)0); + out = stream_new (fil, SNV_UNLIMITED, NULL, snv_filputc); + user_func (out, pinfo, args); + stream_delete (out); + len = (int)fillen (fil); + p = fildelete (fil); + + /* Left pad to the width if the supplied argument is less than + the width specifier. */ + if (p != NULL && pinfo->prec && pinfo->prec < len) + len = pinfo->prec; + + if ((len < pinfo->width) && !pinfo->left) + { + int padwidth = pinfo->width - len; + while ((count_or_errorcode >= 0) && (count_or_errorcode < padwidth)) + SNV_EMIT (pinfo->pad, stream, count_or_errorcode); + } + + /* Fill the buffer with as many characters from the format argument + * as possible without overflowing or exceeding the precision. + */ + if ((count_or_errorcode >= 0) && (p != NULL)) + { + int mark = count_or_errorcode; + while ((count_or_errorcode >= 0) && *p != '\0' + && ((pinfo->prec == 0) || (count_or_errorcode - mark < len))) + SNV_EMIT (*p++, stream, count_or_errorcode); + } + + /* Right pad to the width if we still didn't reach the specified + * width and the left justify flag was set. + */ + if ((count_or_errorcode < pinfo->width) && pinfo->left) + while ((count_or_errorcode >= 0) + && (count_or_errorcode < pinfo->width)) + SNV_EMIT (pinfo->pad, stream, count_or_errorcode); + + /* Return the number of characters emitted. */ + return count_or_errorcode; +} + +/* + * Local Variables: + * mode: C + * c-file-style: "gnu" + * indent-tabs-mode: nil + * End: + * end of snprintfv/custom.c */ diff --git a/snprintfv/filament.c b/snprintfv/filament.c new file mode 100644 index 0000000..4f6af29 --- /dev/null +++ b/snprintfv/filament.c @@ -0,0 +1,231 @@ +/* -*- Mode: C -*- */ + +/* filament.c --- a bit like a string, but different =)O| + * Copyright (C) 1999 Gary V. Vaughan + * Originally by Gary V. Vaughan, 1999 + * This file is part of Snprintfv + * + * Snprintfv 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. + * + * Snprintfv program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * As a special exception to the GNU General Public License, if you + * distribute this file as part of a program that also links with and + * uses the libopts library from AutoGen, you may include it under + * the same distribution terms used by the libopts library. + */ + +/* Commentary: + * + * Try to exploit usage patterns to optimise string handling, and + * as a happy consequence handle NUL's embedded in strings properly. + * + * o Since finding the length of a (long) string is time consuming and + * requires careful coding to cache the result in local scope: We + * keep count of the length of a Filament all the time, so finding the + * length is O(1) at the expense of a little bookkeeping while + * manipulating the Filament contents. + * + * o Constantly resizing a block of memory to hold a string is memory + * efficient, but slow: Filaments are only ever expanded in size, + * doubling at each step to minimise the number of times the block + * needs to be reallocated and the contents copied (this problem is + * especially poignant for very large strings). + * + * o Most strings tend to be either relatively small and short-lived, + * or else long-lived but growing in asymptotically in size: To + * care for the former case, Filaments start off with a modest static + * buffer for the string contents to avoid any mallocations (except + * the initial one to get the structure!); the latter case is handled + * gracefully by the resizing algorithm in the previous point. + * + * o Extracting a C-style NUL terminated string from the Filament is + * an extremely common operation: We ensure there is always a + * terminating NUL character after the last character in the string + * so that the conversion can be performed quickly. + * + * In summary, Filaments are good where you need to do a lot of length + * calculations with your strings and/or gradually append more text + * onto existing strings. Filaments are also an easy way to get 8-bit + * clean strings is a more lightweight approach isn't required. + * + * They probably don't buy much if you need to do insertions and partial + * deletions, but optimising for that is a whole other problem! + */ + +/* Code: */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef WITH_DMALLOC +# include +#endif + +#include "mem.h" +#include "filament.h" + + + +/** + * filnew: constructor + * @init: address of the first byte to copy into the new object. + * @len: the number of bytes to copy into the new object. + * + * Create a new Filament object, initialised to hold a copy of the + * first @len bytes starting at address @init. If @init is NULL, or + * @len is 0 (or less), then the initialised Filament will return the + * empty string, "", if its value is queried. + * + * Return value: + * A newly created Filament object is returned. + **/ +Filament * +filnew (const char *const init, size_t len) +{ + Filament *new; + + new = snv_new (Filament, 1); + + new->value = new->buffer; + new->length = 0; + new->size = FILAMENT_BUFSIZ; + + return (init || len) ? filinit (new, init, len) : new; +} + +/** + * filinit: + * @fil: The Filament object to initialise. + * @init: address of the first byte to copy into the new object. + * @len: the number of bytes to copy into the new object. + * + * Initialise a Filament object to hold a copy of the first @len bytes + * starting at address @init. If @init is NULL, or @len is 0 (or less), + * then the Filament will be reset to hold the empty string, "". + * + * Return value: + * The initialised Filament object is returned. + **/ +Filament * +filinit (Filament *fil, const char *const init, size_t len) +{ + if (init == NULL || len < 1) + { + /* Recycle any dynamic memory assigned to the previous + contents of @fil, and point back into the static buffer. */ + if (fil->value != fil->buffer) + snv_delete (fil->value); + + fil->value = fil->buffer; + fil->length = 0; + fil->size = FILAMENT_BUFSIZ; + } + else + { + if (len < FILAMENT_BUFSIZ) + { + /* We have initialisation data which will easily fit into + the static buffer: recycle any memory already assigned + and initialise in the static buffer. */ + if (fil->value != fil->buffer) + { + snv_delete (fil->value); + fil->value = fil->buffer; + fil->size = FILAMENT_BUFSIZ; + } + } + else + { + /* If we get to here then we never try to shrink the already + allocated dynamic buffer (if any), we just leave it in + place all ready to expand into later... */ + fil_maybe_extend (fil, len, false); + } + + snv_assert (len < fil->size); + + fil->length = len; + memcpy (fil->value, init, len); + } + + return fil; +} + +/** + * fildelete: destructor + * @fil: The Filament object for recycling. + * + * The memory being used by @fil is recycled. + * + * Return value: + * The original contents of @fil are converted to a null terminated + * string which is returned, either to be freed itself or else used + * as a normal C string. The entire Filament contents are copied into + * this string including any embedded nulls. + **/ +char * +fildelete (Filament *fil) +{ + char *value; + + if (fil->value == fil->buffer) + { + value = memcpy (snv_new (char, 1 + fil->length), + fil->buffer, 1 + fil->length); + value[fil->length] = '\0'; + } + else + value = filval (fil); + + snv_delete (fil); + + return value; +} + +/** + * _fil_extend: + * @fil: The Filament object which may need more string space. + * @len: The length of the data to be stored in @fil. + * @copy: whether to copy data from the static buffer on reallocation. + * + * This function will will assign a bigger block of memory to @fil + * considering the space left in @fil and @len, the length required + * for the prospective contents. + */ +void +_fil_extend (Filament *fil, size_t len, bool copy) +{ + /* Usually we will simply double the amount of space previously + allocated, but if the extra data is larger than the current + size it *still* won't fit, so in that case we allocate enough + room plus some we leave the current free space to expand into. */ + fil->size += MAX (len, fil->size); + + if (fil->value == fil->buffer) + { + fil->value = snv_new (char, fil->size); + if (copy) + memcpy (fil->value, fil->buffer, fil->length); + } + else + fil->value = snv_renew (char, fil->value, fil->size); +} + +/* + * Local Variables: + * mode: C + * c-file-style: "gnu" + * indent-tabs-mode: nil + * End: + * end of snprintfv/filament.c */ diff --git a/snprintfv/filament.h b/snprintfv/filament.h new file mode 100644 index 0000000..d00aefc --- /dev/null +++ b/snprintfv/filament.h @@ -0,0 +1,256 @@ +/* -*- Mode: C -*- */ + +/* filament.h --- a bit like a string but different =)O| + * Copyright (C) 1998, 1999, 2000, 2002 Gary V. Vaughan + * Originally by Gary V. Vaughan, 1998 + * This file is part of Snprintfv + * + * Snprintfv 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. + * + * Snprintfv program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * As a special exception to the GNU General Public License, if you + * distribute this file as part of a program that also links with and + * uses the libopts library from AutoGen, you may include it under + * the same distribution terms used by the libopts library. + */ + +/* Code: */ + +#ifndef FILAMENT_H +#define FILAMENT_H 1 + +#include + +#ifdef __cplusplus +extern "C" +{ +#if 0 +/* This brace is so that emacs can still indent properly: */ } +#endif +#endif /* __cplusplus */ + +#define FILAMENT_BUFSIZ (512 - sizeof(char *) - (2 * sizeof(size_t))) + +/** + * Filament: + * Opaque data type used to hold 8-bit clean dynamic strings which know + * their own length and resize themselves to avoid buffer overruns. + **/ +typedef struct filament Filament; + +struct filament +{ + char *value; /* pointer to the start of the string */ + size_t length; /* length of the string */ + size_t size; /* total memory allocated */ + char buffer[FILAMENT_BUFSIZ]; /* usually string == &buffer[0] */ +}; + +/** + * filnew: constructor + * @init: address of the first byte to copy into the new object. + * @len: the number of bytes to copy into the new object. + * + * Create a new Filament object, initialised to hold a copy of the + * first @len bytes starting at address @init. If @init is NULL, or + * @len is 0 (or less), then the initialised Filament will return the + * empty string, "", if its value is queried. + * + * Return value: + * A newly created Filament object is returned. + **/ +extern Filament * +filnew (const char *const init, size_t len); + +/** + * filinit: + * @fil: The Filament object to initialise. + * @init: address of the first byte to copy into the new object. + * @len: the number of bytes to copy into the new object. + * + * Initialise a Filament object to hold a copy of the first @len bytes + * starting at address @init. If @init is NULL, or @len is 0 (or less), + * then the Filament will be reset to hold the empty string, "". + * + * Return value: + * The initialised Filament object is returned. + **/ +extern Filament * +filinit (Filament *fil, const char *const init, size_t len); + +/** + * fildelete: destructor + * @fil: The Filament object for recycling. + * + * The memory being used by @fil is recycled. + * + * Return value: + * The original contents of @fil are converted to a null terminated + * string which is returned, either to be freed itself or else used + * as a normal C string. The entire Filament contents are copied into + * this string including any embedded nulls. + **/ +extern char * +fildelete (Filament *fil); + +/** + * _fil_extend: + * @fil: The Filament object which may need more string space. + * @len: The length of the data to be stored in @fil. + * @copy: whether to copy data from the static buffer on reallocation. + * + * This function will will assign a bigger block of memory to @fil + * considering the space left in @fil and @len, the length required + * for the prospective contents. + */ +extern void +_fil_extend (Filament *fil, size_t len, bool copy); + +#line 60 "filament.in" + +/* Save the overhead of a function call in the great majority of cases. */ +#define fil_maybe_extend(fil, len, copy) \ + (((len)>=(fil)->size) ? _fil_extend((fil), (len), (copy)) : (void)0) + +/** + * filval: + * @fil: The Filament object being queried. + * + * Return value: + * A pointer to the null terminated string held by the Filament + * object is returned. Since the @fil may contain embedded nulls, it + * is not entirely safe to use the strfoo() API to examine the contents + * of the return value. + **/ +SNV_INLINE char * +filval (Filament *fil) +{ + /* Because we have been careful to ensure there is always at least + one spare byte of allocated memory, it is safe to set it here. */ + fil->value[fil->length] = '\0'; + return (char *) (fil->value); +} + +/** + * fillen: + * @fil: The Filament object being queried. + * + * Return value: + * The length of @fil, including any embedded nulls, but excluding the + * terminating null, is returned. + **/ +SNV_INLINE size_t +fillen (Filament *fil) +{ + return fil->length; +} + +/** + * filelt: + * @fil: The Filament being queried. + * @n: A zero based index into @fil. + * + * This function looks for the @n'th element of @fil. + * + * Return value: + * If @n is an index inside the Filament @fil, then the character stored + * at that index cast to an int is returned, otherwise @n is outside + * this range and -1 is returned. + **/ +SNV_INLINE int +filelt (Filament *fil, ssize_t n) +{ + if ((n >= 0) && (n < (ssize_t)fil->length)) + return (int) fil->value[n]; + else + return -1; +} + +/** + * filncat: + * @fil: The destination Filament of the concatenation. + * @str: The address of the source bytes for concatenation. + * @n: The number of bytes to be copied from @str. + * + * @n bytes starting with the byte at address @str are destructively + * concatenated to @fil. If necessary, @fil is dynamically reallocated + * to make room for this operation. + * + * Return value: + * A pointer to the (not null terminated) string which is the result + * of this concatenation is returned. + **/ +SNV_INLINE char * +filncat (Filament *fil, const char *str, size_t n) +{ + fil_maybe_extend (fil, n + fil->length, true); + memcpy (fil->value + fil->length, str, n); + fil->length += n; + return fil->value; +} + +/** + * filcat: + * @fil: The destination Filament of the concatenation. + * @str: The address of the source bytes for concatenation. + * + * The bytes starting at address @str upto and including the first null + * byte encountered are destructively concatenated to @fil. If + * necessary @fil is dynamically reallocated to make room for this + * operation. + * + * Return value: + * A pointer to the (not null terminated) string which is the result + * of this concatenation is returned. + **/ +SNV_INLINE char * +filcat (Filament *fil, const char *str) +{ + size_t length = strlen (str); + return filncat (fil, str, length); +} + +/** + * filccat: + * @fil: The destination Filament of the concatenation. + * @c: The character to append to @fil. + * + * @c is destructively concatenated to @fil. If necessary, @fil is + * dynamically reallocated to make room for this operation. When used + * repeatedly this function is less efficient than %filncat, + * since it must check whether to extend the filament before each + * character is appended. + * + * Return value: + * A pointer to the (not null terminated) string which is the result + * of this concatenation is returned. + **/ +SNV_INLINE char * +filccat (Filament *fil, int c) +{ + fil_maybe_extend (fil, 1 + fil->length, true); + fil->value[fil->length++] = (char)(c & 0xFF); + return fil->value; +} + +#ifdef __cplusplus +#if 0 +/* This brace is so that emacs can still indent properly: */ +{ +#endif +} +#endif /* __cplusplus */ + +#endif /* FILAMENT_H */ + +/* filament.h ends here */ diff --git a/snprintfv/filament.in b/snprintfv/filament.in new file mode 100644 index 0000000..a21a574 --- /dev/null +++ b/snprintfv/filament.in @@ -0,0 +1,196 @@ +/* -*- Mode: C -*- */ + +/* filament.h --- a bit like a string but different =)O| + * Copyright (C) 1998, 1999, 2000, 2002 Gary V. Vaughan + * Originally by Gary V. Vaughan, 1998 + * This file is part of Snprintfv + * + * Snprintfv 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. + * + * Snprintfv program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * As a special exception to the GNU General Public License, if you + * distribute this file as part of a program that also links with and + * uses the libopts library from AutoGen, you may include it under + * the same distribution terms used by the libopts library. + */ + +/* Code: */ + +#ifndef FILAMENT_H +#define FILAMENT_H 1 + +#include + +#ifdef __cplusplus +extern "C" +{ +#if 0 +/* This brace is so that emacs can still indent properly: */ } +#endif +#endif /* __cplusplus */ + +#define FILAMENT_BUFSIZ (512 - sizeof(char *) - (2 * sizeof(size_t))) + +/** + * Filament: + * Opaque data type used to hold 8-bit clean dynamic strings which know + * their own length and resize themselves to avoid buffer overruns. + **/ +typedef struct filament Filament; + +struct filament +{ + char *value; /* pointer to the start of the string */ + size_t length; /* length of the string */ + size_t size; /* total memory allocated */ + char buffer[FILAMENT_BUFSIZ]; /* usually string == &buffer[0] */ +}; + +@protos filament.c + +/* Save the overhead of a function call in the great majority of cases. */ +#define fil_maybe_extend(fil, len, copy) \ + (((len)>=(fil)->size) ? _fil_extend((fil), (len), (copy)) : (void)0) + +/** + * filval: + * @fil: The Filament object being queried. + * + * Return value: + * A pointer to the null terminated string held by the Filament + * object is returned. Since the @fil may contain embedded nulls, it + * is not entirely safe to use the strfoo() API to examine the contents + * of the return value. + **/ +SNV_INLINE char * +filval (Filament *fil) +{ + /* Because we have been careful to ensure there is always at least + one spare byte of allocated memory, it is safe to set it here. */ + fil->value[fil->length] = '\0'; + return (char *) (fil->value); +} + +/** + * fillen: + * @fil: The Filament object being queried. + * + * Return value: + * The length of @fil, including any embedded nulls, but excluding the + * terminating null, is returned. + **/ +SNV_INLINE size_t +fillen (Filament *fil) +{ + return fil->length; +} + +/** + * filelt: + * @fil: The Filament being queried. + * @n: A zero based index into @fil. + * + * This function looks for the @n'th element of @fil. + * + * Return value: + * If @n is an index inside the Filament @fil, then the character stored + * at that index cast to an int is returned, otherwise @n is outside + * this range and -1 is returned. + **/ +SNV_INLINE int +filelt (Filament *fil, ssize_t n) +{ + if ((n >= 0) && (n < (ssize_t)fil->length)) + return (int) fil->value[n]; + else + return -1; +} + +/** + * filncat: + * @fil: The destination Filament of the concatenation. + * @str: The address of the source bytes for concatenation. + * @n: The number of bytes to be copied from @str. + * + * @n bytes starting with the byte at address @str are destructively + * concatenated to @fil. If necessary, @fil is dynamically reallocated + * to make room for this operation. + * + * Return value: + * A pointer to the (not null terminated) string which is the result + * of this concatenation is returned. + **/ +SNV_INLINE char * +filncat (Filament *fil, const char *str, size_t n) +{ + fil_maybe_extend (fil, n + fil->length, true); + memcpy (fil->value + fil->length, str, n); + fil->length += n; + return fil->value; +} + +/** + * filcat: + * @fil: The destination Filament of the concatenation. + * @str: The address of the source bytes for concatenation. + * + * The bytes starting at address @str upto and including the first null + * byte encountered are destructively concatenated to @fil. If + * necessary @fil is dynamically reallocated to make room for this + * operation. + * + * Return value: + * A pointer to the (not null terminated) string which is the result + * of this concatenation is returned. + **/ +SNV_INLINE char * +filcat (Filament *fil, const char *str) +{ + size_t length = strlen (str); + return filncat (fil, str, length); +} + +/** + * filccat: + * @fil: The destination Filament of the concatenation. + * @c: The character to append to @fil. + * + * @c is destructively concatenated to @fil. If necessary, @fil is + * dynamically reallocated to make room for this operation. When used + * repeatedly this function is less efficient than %filncat, + * since it must check whether to extend the filament before each + * character is appended. + * + * Return value: + * A pointer to the (not null terminated) string which is the result + * of this concatenation is returned. + **/ +SNV_INLINE char * +filccat (Filament *fil, int c) +{ + fil_maybe_extend (fil, 1 + fil->length, true); + fil->value[fil->length++] = (char)(c & 0xFF); + return fil->value; +} + +#ifdef __cplusplus +#if 0 +/* This brace is so that emacs can still indent properly: */ +{ +#endif +} +#endif /* __cplusplus */ + +#endif /* FILAMENT_H */ + +/* filament.h ends here */ diff --git a/snprintfv/filament.stamp b/snprintfv/filament.stamp new file mode 100644 index 0000000..e69de29 diff --git a/snprintfv/format.c b/snprintfv/format.c new file mode 100644 index 0000000..e684bdf --- /dev/null +++ b/snprintfv/format.c @@ -0,0 +1,1282 @@ +/* -*- Mode: C -*- */ + +/* format.c --- printf clone for argv arrays + * Copyright (C) 1998, 1999, 2000, 2002 Gary V. Vaughan + * Originally by Gary V. Vaughan, 1998 + * This file is part of Snprintfv + * + * Snprintfv 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. + * + * Snprintfv program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * As a special exception to the GNU General Public License, if you + * distribute this file as part of a program that also links with and + * uses the libopts library from AutoGen, you may include it under + * the same distribution terms used by the libopts library. + */ + +/* Code: */ + +#include "compat.h" + +#ifdef HAVE_LIMITS_H +#include +#else +#include +#endif + +#ifdef WITH_DMALLOC +# include +#endif + +#include +#include +#include + +#if HAVE_RUNETYPE_H +# include +#endif + +#ifdef HAVE_WCHAR_H +# include +#endif + +#include "printf.h" + +#ifndef NO_FLOAT_PRINTING +# ifdef HAVE_LONG_DOUBLE +# ifndef HAVE_ISNANL +# define isnanl(x) ((x) != (x)) +# endif +# ifndef HAVE_ISINFL +# define isinfl(x) isnanl ((x) - (x)) +# endif +# ifndef HAVE_MODFL +static snv_long_double modfl (long double x, long double *exp); +# endif +# ifndef HAVE_COPYSIGNL +static snv_long_double copysignl (long double x, long double y); +# endif +# else +# ifdef HAVE_ISNAN +# define isnanl isnan +# else +# define isnanl(x) ((x) != (x)) +# endif +# ifdef HAVE_ISINF +# define isinfl isinf +# else +# define isinfl(x) isnanl ((x) - (x)) +# endif +# ifdef HAVE_COPYSIGN +# define copysignl copysign +# else +# define copysign(x, y) (((x) < 0.0 ^ (y) < 0.0) ? (x) * -1.0 : (x)); +# endif +# define modfl modf +# endif +#endif + + +static uintmax_t +fetch_uintmax (struct printf_info *pinfo, union printf_arg const *arg) +{ + if (pinfo->is_long_double) + return (uintmax_t) arg->pa_u_long_long_int; + + if (pinfo->is_long) + return (uintmax_t) arg->pa_u_long_int; + + if (pinfo->is_short) + return (uintmax_t) arg->pa_u_short_int; + + if (pinfo->is_char) + return (uintmax_t) arg->pa_char; + + return (uintmax_t) arg->pa_u_int; +} + +static intmax_t +fetch_intmax (struct printf_info *pinfo, union printf_arg const *arg) +{ + if (pinfo->is_long_double) + return (intmax_t) (signed long long) arg->pa_long_long_int; + + if (pinfo->is_long) + return (intmax_t) (signed long) arg->pa_long_int; + + if (pinfo->is_short) + return (intmax_t) (signed short) arg->pa_short_int; + + if (pinfo->is_char) + return (intmax_t) (signed char) arg->pa_char; + + return (intmax_t) (signed int) arg->pa_int; +} + +#ifndef NO_FLOAT_PRINTING +static snv_long_double +fetch_double (struct printf_info *pinfo, union printf_arg const *arg) +{ + if (pinfo->is_long_double) + return (snv_long_double) arg->pa_long_double; + else + return (snv_long_double) (arg->pa_double); +} +#endif + + +#ifndef NO_FLOAT_PRINTING + +/* These two routines are cleaned up version of the code in libio 2.95.3 + (actually I got it from the Attic, not from the released tarball). + The changes were mainly to share code between %f and %g (libio did + share some code between %e and %g), and to share code between the + %e and %f when invoked by %g. Support from infinities and NaNs comes + from the old snprintfv code. */ + +typedef struct { + int pfs_prec; + int fmtch; + int expcnt; + int gformat; + char * scan_back_pz; + char * out_pz; + char * start_pz; + char * pfs_end; + snv_long_double fract; + snv_long_double integer; + snv_long_double tmp; +} print_float_status_t; + +static char * +print_float_round (snv_long_double fract, int *exp, char *start, char *end, + char ch, int *signp) +{ + snv_long_double tmp; + if (fract) + (void) modfl (fract * 10, &tmp); + else + tmp = ch - '0'; + + if (tmp > 4) + for (;; --end) + { + if (*end == '.') + --end; + if (end == start) + { + if (exp) /* e/E; increment exponent */ + ++end, ++*exp; + + *end = '1'; + break; + } + if (++*end <= '9') + break; + *end = '0'; + } + + /* ``"%.3f", (double)-0.0004'' gives you a negative 0. */ + else if (*signp == '-') + for (;; --end) + { + if (*end == '.') + --end; + if (*end != '0') + break; + if (end == start) + *signp = 0; + } + return (start); +} + +static void +fiddle_precision (print_float_status_t * pfs) +{ + /* %e/%f/%#g add 0's for precision, others trim 0's */ + if (pfs->gformat && !pinfo->alt) + { + while (pfs->out_pz > pfs->start_pz && *--pfs->out_pz == '0'); + if (*pfs->out_pz != '.') + ++pfs->out_pz; + } + else + for (; pfs->pfs_prec--; *pfs->out_pz++ = '0'); +} + +static void +do_fformat (print_float_status_t * pfs) +{ + /* reverse integer into beginning of buffer */ + if (pfs->expcnt) + for (; ++pfs->scn_bk_pz < pfs->pfs_end; *pfs->out_pz++ = *pfs->scn_bk_pz); + else + *pfs->out_pz++ = '0'; + + /* If precision required or alternate flag set, add in a + decimal point. */ + if (pinfo->prec || pinfo->alt) + *pfs->out_pz++ = '.'; + + /* if requires more precision and some fraction left */ + if (pfs->fract) + { + if (pfs->pfs_prec) + { + /* For %g, if no integer part, don't count initial + zeros as significant digits. */ + do + { + pfs->fract = modfl (pfs->fract * 10, &pfs->tmp); + *pfs->out_pz++ = '0' + ((int) pfs->tmp); + } + while (!pfs->tmp && !pfs->expcnt && pfs->gformat); + + while (--pfs->pfs_prec && pfs->fract) + { + pfs->fract = modfl (pfs->fract * 10, &pfs->tmp); + *pfs->out_pz++ = '0' + ((int) pfs->tmp); + } + } + + if (pfs->fract) + pfs->start_pz = + print_float_round (pfs->fract, (int *) NULL, pfs->start_pz, + pfs->out_pz - 1, (char) 0, signp); + } + + fiddle_precision (pfp); +} + +static void +do_eformat (print_float_status_t * pfs) +{ + if (pfs->expcnt) + { + *pfs->out_pz++ = *++pfs->scn_bk_pz; + if (pinfo->prec || pinfo->alt) + *pfs->out_pz++ = '.'; + + /* if requires more precision and some integer left */ + for (; pfs->pfs_prec && ++pfs->scn_bk_pz < pfs->pfs_end; --pfs->pfs_prec) + *pfs->out_pz++ = *pfs->scn_bk_pz; + + /* if done precision and more of the integer component, + round using it; adjust fract so we don'pfs->out_pz re-round + later. */ + if (!pfs->pfs_prec && ++pfs->scn_bk_pz < pfs->pfs_end) + { + pfs->fract = 0; + pfs->start_pz = print_float_round ( + (snv_long_double) 0, &pfs->expcnt, pfs->start_pz, pfs->out_pz - 1, + *pfs->scn_bk_pz, signp); + } + + /* adjust expcnt for digit in front of decimal */ + --pfs->expcnt; + } + + /* until first fractional digit, decrement exponent */ + else if (pfs->fract) + { + /* adjust expcnt for digit in front of decimal */ + for (pfs->expcnt = -1;; --pfs->expcnt) + { + pfs->fract = modfl (pfs->fract * 10, &pfs->tmp); + if (pfs->tmp) + break; + } + *pfs->out_pz++ = '0' + ((int) pfs->tmp); + if (pinfo->prec || pinfo->alt) + *pfs->out_pz++ = '.'; + } + + else + { + *pfs->out_pz++ = '0'; + if (pinfo->prec || pinfo->alt) + *pfs->out_pz++ = '.'; + } + + /* if requires more precision and some fraction left */ + if (pfs->fract) + { + if (pfs->pfs_prec) + do + { + pfs->fract = modfl (pfs->fract * 10, &pfs->tmp); + *pfs->out_pz++ = '0' + ((int) pfs->tmp); + } + while (--pfs->pfs_prec && pfs->fract); + + if (pfs->fract) + pfs->start_pz = print_float_round ( + pfs->fract, &pfs->expcnt, pfs->start_pz, pfs->out_pz - 1, + (char) 0, signp); + } + + fiddle_precision (pfp); + + if (pfs.fmtch != 'e' && pfs.fmtch != 'E') + return; + + { + char expbuf[10]; + *pfs.out_pz++ = pfs.fmtch; + if (pfs.expcnt < 0) + { + pfs.expcnt = -pfs.expcnt; + *pfs.out_pz++ = '-'; + } + else + *pfs.out_pz++ = '+'; + + pfs.scn_bk_pz = expbuf; + do + *pfs.scn_bk_pz++ = '0' + (pfs.expcnt % 10); + while ((pfs.expcnt /= 10) > 9); + *pfs.scn_bk_pz++ = '0' + pfs.expcnt; + while (pfs.scn_bk_pz > expbuf) + *pfs.out_pz++ = *--pfs.scn_bk_pz; + } +} + +static void +do_gformat (print_float_status_t * pfs) +{ + pfs->gformat = 1; + + /* a precision of 0 is treated as a precision of 1. */ + if (!pfs->pfs_prec) + pinfo->prec = ++pfs->pfs_prec; + + /* ``The style used depends on the value converted; style e + will be used only if the exponent resulting from the + conversion is less than -4 or greater than the precision.'' + -- ANSI X3J11 */ + if ( (pfs->expcnt > pfs->pfs_prec) + || (!pfs->expcnt && pfs->fract && pfs->fract < .0001L)) + { + /* g/G format counts "significant digits, not digits of + precision; for the e/E format, this just causes an + off-by-one problem, i.e. g/G considers the digit + before the decimal point significant and e/E doesn't + count it as precision. */ + --pfs->pfs_prec; + pfs->fmtch -= 2; /* G->E, g->e */ + do_eformat (pfs); + } + else + { + /* Decrement precision */ + if (fnum != 0.0L) + pfs->pfs_prec -= (pfs->pfs_end - pfs->scn_bk_pz) - 1; + else + pfs->pfs_prec--; + + do_fformat (pfs); + } +} + +static int +print_float (struct printf_info *pinfo, char *startp, char *endp, int *signp, + snv_long_double fnum) +{ + print_float_status_t pfs = { + .pfs_prec = pinfo->prec, + .pfs_end = endp, + .fmtch = pinfo->spec, + .out_pz = startp, + .start_pz = startp, + .gformat = 0 + }; + + *signp = 0; + + /* Do the special cases: nans, infinities, zero, and negative numbers. */ + if (isnanl (fnum)) + { + /* Not-a-numbers are printed as a simple string. */ + *pfs.out_pz++ = pfs.fmtch < 'a' ? 'N' : 'n'; + *pfs.out_pz++ = pfs.fmtch < 'a' ? 'A' : 'a'; + *pfs.out_pz++ = pfs.fmtch < 'a' ? 'N' : 'n'; + return pfs.out_pz - pfs.start_pz; + } + + /* Zero and infinity also can have a sign in front of them. */ + if (copysignl (1.0, fnum) < 0.0) + { + fnum = -1.0 * fnum; + *signp = '-'; + } + + if (isinfl (fnum)) + { + /* Infinities are printed as a simple string. */ + *pfs.out_pz++ = pfs.fmtch < 'a' ? 'I' : 'i'; + *pfs.out_pz++ = pfs.fmtch < 'a' ? 'N' : 'n'; + *pfs.out_pz++ = pfs.fmtch < 'a' ? 'F' : 'f'; + goto set_signp; + } + + pfs.expcnt = 0; + pfs.fract = modfl (fnum, &pfs.integer); + + /* get an extra slot for rounding. */ + *pfs.out_pz++ = '0'; + + /* get integer portion of number; put into the end of the buffer; the + .01 is added for modfl (356.0 / 10, &integer) returning .59999999... */ + for (pfs.scn_bk_pz = pfs.pfs_end - 1; + pfs.scn_bk_pz >= pfs.start_pz && pfs.integer; + ++pfs.expcnt) + { + pfs.tmp = modfl (pfs.integer / 10, &pfs.integer); + *pfs.scn_bk_pz-- = '0' + ((int) ((pfs.tmp + .01L) * 10)); + } + + switch (pfs.fmtch) + { + case 'g': + case 'G': + do_gformat (&pfs); + break; + + case 'f': + case 'F': + do_fformat (&pfs); + break; + + case 'e': + case 'E': + do_eformat (&pfs); + break; + + default: + abort (); + } + +set_signp: + if (!*signp) + { + if (pinfo->showsign) + *signp = '+'; + else if (pinfo->space) + *signp = ' '; + } + + return (pfs.out_pz - pfs.start_pz); +} +#endif + + +static int +printf_flag_info (struct printf_info *const pinfo, size_t n, int *argtypes) +{ + return_val_if_fail (pinfo != NULL, SNV_ERROR); + (void)n; + (void)argtypes; + + if (!(pinfo->state & (SNV_STATE_BEGIN | SNV_STATE_FLAG))) + { + PRINTF_ERROR (pinfo, "invalid specifier"); + return -1; + } + + pinfo->state = SNV_STATE_FLAG; + + while (pinfo->state & SNV_STATE_FLAG) + { + switch (*pinfo->format) + { + case '#': + pinfo->alt = true; + pinfo->format++; + break; + + case '0': + if (!pinfo->left) + pinfo->pad = '0'; + pinfo->format++; + break; + + case '-': + pinfo->pad = ' '; + pinfo->left = true; + pinfo->format++; + break; + + case ' ': + pinfo->space = true; + pinfo->format++; + break; + + case '+': + pinfo->showsign = true; + pinfo->format++; + break; + + case '\'': + pinfo->group = true; + pinfo->format++; + break; + + default: + pinfo->state = ~(SNV_STATE_BEGIN | SNV_STATE_FLAG); + break; + } + } + + pinfo->format--; + + /* Return the number of characters emitted. */ + return 0; +} + +/* This function has considerably more freedom than the others in + playing with pinfo; in particular, it modifies argindex and can + return completely bogus values whose only purpose is to extend + the argtypes vector so that it has enough items for the positional + parameter of the width (in the *n$ case). It also expects that + argtypes = (base of argtypes vector) + pinfo->argindex. + + This is messy, suggestion for simplifying it are gladly accepted. */ +static int +printf_numeric_param_info (struct printf_info *const pinfo, size_t n, int *argtypes) +{ + const char *pEnd = NULL; + int found = 0, allowed_states, new_state; + unsigned int position = 0, skipped_args = 0; + long value; + + return_val_if_fail (pinfo != NULL, SNV_ERROR); + + /* If we are looking at a ``.'', then this is a precision parameter. */ + if (*pinfo->format == '.') + { + pinfo->format++; + found |= 1; + } + + /* First we might have a ``*''. */ + if (*pinfo->format == '*') + { + pinfo->format++; + found |= 2; + } + + /* Parse the number. */ + for (pEnd = pinfo->format, value = 0; *pEnd >= '0' && *pEnd <= '9'; pEnd++) + value = value * 10 + (*pEnd - '0'); + + if (pEnd > pinfo->format) + { + pinfo->format = pEnd; + found |= 4; + } + + if (value > INT_MAX) + { + PRINTF_ERROR (pinfo, "out of range"); + return -1; + } + + /* And finally a dollar sign. */ + if (*pinfo->format == '$') + { + if (value <= 0) + { + PRINTF_ERROR (pinfo, "invalid position specifier"); + return -1; + } + + position = (unsigned int)value; + pinfo->format++; + found |= 8; + } + + switch (found & 14) + { + /* We found a * specification */ + case 2: + if (pinfo->args) + value = pinfo->args[pinfo->argindex].pa_int; + if (n) + argtypes[0] = PA_INT; + pinfo->argindex++; + skipped_args = 1; + found ^= 6; + break; + + /* We found a *n$ specification */ + case 14: + if ((unsigned int)n + (unsigned int)pinfo->argindex > (position - 1)) + argtypes[(unsigned)position - 1 - (unsigned)pinfo->argindex] = PA_INT; + + /* Else there is not enough space, reallocate and retry please... + ... but we must say how much to skip. */ + if (position >= (unsigned)pinfo->argindex) + skipped_args = position - (unsigned)pinfo->argindex; + + if (pinfo->args) + value = pinfo->args[position - 1].pa_int; + found ^= 10; + break; + } + + switch (found) + { + /* We must have read a width specification. */ + case 4: + allowed_states = SNV_STATE_BEGIN | SNV_STATE_WIDTH; + new_state = ~(SNV_STATE_BEGIN | SNV_STATE_FLAG | SNV_STATE_WIDTH); + + /* How awful... */ + if (value < 0) + { + pinfo->pad = ' '; + pinfo->left = true; + value = -value; + } + + pinfo->width = (int)value; + break; + + /* We must have read a precision specification. */ + case 5: + allowed_states = SNV_STATE_PRECISION | SNV_STATE_BEGIN; + new_state = SNV_STATE_MODIFIER | SNV_STATE_SPECIFIER; + pinfo->prec = (int)value; + break; + + /* We must have read a position specification. */ + case 12: + allowed_states = SNV_STATE_BEGIN; + new_state = ~SNV_STATE_BEGIN; + pinfo->dollar = (int)position; + break; + + /* We must have read something bogus. */ + default: + PRINTF_ERROR (pinfo, "invalid specifier"); + return -1; + } + + if (!(pinfo->state & allowed_states)) + { + PRINTF_ERROR (pinfo, "invalid specifier"); + return -1; + } + + pinfo->state = new_state; + pinfo->format--; + return (int)skipped_args; +} + +static int +printf_modifier_info (struct printf_info *const pinfo, size_t n, int *argtypes) +{ + return_val_if_fail (pinfo != NULL, SNV_ERROR); + (void)n; + (void)argtypes; + + /* Check for valid pre-state. */ + if (!(pinfo->state & (SNV_STATE_BEGIN | SNV_STATE_MODIFIER))) + { + PRINTF_ERROR (pinfo, "out of range"); + return -1; + } + + while (pinfo->state != SNV_STATE_SPECIFIER) + { + switch (*pinfo->format) + { + case 'h': + if (*++pinfo->format != 'h') + { + pinfo->is_short = true; + break; + } + + pinfo->is_char = true; + pinfo->format++; + break; + + case 'z': + if (sizeof (size_t) > sizeof (char *)) + pinfo->is_long_double = true; + else + pinfo->is_long = true; + + pinfo->format++; + break; + + case 't': + if (sizeof (ptrdiff_t) > sizeof (char *)) + pinfo->is_long_double = true; + else + pinfo->is_long = true; + + pinfo->format++; + break; + + case 'l': + if (*++pinfo->format != 'l') + { + pinfo->is_long = true; + break; + } + /*FALLTHROUGH*/ + + case 'j': + case 'q': + case 'L': + pinfo->is_long_double = true; + pinfo->format++; + break; + + default: + pinfo->state = SNV_STATE_SPECIFIER; + pinfo->format--; + break; + } + } + + /* Return the number of characters emitted. */ + return 0; +} + + +static int +printf_char (STREAM *stream, struct printf_info *const pinfo, union printf_arg const *args) +{ + int count_or_errorcode = SNV_OK; + unsigned char ch = '\0'; + + return_val_if_fail (pinfo != NULL, SNV_ERROR); + + /* Check for valid pre-state. */ + if (pinfo->prec != -1 + || pinfo->is_char || pinfo->is_short || pinfo->is_long + || pinfo->is_long_double || pinfo->pad == '0' + || pinfo->alt || pinfo->space || pinfo->showsign) + { + PRINTF_ERROR (pinfo, "invalid flags"); + return -1; + } + + /* Extract the correct argument from the arg vector. */ + ch = args->pa_char; + + /* Left pad to the width if the supplied argument is less than + the width specifier. */ + if ((pinfo->width > 1) && !pinfo->left) + { + int padwidth = pinfo->width - 1; + + while ((count_or_errorcode >= 0) && (count_or_errorcode < padwidth)) + SNV_EMIT (pinfo->pad, stream, count_or_errorcode); + } + + /* Emit the character argument. */ + SNV_EMIT (ch, stream, count_or_errorcode); + + /* Right pad to the width if we still didn't reach the specified + width and the left justify flag was set. */ + if ((count_or_errorcode < pinfo->width) && pinfo->left) + while ((count_or_errorcode >= 0) + && (count_or_errorcode < pinfo->width)) + SNV_EMIT (pinfo->pad, stream, count_or_errorcode); + + /* Return the number of characters emitted. */ + return count_or_errorcode; +} + +#ifndef NO_FLOAT_PRINTING + +static int +printf_float (STREAM *stream, + struct printf_info *const pinfo, + union printf_arg const *args) +{ + snv_long_double value = 0.0; + int sign, len, count_or_errorcode = SNV_OK; +#ifdef HAVE_LONG_DOUBLE + char buffer[LDBL_MAX_10_EXP * 2 + 20], *p = buffer; +#else + char buffer[DBL_MAX_10_EXP * 2 + 20], *p = buffer; +#endif + + return_val_if_fail (pinfo != NULL, SNV_ERROR); + + /* Check for valid pre-state */ + if (pinfo->prec == -1) + pinfo->prec = SNV_POINTER_TO_LONG (pinfo->extra); + + /* Check for valid pre-state. */ + if (pinfo->prec <= -1 + || pinfo->is_char || pinfo->is_short || pinfo->is_long) + { + PRINTF_ERROR (pinfo, "invalid flags"); + return -1; + } + + /* Extract the correct argument from the arg vector. */ + value = fetch_double (pinfo, args); + + /* Convert the number into a string. */ + len = print_float (pinfo, buffer, buffer + sizeof (buffer), &sign, value); + if (*buffer == '0') + p++, len--; + + /* Compute the size of the padding. */ + pinfo->width -= len; + if (sign) + pinfo->width--; + + /* Left pad to the remaining width if the supplied argument is less + than the width specifier, and the padding character is ' '. */ + if (pinfo->pad == ' ' && !pinfo->left) + while ((count_or_errorcode >= 0) && (pinfo->width-- > 0)) + SNV_EMIT (pinfo->pad, stream, count_or_errorcode); + + /* Display any sign character. */ + if (count_or_errorcode >= 0 && sign) + SNV_EMIT (sign, stream, count_or_errorcode); + + /* Left pad to the remaining width if the supplied argument is less + than the width specifier, and the padding character is not ' '. */ + if (pinfo->pad != ' ' && !pinfo->left) + while ((count_or_errorcode >= 0) && (pinfo->width-- > 0)) + SNV_EMIT (pinfo->pad, stream, count_or_errorcode); + + /* Fill the stream buffer with as many characters from the number + buffer as possible without overflowing. */ + while ((count_or_errorcode >= 0) && (len-- > 0)) + SNV_EMIT (*p++, stream, count_or_errorcode); + + /* Right pad to the width if we still didn't reach the specified + width and the left justify flag was set. */ + if (pinfo->left) + while ((count_or_errorcode >= 0) && (pinfo->width-- > 0)) + SNV_EMIT (pinfo->pad, stream, count_or_errorcode); + + /* Return the number of characters emitted. */ + return count_or_errorcode; +} +#endif + +static int +printf_count (STREAM *stream, struct printf_info *const pinfo, union printf_arg const *args) +{ + (void)stream; + + if (pinfo->is_char) + *(char *) (args->pa_pointer) = (char)pinfo->count; + + else if (pinfo->is_short) + *(short *) (args->pa_pointer) = (short)pinfo->count; + + else if (pinfo->is_long) + *(long *) (args->pa_pointer) = (long)pinfo->count; + + else if (pinfo->is_long_double) + *(intmax_t *) (args->pa_pointer) = (intmax_t)pinfo->count; + + else + *(int *) (args->pa_pointer) = (int)pinfo->count; + + return 0; +} + +static int +printf_integer (STREAM *stream, struct printf_info *const pinfo, union printf_arg const *args) +{ + static const char digits_lower[] = "0123456789abcdefghijklmnopqrstuvwxyz"; + static const char digits_upper[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + const char *digits; + + unsigned base = (unsigned int)SNV_POINTER_TO_ULONG (pinfo->extra); + uintmax_t value = 0L; + int type, count_or_errorcode = SNV_OK; + char buffer[256], *p, *end; + bool is_negative = false; + + return_val_if_fail (pinfo != NULL, SNV_ERROR); + + /* Check for valid pre-state. */ + if (!(pinfo->state & (SNV_STATE_BEGIN | SNV_STATE_SPECIFIER))) + { + PRINTF_ERROR (pinfo, "out of range"); + return -1; + } + + /* Upper or lower-case hex conversion? */ + digits = ((pinfo->spec >= 'a') && (pinfo->spec <= 'z')) + ? digits_lower : digits_upper; + + if (pinfo->prec == -1) + pinfo->prec = 0; + + /* Check for valid pre-state. */ + if (pinfo->prec < 0) + { + PRINTF_ERROR (pinfo, "invalid precision"); + return -1; + } + + type = pinfo->type; + + /* Extract the correct argument from the arg vector. */ + if (type & PA_FLAG_UNSIGNED) + { + value = fetch_uintmax (pinfo, args); + is_negative = false; + pinfo->showsign = pinfo->space = false; + } + else + { + intmax_t svalue = 0L; + svalue = fetch_intmax (pinfo, args); + is_negative = (svalue < 0); + value = (uintmax_t) ABS (svalue); + } + + /* Convert the number into a string. */ + p = end = &buffer[sizeof (buffer) - 1]; + + if (value == 0) + *p-- = '0'; + + else + while (value > 0) + { + *p-- = digits[value % base]; + value /= base; + } + + pinfo->width -= (int)(end - p); + pinfo->prec -= (int)(end - p); + + /* Octal numbers have a leading zero in alterate form. */ + if (pinfo->alt && base == 8) + { + *p-- = '0'; + --pinfo->width; + } + + /* Left pad with zeros to make up the precision. */ + if (pinfo->prec > 0) + { + pinfo->width -= pinfo->prec; + while (pinfo->prec-- > 0) + *p-- = '0'; + } + + /* Reserve room for leading `0x' for hexadecimal. */ + if (pinfo->alt && base == 16) + pinfo->width -= 2; + + /* Reserve room for a sign character. */ + if (is_negative || pinfo->showsign || pinfo->space) + --pinfo->width; + + /* Left pad to the remaining width if the supplied argument is less + * than the width specifier, and the padding character is ' '. + */ + if (pinfo->pad == ' ' && !pinfo->left) + while ((count_or_errorcode >= 0) && (pinfo->width-- > 0)) + SNV_EMIT (pinfo->pad, stream, count_or_errorcode); + + /* Display any sign character. */ + if (count_or_errorcode >= 0) + { + if (is_negative) + SNV_EMIT ('-', stream, count_or_errorcode); + else if (pinfo->showsign) + SNV_EMIT ('+', stream, count_or_errorcode); + else if (pinfo->space) + SNV_EMIT (' ', stream, count_or_errorcode); + } + + /* Display `0x' for alternate hexadecimal specifier. */ + if ((count_or_errorcode >= 0) && (base == 16) && pinfo->alt) + { + SNV_EMIT ('0', stream, count_or_errorcode); + SNV_EMIT (digits['X' - 'A' + 10], stream, count_or_errorcode); + } + + /* Left pad to the remaining width if the supplied argument is less + * than the width specifier, and the padding character is not ' '. + */ + if (pinfo->pad != ' ' && !pinfo->left) + while ((count_or_errorcode >= 0) && (pinfo->width-- > 0)) + SNV_EMIT (pinfo->pad, stream, count_or_errorcode); + + /* Fill the stream buffer with as many characters from the number + * buffer as possible without overflowing. + */ + while ((count_or_errorcode >= 0) && (++p < &buffer[sizeof (buffer)])) + SNV_EMIT (*p, stream, count_or_errorcode); + + /* Right pad to the width if we still didn't reach the specified + * width and the left justify flag was set. + */ + if (pinfo->left) + while ((count_or_errorcode >= 0) && (pinfo->width-- > 0)) + SNV_EMIT (pinfo->pad, stream, count_or_errorcode); + + /* Return the number of characters emitted. */ + return count_or_errorcode; +} + +static int +printf_pointer (STREAM *stream, struct printf_info *const pinfo, union printf_arg const *args) +{ + int count_or_errorcode = SNV_OK; + + return_val_if_fail (pinfo != NULL, SNV_ERROR); + + /* Read these now to advance the argument pointer appropriately */ + if (pinfo->prec == -1) + pinfo->prec = 0; + + /* Check for valid pre-state. */ + if (pinfo->prec <= -1 + || pinfo->is_char || pinfo->is_short || pinfo->is_long + || pinfo->is_long_double) + { + PRINTF_ERROR (pinfo, "invalid flags"); + return -1; + } + + /* Always print 0x. */ + pinfo->alt = 1; + pinfo->is_long = sizeof(long) == sizeof (char *); + pinfo->is_long_double = sizeof(intmax_t) == sizeof (char *); + + /* Use the standard routine for numbers for the printing call, + if the pointer is not NULL. */ + + if (args->pa_pointer != NULL) + return printf_integer (stream, pinfo, args); + + /* Print a NULL pointer as (nil), appropriately padded. */ + if ((pinfo->width > 5) && !pinfo->left) + { + int padwidth = pinfo->width - 5; + while ((count_or_errorcode >= 0) && (count_or_errorcode < padwidth)) + SNV_EMIT (pinfo->pad, stream, count_or_errorcode); + } + + SNV_EMIT ('(', stream, count_or_errorcode); + SNV_EMIT ('n', stream, count_or_errorcode); + SNV_EMIT ('i', stream, count_or_errorcode); + SNV_EMIT ('l', stream, count_or_errorcode); + SNV_EMIT (')', stream, count_or_errorcode); + + if ((pinfo->width > 5) && pinfo->left) + while ((count_or_errorcode >= 0) + && (count_or_errorcode < pinfo->width)) + SNV_EMIT (pinfo->pad, stream, count_or_errorcode); + + return count_or_errorcode; +} + +static int +printf_string (STREAM *stream, struct printf_info *const pinfo, union printf_arg const *args) +{ + size_t len = 0; + int count_or_errorcode = SNV_OK; + const char *p = NULL; + + return_val_if_fail (pinfo != NULL, SNV_ERROR); + + /* Read these now to advance the argument pointer appropriately */ + if (pinfo->prec == -1) + pinfo->prec = 0; + + /* Check for valid pre-state. */ + if (pinfo->prec <= -1 + || pinfo->is_char || pinfo->is_short || pinfo->is_long + || pinfo->is_long_double) + { + PRINTF_ERROR (pinfo, "invalid flags"); + return -1; + } + + /* Extract the correct argument from the arg vector. */ + p = args->pa_string; + + /* Left pad to the width if the supplied argument is less than + the width specifier. */ + if (p != NULL) + { + len = strlen (p); + if (pinfo->prec && ((size_t)pinfo->prec < len)) + len = (size_t)pinfo->prec; + } + + if ((len < (size_t)pinfo->width) && !pinfo->left) + { + int padwidth = pinfo->width - (int)len; + while ((count_or_errorcode >= 0) && (count_or_errorcode < padwidth)) + SNV_EMIT (pinfo->pad, stream, count_or_errorcode); + } + + /* Fill the buffer with as many characters from the format argument + as possible without overflowing or exceeding the precision. */ + if ((count_or_errorcode >= 0) && (p != NULL)) + { + int mark = (int)count_or_errorcode; + while ( (*p != '\0') + && ( (pinfo->prec == 0) + || (count_or_errorcode - mark < (int)len))) + SNV_EMIT (*p++, stream, count_or_errorcode); + } + + /* Right pad to the width if we still didn't reach the specified + width and the left justify flag was set. */ + if ((count_or_errorcode < pinfo->width) && pinfo->left) + while ((count_or_errorcode >= 0) + && (count_or_errorcode < pinfo->width)) + SNV_EMIT (pinfo->pad, stream, count_or_errorcode); + + /* Return the number of characters emitted. */ + return count_or_errorcode; +} + + + +/* replacements for modfl and copysignl follow. */ + +#if !defined NO_FLOAT_PRINTING && defined HAVE_LONG_DOUBLE +# ifndef HAVE_MODFL +static long double modfl (long double x, long double *exp) +{ + /* To compute the integer part of a positive integer (in this case + abs(X)), sum a big enough integer to the absolute value, so that + the precision of the floating point number is exactly 1. Then + we round towards zero. + + The code in the two branches is the same but it considers -x + if x is negative. */ + + long double z; + if (x < 0.0L) + { + z = 1.0L / LDBL_EPSILON - x - 1.0 / LDBL_EPSILON; + if (z + x > 0.0L) + z = z - 1.0L; + + return (*exp = -z) + x; + } + else + { + z = 1.0L / LDBL_EPSILON + x - 1.0 / LDBL_EPSILON; + if (z > x) + z = z - 1.0L; + + return x - (*exp = z); + } +} +# endif /* !HAVE_MODFL */ + +# ifndef HAVE_COPYSIGNL +long double +copysignl (long double x, long double y) +{ +# ifdef HAVE_COPYSIGN + return x * (long double) copysign (1.0, x * y); +# else /* !HAVE_COPYSIGN */ + /* If we do not have copysign, assume zero is unsigned (too risky to + assume we have infinities, which would allow to test with + (x < 0.0 && 1.0 / x < 0.0). */ + return (x < 0.0 ^ y < 0.0) ? x * -1.0 : x; +# endif /* !HAVE_COPYSIGN */ +} +# endif /* !HAVE_COPYSIGNL */ +#endif /* !NO_FLOAT_PRINTING && HAVE_LONG_DOUBLE) */ + + + +/* This is where the parsing of FORMAT strings is handled: + + Each of these functions should inspect PPARSER for parser + state information; update PPARSER as necessary based on + the state discovered; possibly put some characters in STREAM, in + which case that number of characters must be returned. If the + handler detects that parsing (of the current specifier) is complete, + then it must set pinfo->state to SNV_STATE_END. The library will then + copy characters from the format string to STREAM until another unescaped + SNV_CHAR_SPEC is detected when the handlers will be called again. */ + +spec_entry snv_default_spec_table[] = { + /* ch type function */ + {' ', 0, 0, NULL, printf_flag_info, NULL}, + {'#', 0, 0, NULL, printf_flag_info, NULL}, + {'+', 0, 0, NULL, printf_flag_info, NULL}, + {'-', 0, 0, NULL, printf_flag_info, NULL}, + {'\'', 0, 0, NULL, printf_flag_info, NULL}, + {'*', 0, PA_INT, NULL, printf_numeric_param_info, NULL}, + {'$', 0, 0, NULL, printf_numeric_param_info, NULL}, + {'.', 0, 0, NULL, printf_numeric_param_info, NULL}, + {'0', 0, 0, NULL, printf_flag_info, NULL}, + {'1', 0, 0, NULL, printf_numeric_param_info, NULL}, + {'2', 0, 0, NULL, printf_numeric_param_info, NULL}, + {'3', 0, 0, NULL, printf_numeric_param_info, NULL}, + {'4', 0, 0, NULL, printf_numeric_param_info, NULL}, + {'5', 0, 0, NULL, printf_numeric_param_info, NULL}, + {'6', 0, 0, NULL, printf_numeric_param_info, NULL}, + {'7', 0, 0, NULL, printf_numeric_param_info, NULL}, + {'8', 0, 0, NULL, printf_numeric_param_info, NULL}, + {'9', 0, 0, NULL, printf_numeric_param_info, NULL}, + {'c', 0, PA_CHAR, printf_char, NULL, NULL}, + {'d', 0, PA_INT, printf_integer, printf_generic_info, (snv_pointer) 10}, +#ifndef NO_FLOAT_PRINTING + {'e', 0, PA_DOUBLE, printf_float, printf_generic_info, (snv_pointer) 6}, + {'E', 0, PA_DOUBLE, printf_float, printf_generic_info, (snv_pointer) 6}, + {'f', 0, PA_DOUBLE, printf_float, printf_generic_info, (snv_pointer) 6}, + {'F', 0, PA_DOUBLE, printf_float, printf_generic_info, (snv_pointer) 6}, + {'g', 0, PA_DOUBLE, printf_float, printf_generic_info, (snv_pointer) 6}, + {'G', 0, PA_DOUBLE, printf_float, printf_generic_info, (snv_pointer) 6}, +#endif + {'h', 0, 0, NULL, printf_modifier_info, NULL}, + {'i', 0, PA_INT, printf_integer, printf_generic_info, (snv_pointer) 10}, + {'j', 0, 0, NULL, printf_modifier_info, NULL}, + {'l', 0, 0, NULL, printf_modifier_info, NULL}, + {'L', 0, 0, NULL, printf_modifier_info, NULL}, + {'n', 0, PA_INT | PA_FLAG_PTR, printf_count, printf_generic_info, NULL}, + {'o', 0, PA_INT | PA_FLAG_UNSIGNED, + printf_integer, printf_generic_info, (snv_pointer) 8}, + {'p', 0, PA_POINTER, printf_pointer, NULL, (snv_pointer) 16}, + {'q', 0, 0, NULL, printf_modifier_info, NULL}, + {'s', 0, PA_STRING, printf_string, NULL, NULL}, + {'t', 0, 0, NULL, printf_modifier_info, NULL}, + {'u', 0, PA_INT | PA_FLAG_UNSIGNED, + printf_integer, printf_generic_info, (snv_pointer) 10}, + {'x', 0, PA_INT | PA_FLAG_UNSIGNED, + printf_integer, printf_generic_info, (snv_pointer) 16}, + {'X', 0, PA_INT | PA_FLAG_UNSIGNED, + printf_integer, printf_generic_info, (snv_pointer) 16}, + {'z', 0, 0, NULL, printf_modifier_info, NULL}, + {'\0', 0, PA_LAST, NULL, NULL, NULL} +}; + +/* + * Local Variables: + * mode: C + * c-file-style: "gnu" + * indent-tabs-mode: nil + * End: + * end of snprintfv/format.c */ diff --git a/snprintfv/mem.c b/snprintfv/mem.c new file mode 100644 index 0000000..1c345f5 --- /dev/null +++ b/snprintfv/mem.c @@ -0,0 +1,81 @@ +/* -*- Mode: C -*- */ + +/* mem.c --- memory management routines + * Copyright (C) 2002 Gary V. Vaughan + * Originally by Paolo Bonzini, 2002 + * This file is part of Snprintfv + * + * Snprintfv 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. + * + * Snprintfv program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * As a special exception to the GNU General Public License, if you + * distribute this file as part of a program that also links with and + * uses the libopts library from AutoGen, you may include it under + * the same distribution terms used by the libopts library. + */ + +/* Code: */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef HAVE_DMALLOC +# include +#endif + +#include "mem.h" + + +/* We deliberately don't prototype the malloc functions; they are cast + to match the function pointers we expose to avoid compiler warnings + from mismatched prototypes (if we find a host implementation. + + Not also that if this file is compiled -DWITH_DMALLOC, the inclusion + in mem.h will cause the malloc references below to be redirected + correctly. */ +malloc_proc_t* snv_malloc = (malloc_proc_t*)malloc; +realloc_proc_t* snv_realloc = (realloc_proc_t*)realloc; +free_proc_t* snv_free = (free_proc_t*)free; + +/* Unportable memory management functions are reimplemented tout court. */ +snv_pointer +snv_xrealloc (snv_pointer old, size_t count) +{ + if (count < 1) + { + snv_free (old); + return NULL; + } + if (!old) + return snv_malloc (count); + else + return snv_realloc (old, count); +} + +char * +snv_strdup (const char *str) +{ + size_t len = strlen (str); + char *result = snv_malloc (len + 1); + memcpy (result, str, len + 1); + return result; +} + +/* + * Local Variables: + * mode: C + * c-file-style: "gnu" + * indent-tabs-mode: nil + * End: + * end of snprintfv/mem.c */ diff --git a/snprintfv/mem.h b/snprintfv/mem.h new file mode 100644 index 0000000..44aa88c --- /dev/null +++ b/snprintfv/mem.h @@ -0,0 +1,119 @@ +/* -*- Mode: C -*- */ + +/* mem.h --- memory handling macros + * Copyright (C) 1999 Gary V. Vaughan + * Originally by Gary V. Vaughan, 1999 + * This file is part of Snprintfv + * + * Snprintfv 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. + * + * Snprintfv program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * As a special exception to the GNU General Public License, if you + * distribute this file as part of a program that also links with and + * uses the libopts library from AutoGen, you may include it under + * the same distribution terms used by the libopts library. + */ + +/* Code: */ + +#ifndef SNPRINTFV_MEM_H +#define SNPRINTFV_MEM_H 1 + +#include + +#ifdef WITH_DMALLOC +# include +#endif + +#ifdef _WIN32 +# ifdef DLL_EXPORT +# define SNV_SCOPE extern __declspec(dllexport) +# else +# ifdef LIBSNPRINTFV_DLL_IMPORT +# define SNV_SCOPE extern __declspec(dllimport) +# endif +# endif +#else +# define SNV_SCOPE extern +#endif + +/* This is the API we use throughout libsnprintfv. */ +#define snv_new(type, count) \ + ((type*)snv_malloc(sizeof(type) * (size_t)(count))) +#define snv_renew(type, ptr, count) \ + ((type*)snv_xrealloc((ptr), sizeof(type) * (size_t)(count))) +#define snv_delete(old) snv_free(old) + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +typedef void* (malloc_proc_t )(size_t); +typedef void* (realloc_proc_t)(snv_pointer, size_t); +typedef void* (free_proc_t )(snv_pointer); + +/* These function pointers are exposed through the API incase a user + of this library needs to map our memory management routines to + their own (e.g. xmalloc). */ + +/** + * snv_malloc: + * @count: The number of bytes to allocate. + * + * Allocates a fresh block of memory whose size is @count bytes. + * + * Return value: + * The pointer to the newly-allocated memory area. + */ +SNV_SCOPE malloc_proc_t *snv_malloc; + +/** + * snv_realloc: + * @old: The pointer to the block whose size must be changed. + * @count: The number of bytes to allocate. + * + * Reallocates a fresh block of memory pointed to by @old + * so that its size becomes @count bytes. + * + * Return value: + * The pointer to the newly-allocated memory area, possibly + * the same as @old. + */ +SNV_SCOPE realloc_proc_t *snv_realloc; + +/** + * snv_free: + * @old: The pointer to the block that must freed. + * + * Frees a block of memory pointed to by @old. + */ +SNV_SCOPE free_proc_t *snv_free; + +/* And these are reimplemented tout court because they are + not fully portable. */ +extern realloc_proc_t snv_xrealloc; +extern char* snv_strdup (const char *str); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* SNPRINTFV_MEM_H */ + +/* + * Local Variables: + * mode: C + * c-file-style: "gnu" + * indent-tabs-mode: nil + * End: + * end of snprintfv/mem.h */ diff --git a/snprintfv/printf.c b/snprintfv/printf.c new file mode 100644 index 0000000..01fd750 --- /dev/null +++ b/snprintfv/printf.c @@ -0,0 +1,1572 @@ +/* -*- Mode: C -*- */ + +/* printf.c --- printf clone for argv arrays + * Copyright (C) 1998, 1999, 2000, 2002 Gary V. Vaughan + * Originally by Gary V. Vaughan, 1998 + * This file is part of Snprintfv + * + * Snprintfv 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. + * + * Snprintfv program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * As a special exception to the GNU General Public License, if you + * distribute this file as part of a program that also links with and + * uses the libopts library from AutoGen, you may include it under + * the same distribution terms used by the libopts library. + */ + +/* Code: */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include /* for the write(2) call */ + +#ifdef HAVE_ASSERT_H +# include +#else +# define assert(_e) +#endif + +#define COMPILING_PRINTF_C +#include "printf.h" + +#ifdef WITH_DMALLOC +#include +#endif + +#include "filament.h" +#include "stream.h" +#include "mem.h" + +#ifdef SNV_LIBRARY_BUILD +# include "dl.h" +#else + +# ifndef HAVE_STRTOUL +# include "strtoul.c" +# endif +#endif /* SNV_LIBRARY_BUILD */ + +#define EOS '\0' +#define SNV_CHAR_SPEC '%' +#define SNV_ESC_SPEC '\\' + +/* Functions to manage mapping of spec chars to handlers. */ +SNV_INLINE unsigned spec_hash (unsigned spec); +SNV_INLINE void spec_init (void); +SNV_INLINE spec_entry *spec_lookup (unsigned spec); +static void spec_insert (spec_entry * pentry); +static int do_printfv (STREAM *stream, const char *format, + union printf_arg const args[]); + +/* FIXME: We are assuming an ASCII character set where all the + printable characters are between SPACE and DEL. */ +#define ASCII_DEL (int)'\177' +#define ASCII_SPACE (int)' ' + +#define IS_MODIFIER(spec) (!((spec)->fmt)) + +/* TODO: This is not thread-safe. Change the API to pass the spec_table + in as the first parameter to the functions which use it? */ +static spec_entry *spec_table[ASCII_DEL - ASCII_SPACE]; + +/* TODO: This is not thread-safe as well. */ +static char *printf_last_error; + +SNV_INLINE unsigned +spec_hash (unsigned spec) +{ + return (spec & ASCII_DEL) - ASCII_SPACE; +} + +/* Register all of the functions in INIT_SPEC_TABLE. */ +static void +spec_init (void) +{ + static bool is_init = false; + + if (!is_init) + { + extern spec_entry snv_default_spec_table[]; + unsigned ix; + + memset (spec_table, 0, sizeof (spec_table)); + for (ix = 0; snv_default_spec_table[ix].spec_key != EOS; ix++) + { + unsigned hash = spec_hash (snv_default_spec_table[ix].spec_key); + spec_table[hash] = snv_default_spec_table + ix; + } + + is_init = true; + } +} + +/* Insert PENTRY, a new handler, into SPEC_TABLE. */ +SNV_INLINE void +spec_insert (spec_entry *pentry) +{ + unsigned hash = spec_hash (pentry->spec_key); + spec_init (); + spec_table[hash] = pentry; +} + +/* Lookup and return the SPEC_TABLE entry for SPEC. */ +SNV_INLINE spec_entry * +spec_lookup (unsigned spec) +{ + unsigned hash = spec_hash (spec); + spec_init (); + return spec_table[hash]; +} + +/** + * register_printf_function: printf.h + * @spec: the character which will trigger @func, cast to an unsigned int. + * @fmt: the handler function to actually print the arguments to the specifier + * @arg: the handler function to tell %printf about the types of the arguments + * to the specifier + * + * Register the pair made of @fmt and @arg, so that it is called + * when @spec is encountered in a format string. + * + * Return value: + * Returns %NULL if @func was not successfully registered, a + * %spec_entry with the information on the function if it was. + **/ +spec_entry * +register_printf_function (unsigned spec, printf_function *fmt, + printf_arginfo_function *arg) +{ + spec_entry *new, *old; + old = spec_lookup (spec); + if (old && IS_MODIFIER (old)) + return NULL; + + if (!fmt || !spec) + return NULL; + + new = snv_new (spec_entry, 1); + new->spec_key = spec; + new->fmt = fmt; + new->arg = arg; + new->user = NULL; + + spec_insert (new); + + return new; +} + +static int +call_argtype_function ( + struct printf_info *const pinfo, + int **argtypes, + spec_entry *spec) +{ + int n; + int argindex = (pinfo->dollar && !IS_MODIFIER (spec)) + ? pinfo->dollar - 1 + : pinfo->argindex; + + int save_argindex = pinfo->argindex; + int save_state = pinfo->state; + char const *save_format = pinfo->format; + + if (!spec->arg) + { + n = 1; + if (pinfo->argc <= argindex) + { + /* + * "argtypes" points to a pointer of an array of int values. + * Here, we ensure that there are "argindex + 1" entries in + * that array. + */ + *argtypes = snv_renew (int, *argtypes, (argindex + 1)); + + /* + * IF there are more entries that follow the current argument + * index, then we will clobber all the entries that follow. + * The size of these entries is the size of the array elements, + * not the size of the pointer to the array elements. + */ + if (pinfo->argc < argindex) + memset(*argtypes + pinfo->argc, PA_UNKNOWN, + (size_t)(argindex - pinfo->argc) * sizeof(**argtypes)); + + pinfo->argc = argindex + 1; + } + + (*argtypes) [argindex] = spec->type; + } + + else + { + pinfo->spec = (unsigned)*(pinfo->format); + pinfo->extra = spec->user; + pinfo->type = spec->type; + + if (pinfo->argc > argindex) + n = spec->arg(pinfo, (size_t) (pinfo->argc - argindex), + *argtypes + argindex); + else + n = spec->arg(pinfo, (size_t)0, NULL); + + if (n < 0) + return n; + if (argindex + n > pinfo->argc) + { + int new_ct = argindex + n; + *argtypes = snv_renew (int, *argtypes, new_ct); + memset(*argtypes + pinfo->argc, PA_UNKNOWN, + (size_t)(new_ct - pinfo->argc) * sizeof(**argtypes)); + pinfo->argc = argindex + n; + /* Call again... */ + pinfo->argindex = save_argindex; + pinfo->format = save_format; + pinfo->state = save_state; + pinfo->spec = (unsigned)*(pinfo->format); + pinfo->extra = spec->user; + pinfo->type = spec->type; + n = spec->arg(pinfo, (size_t)n, *argtypes + argindex); + } + } + + if (!pinfo->dollar || !IS_MODIFIER (spec)) + pinfo->argindex += n; + + return n; +} + + +/** + * printf_strerror: printf.h + * + * Communicate information on the last error in a printf + * format string. + * + * Return value: + * A string describing the last error which occurred during the + * parsing of a printf format string. It is the responsibility + * of the caller to free the string. + */ +char * +printf_strerror (void) +{ + return snv_strdup(printf_last_error); +} + +/* (re)initialise the memory used by PPARSER. */ +static inline void +parser_init ( + struct printf_info *pinfo, + const char *format, + const union printf_arg *args) +{ + memset (pinfo, 0, sizeof (struct printf_info)); + pinfo->format = format; + pinfo->args = args; +} + +static inline struct printf_info * +parser_reset (struct printf_info *pinfo) +{ + pinfo->is_long_double = pinfo->is_char = pinfo->is_short = + pinfo->is_long = 0; + pinfo->alt = 0; + pinfo->left = 0; + pinfo->showsign = 0; + pinfo->group = 0; + pinfo->wide = 0; + pinfo->spec = 0; + pinfo->width = 0; + pinfo->space = 0; + pinfo->state = SNV_STATE_BEGIN; + pinfo->prec = -1; + pinfo->dollar = 0; + pinfo->pad = ' '; + + return pinfo; +} + + +/** + * printf_error: printf.h + * @pinfo: pointer to the current parser state. + * @file: file where error was detected. + * @line: line where error was detected. + * @func1: " (" if function is supplied by compiler. + * @func2: function where error was detected, if supplied by compiler. + * @func3: ")" if function is supplied by compiler. + * @error_message: new error message to append to @pinfo. + * + * The contents of @error_message are appended to the @pinfo internal + * error string, so it is safe to pass static strings or recycle the + * original when this function returns. + * + * Return value: + * The address of the full accumulated error message in @pinfo is + * returned. + **/ +char * +printf_error (struct printf_info *pinfo, const char *file, int line, + const char *func1, const char *func2, const char *func3, + const char *error_message) +{ + int i; + char *result; + if (pinfo->error == NULL) + pinfo->error = filnew (NULL, (size_t)0); + else + filccat (pinfo->error, '\n'); + + /* Cannot use printf because a bug in it might trigger another + printf_error! */ + result = filcat (pinfo->error, "file "); + filcat (pinfo->error, file); + filcat (pinfo->error, ": line "); + for (i = 10; i <= line; i *= 10); + for (i /= 10; i >= 1; i /= 10) + filccat (pinfo->error, '0' + (line / i) % 10); + + filcat (pinfo->error, func1); + filcat (pinfo->error, func2); + filcat (pinfo->error, func3); + filcat (pinfo->error, ": "); + filcat (pinfo->error, error_message); + return result; +} + + + +/** + * parse_printf_format: printf.h + * @format: a % delimited format string. + * @n: the size of the @argtypes vector + * @argtypes: a vector of ints, to be filled with the argument types from @format + * + * Returns information about the number and types of + * arguments expected by the template string @format. + * The argument @n specifies the number of elements in the array + * @argtypes. This is the maximum number of elements that + * the function will try to write. + * + * Return value: + * The total number of arguments required by @format. If this + * number is greater than @n, then the information returned + * describes only the first @n arguments. If you want information + * about additional arguments, allocate a bigger array and call + * this function again. If there is an error, then %SNV_ERROR + * is returned instead. + **/ +size_t +parse_printf_format (const char *format, int n, int *argtypes) +{ + struct printf_info info; + + return_val_if_fail (format != NULL, (size_t)-1); + + parser_init (&info, format, NULL); + + while (*info.format != EOS) + { + int ch = (int) *info.format++; + spec_entry *spec; + int status; + int argindex; + + if (ch != SNV_CHAR_SPEC) + continue; + + if (*info.format == SNV_CHAR_SPEC) + { + /* An escaped CHAR_SPEC: ignore it (by falling through). */ + ++info.format; + continue; + } + + /* We found the start of a format specifier! */ + parser_reset (&info); + do + { + /* Until we fill the stream (or get some other + exception) or one of the handlers tells us + we have reached the end of the specifier... */ + + /* ...lookup the handler associated with the char + we are looking at in the format string... */ + spec = spec_lookup ((unsigned)*(info.format)); + if (spec == NULL) + { + PRINTF_ERROR (&info, "unregistered specifier"); + goto error; + } + + if (!IS_MODIFIER (spec) && + !(info.state & (SNV_STATE_BEGIN | SNV_STATE_SPECIFIER))) + { + PRINTF_ERROR (&info, "invalid combination of flags"); + goto error; + } + + argindex = info.dollar && !IS_MODIFIER (spec) + ? info.dollar - 1 : info.argindex; + + /* ...and call the relevant handler. */ + if (spec->arg) + { + info.spec = (unsigned)*(info.format); + info.extra = spec->user; + info.type = spec->type; + status = (*spec->arg) (&info, (size_t) (n - argindex), + argtypes + argindex); + } + else + { + status = 1; + if (n > argindex) + argtypes[argindex] = spec->type; + } + + if (status < 0) + goto error; + + info.argc = MAX (info.argc, argindex + status); + if (!info.dollar || !IS_MODIFIER (spec)) + info.argindex += status; + + info.format++; + } + while (IS_MODIFIER (spec)); + + continue; + + error: + /* Get here on error */ + info.argc = -1; + break; + } + + if (printf_last_error) + snv_delete (printf_last_error); + + if (info.error) + printf_last_error = fildelete (info.error); + else + printf_last_error = NULL; + + return (size_t)info.argc; +} + +static int +do_printfv (STREAM *stream, const char *format, union printf_arg const args[]) +{ + struct printf_info info; + + /* This is the parser driver. + + Here we scan through the format string and move bytes into the + stream and call handlers based on the parser state. */ + + parser_init (&info, format, args); + + /* Keep going until the format string runs out! */ + while (*info.format != EOS) + { + int ch = (int) *info.format++; + + switch (ch) + { + case SNV_CHAR_SPEC: + if (*info.format != SNV_CHAR_SPEC) + { + /* We found the start of a format specifier! */ + spec_entry *spec; + int status; + int argindex; + + parser_reset (&info); + do + { + /* Until we fill the stream (or get some other + exception) or one of the handlers tells us + we have reached the end of the specifier... */ + + /* ...lookup the handler associated with the char + we are looking at in the format string... */ + spec = spec_lookup ((unsigned)*(info.format)); + if (spec == NULL) + { + PRINTF_ERROR (&info, "unregistered specifier"); + goto error; + } + + if (!IS_MODIFIER (spec) && + !(info.state & (SNV_STATE_BEGIN | SNV_STATE_SPECIFIER))) + { + PRINTF_ERROR (&info, "invalid combination of flags"); + goto error; + } + + /* ...and call the relevant handler. */ + info.spec = (unsigned)*(info.format); + info.extra = spec->user; + info.type = spec->type; + + status = spec->arg ? (*spec->arg) (&info, (size_t)0, NULL) : 1; + + if (status < 0) + goto error; + + argindex = info.dollar && !IS_MODIFIER (spec) + ? info.dollar - 1 : info.argindex; + + info.format++; + info.argc = MAX (info.argc, argindex + status); + if (!info.dollar && !IS_MODIFIER (spec)) + info.argindex += status; + } + while (info.count >= 0 && IS_MODIFIER (spec)); + + status = (*spec->fmt) (stream, &info, args + argindex); + + if (status < 0) + goto error; + + info.count += status; + continue; + } + + /* An escaped CHAR_SPEC: ignore it (by falling through). */ + ++info.format; + + /*FALLTHROUGH*/ + + default: + /* Just a character: copy it. */ + SNV_EMIT (ch, stream, info.count); + continue; + } + + error: + /* Get here on error */ + info.count = -1; + break; + } + + if (printf_last_error) + snv_delete (printf_last_error); + + if (info.error) + printf_last_error = fildelete (info.error); + else + printf_last_error = NULL; + + return info.count; +} + +/** + * stream_printfv: printf.h + * @stream: an initialised stream structure. + * @format: a % delimited format string. + * @args: a vector of argument addresses to match @format. + * + * Format the elements of @args according to @format, and write + * the results to @stream. If @stream is %NULL, only count the + * number of characters needed to output the format. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +int +stream_printfv (STREAM *stream, const char *format, snv_constpointer const *ap) +{ + union printf_arg *args; + struct printf_info info; + int count_or_errorcode; + int *argtypes = NULL; + + return_val_if_fail (format != NULL, SNV_ERROR); + + parser_init (&info, format, NULL); + + /* Keep going until the format string runs out! */ + while (*info.format != EOS) + { + int ch = (int) *info.format++; + + switch (ch) + { + case SNV_CHAR_SPEC: + if (*info.format != SNV_CHAR_SPEC) + { + /* We found the start of a format specifier! */ + spec_entry *spec; + + parser_reset (&info); + do + { + /* Until we fill the stream (or get some other + exception) or one of the handlers tells us + we have reached the end of the specifier... */ + + /* ...lookup the handler associated with the char + we are looking at in the format string... */ + spec = spec_lookup ((unsigned)*(info.format)); + if (spec == NULL) + { + PRINTF_ERROR (&info, "unregistered specifier"); + goto error; + } + + if (!IS_MODIFIER (spec) && + !(info.state & (SNV_STATE_BEGIN | SNV_STATE_SPECIFIER))) + { + PRINTF_ERROR (&info, "invalid combination of flags"); + goto error; + } + + /* ...and call the relevant handler. */ + if (call_argtype_function (&info, &argtypes, spec) < 0) + goto error; + + info.format++; + } + while (info.count >= 0 && IS_MODIFIER (spec)); + continue; + } + + /* An escaped CHAR_SPEC: ignore it (by falling through). */ + ++info.format; + + /*FALLTHROUGH*/ + + default: /* Just a character: ignore it. */ + continue; + } + + error: + /* Get here on error */ + info.argc = -1; + break; + } + + if (info.argc == 0) + { + args = NULL; + } + else + { + int idx; + + assert(argtypes != NULL); + args = snv_new (union printf_arg, info.argc); + + /* We scanned the format string to find the type of the arguments, + so we can now cast it and store it correctly. */ + for (idx = 0; idx < info.argc; idx++) + { + int tp = argtypes[idx]; + if ((tp & PA_TYPE_MASK) == PA_TYPE_MASK) + { + if (idx + 1 == info.argc) + { + info.argc--; + break; + } + continue; /* Ignore it. We allow skipping args, but the + * user is responsible for ensuring a void* sized + * spacer in the argument list. + */ + } + + switch (tp & ~PA_FLAG_UNSIGNED) + { + case PA_CHAR: + args[idx].pa_char = (unsigned char)*(const long int *)(ap + idx); + break; + + case PA_WCHAR: + args[idx].pa_wchar = + (snv_wchar_t) *(const long int *)(ap + idx); + break; + + case PA_INT|PA_FLAG_SHORT: + args[idx].pa_short_int = + (short int) *(const long int *)(ap + idx); + break; + + case PA_INT: + args[idx].pa_int = (int) *(const long int *)(ap + idx); + break; + + case PA_INT|PA_FLAG_LONG: + args[idx].pa_long_int = *(const long int *)(ap + idx); + break; + + case PA_INT|PA_FLAG_LONG_LONG: + args[idx].pa_long_long_int = **(const intmax_t **)(ap + idx); + break; + + case PA_FLOAT: + args[idx].pa_float = **(const float **)(ap + idx); + break; + + case PA_DOUBLE|PA_FLAG_LONG_DOUBLE: +#ifdef HAVE_LONG_DOUBLE + args[idx].pa_long_double = **(const long double **)(ap + idx); + break; +#endif + /* else fall through */ + + case PA_DOUBLE: + args[idx].pa_double = **(const double **)(ap + idx); + break; + + /* Note that pointer types are dereferenced just once! */ + case PA_STRING: + args[idx].pa_string = *(const char **)(ap + idx); + break; + + case PA_WSTRING: + args[idx].pa_wstring = *(const snv_wchar_t **)(ap + idx); + break; + + case PA_POINTER: + args[idx].pa_pointer = *(snv_constpointer *)(ap + idx); + break; + + default: + if (argtypes[idx] & PA_FLAG_PTR) + args[idx].pa_pointer = *(snv_constpointer *)(ap + idx); + else + args[idx].pa_long_double = 0.0; + break; + } + } + } + + if (printf_last_error) + snv_delete (printf_last_error); + + if (info.error) + printf_last_error = fildelete (info.error); + else + printf_last_error = NULL; + + count_or_errorcode = do_printfv (stream, format, args); + + snv_delete (argtypes); + if (info.argc > 0) + snv_delete (args); + + return count_or_errorcode; +} + + +/** + * stream_vprintf: printf.h + * @stream: an initialised stream structure. + * @format: a % delimited format string. + * @ap: a varargs/stdargs va_list. + * + * Format the elements of @ap according to @format, and write + * the results to @stream. If @stream is %NULL, only count the + * number of characters needed to output the format. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +int +stream_vprintf (STREAM *stream, const char *format, va_list ap) +{ + union printf_arg *args = NULL; + struct printf_info info; + int count_or_errorcode; + int *argtypes = NULL; + + return_val_if_fail (format != NULL, SNV_ERROR); + + parser_init (&info, format, NULL); + + /* Keep going until the format string runs out! */ + while (*info.format != EOS) + { + int ch = (int) *info.format++; + + switch (ch) + { + case SNV_CHAR_SPEC: + if (*info.format != SNV_CHAR_SPEC) + { + /* We found the start of a format specifier! */ + spec_entry *spec; + + parser_reset (&info); + do + { + /* Until we fill the stream (or get some other + exception) or one of the handlers tells us + we have reached the end of the specifier... */ + /* ...lookup the handler associated with the char + we are looking at in the format string... */ + spec = spec_lookup ((unsigned)*(info.format)); + if (spec == NULL) + { + PRINTF_ERROR (&info, "unregistered specifier"); + goto error; + } + + if (!IS_MODIFIER (spec) && + !(info.state & (SNV_STATE_BEGIN | SNV_STATE_SPECIFIER))) + { + PRINTF_ERROR (&info, "invalid combination of flags"); + goto error; + } + + /* ...and call the relevant handler. */ + if (call_argtype_function (&info, &argtypes, spec) < 0) + goto error; + + info.format++; + } + while (info.count >= 0 && IS_MODIFIER (spec)); + continue; + } + /* An escaped CHAR_SPEC: ignore it (by falling through). */ + ++info.format; + + /*FALLTHROUGH*/ + + default: /* Just a character: ignore it. */ + continue; + } + + error: + /* Get here on error */ + info.argc = -1; + break; + } + + if (info.argc > 0) + { + int idx; + + assert(argtypes != NULL); + args = snv_new (union printf_arg, info.argc); + + /* Scan the format string to find the type of the argument + so we can cast it and store it correctly. + + Note that according to the ISO C standards, standard + type promotion takes place on any variadic arguments as + they are aligned on the call stack, and so it is these + promoted types that we must extract with the va_arg() + macro, or the alignment gets all messed up. + + Thanks to Robert Lipe for explaining all + this to me. */ + for (idx = 0; idx < info.argc; idx++) + switch (argtypes[idx] & ~PA_FLAG_UNSIGNED) + { + case PA_CHAR: + args[idx].pa_char = (unsigned char)va_arg (ap, int); /* Promoted */ + break; + + case PA_WCHAR: + args[idx].pa_wchar = (snv_wchar_t)va_arg (ap, snv_wint_t); + break; + + case PA_INT|PA_FLAG_SHORT: + args[idx].pa_short_int = (short int)va_arg (ap, int); + break; + + case PA_INT: + args[idx].pa_int = va_arg (ap, int); + break; + + case PA_INT|PA_FLAG_LONG: + args[idx].pa_long_int = va_arg (ap, long int); + break; + + case PA_INT|PA_FLAG_LONG_LONG: + args[idx].pa_long_long_int = va_arg (ap, intmax_t); + break; + + case PA_FLOAT: + args[idx].pa_float = (float)va_arg (ap, double); /* Promoted. */ + break; + + case PA_DOUBLE|PA_FLAG_LONG_DOUBLE: + args[idx].pa_long_double = va_arg (ap, long double); + break; + + case PA_DOUBLE: + args[idx].pa_double = va_arg (ap, double); + break; + + case PA_STRING: + args[idx].pa_string = va_arg (ap, const char *); + break; + + case PA_WSTRING: + args[idx].pa_wstring = va_arg (ap, const snv_wchar_t *); + break; + + case PA_POINTER: + args[idx].pa_pointer = va_arg (ap, void *); + break; + + default: + if (argtypes[idx] & PA_FLAG_PTR) + args[idx].pa_pointer = va_arg (ap, void *); + else + args[idx].pa_long_double = 0.0; + break; + } + } + + if (printf_last_error) + snv_delete (printf_last_error); + + if (info.error) + printf_last_error = fildelete (info.error); + else + printf_last_error = NULL; + + count_or_errorcode = do_printfv (stream, format, args); + + snv_delete (argtypes); + snv_delete (args); + return count_or_errorcode; +} + +/** + * stream_printf: printf.h + * @stream: an initialised stream structure. + * @format: a % delimited format string. + * @va_alist: a varargs/stdargs va_list. + * + * Format the elements of @va_alist according to @format, and write + * the results to @stream. If @stream is %NULL, only count the + * number of characters needed to output the format. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +int +stream_printf (STREAM * stream, const char *format, ...) +{ + int count_or_errorcode; + va_list ap; + + va_start (ap, format); + count_or_errorcode = stream_vprintf (stream, format, ap); + va_end (ap); + + return count_or_errorcode; +} + + +/* Finally... the main API implementation: */ + +/** + * snv_fdputc: printf.h + * @ch: A single character to be added to @stream. + * @stream: The stream in which to write @ch. + * + * A StreamPut function for use in putting characters + * into STREAMs holding a file descriptor. + * + * Return value: + * The value of @ch that has been put in @stream, or -1 in case of + * an error (errno will be set to indicate the type of error). + **/ +int +snv_fdputc (int ch, STREAM *stream) +{ + static char buf[1] = { 0 }; + buf[0] = (char) ch; + return + write ((int) SNV_POINTER_TO_LONG (stream_details (stream)), buf, (size_t) 1) + ? ch : -1; +} + +/** + * snv_dprintf: printf.h + * @fd: an open file descriptor. + * @format: a % delimited format string. + * @va_alist: a varargs/stdargs va_list. + * + * Format the elements of @va_alist according to @format, and write + * the results to the file descriptor @fd. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +int +snv_dprintf (int fd, const char *format, ...) +{ + int count_or_errorcode; + va_list ap; + + va_start (ap, format); + count_or_errorcode = snv_vdprintf (fd, format, ap); + va_end (ap); + + return count_or_errorcode; +} + +/** + * snv_vdprintf: printf.h + * @fd: an open file descriptor. + * @format: a % delimited format string. + * @ap: a varargs/stdargs va_list. + * + * Format the elements of @ap according to @format, and write + * the results to the file descriptor @fd. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +int +snv_vdprintf (int fd, const char *format, va_list ap) +{ + int result; + STREAM *out = stream_new (SNV_LONG_TO_POINTER (fd), + SNV_UNLIMITED, NULL, snv_fdputc); + + result = stream_vprintf (out, format, ap); + stream_delete (out); + return result; +} + +/** + * snv_dprintfv: printf.h + * @fd: an open file descriptor. + * @format: a % delimited format string. + * @args: a vector of argument addresses to match @format. + * + * Format the elements of @args according to @format, and write + * the results to file descriptor @fd. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +int +snv_dprintfv (int fd, const char *format, snv_constpointer const args[]) +{ + int result; + STREAM *out = stream_new (SNV_LONG_TO_POINTER (fd), + SNV_UNLIMITED, NULL, snv_fdputc); + + result = stream_printfv (out, format, args); + stream_delete (out); + return result; +} + + +/** + * snv_fileputc: printf.h + * @ch: A single character to be added to @stream. + * @stream: The stream in which to write @ch. + * + * A StreamPut function for use in putting characters + * into STREAMs holding a FILE*. + * + * Return value: + * The value of @ch that has been put in @stream. + **/ +int +snv_fileputc (int ch, STREAM *stream) +{ + FILE *fp = (FILE *) stream_details (stream); + return putc (ch, fp); +} + +static int +snv_fileputc_unlocked (int ch, STREAM *stream) +{ + FILE *fp = (FILE *) stream_details (stream); + return SNV_PUTC_UNLOCKED (ch, fp); +} + +/** + * snv_printf: printf.h + * @format: a % delimited format string. + * @va_alist: a varargs/stdargs va_list. + * + * Format the elements of @va_alist according to @format, and write + * the results to the standard output stream. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +int +snv_printf (const char *format, ...) +{ + int count_or_errorcode; + va_list ap; + + va_start (ap, format); + count_or_errorcode = snv_vprintf (format, ap); + va_end (ap); + + return count_or_errorcode; +} + +/** + * snv_vprintf: printf.h + * @format: a % delimited format string. + * @ap: a varargs/stdargs va_list. + * + * Format the elements of @ap according to @format, and write + * the results to the standard output stream. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +int +snv_vprintf (const char *format, va_list ap) +{ + int result; + STREAM *out = stream_new (stdout, SNV_UNLIMITED, NULL, snv_fileputc_unlocked); + int tmp; + + SNV_WITH_LOCKED_FP (stdout, tmp) + result = stream_vprintf (out, format, ap); + + stream_delete (out); + return result; +} + +/** + * snv_printfv: printf.h + * @format: a % delimited format string. + * @args: a vector of argument addresses to match @format. + * + * Format the elements of @args according to the string @format, + * and write the result to the standard output stream. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +int +snv_printfv (const char *format, snv_constpointer const args[]) +{ + int result; + STREAM *out = stream_new (stdout, SNV_UNLIMITED, NULL, snv_fileputc_unlocked); + int tmp; + + SNV_WITH_LOCKED_FP (stdout, tmp) + result = stream_printfv (out, format, args); + stream_delete (out); + return result; +} + +/** + * snv_fprintf: printf.h + * @file: a stdio.h FILE* stream. + * @format: a % delimited format string. + * @va_alist: a varargs/stdargs va_list. + * + * Format the elements of @va_alist according to @format, and write + * the results to the @file stream. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +int +snv_fprintf (FILE * file, const char *format, ...) +{ + int count_or_errorcode; + va_list ap; + + va_start (ap, format); + count_or_errorcode = snv_vfprintf (file, format, ap); + va_end (ap); + + return count_or_errorcode; +} + +/** + * snv_vfprintf: printf.h + * @file: a stdio.h FILE* stream. + * @format: a % delimited format string. + * @ap: a varargs/stdargs va_list. + * + * Format the elements of @ap according to @format, and write + * the results to the @file stream. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +int +snv_vfprintf (FILE *file, const char *format, va_list ap) +{ + int result; + STREAM *out = stream_new (file, SNV_UNLIMITED, NULL, snv_fileputc_unlocked); + int tmp; + + SNV_WITH_LOCKED_FP (file, tmp) + result = stream_vprintf (out, format, ap); + stream_delete (out); + return result; +} + +/** + * snv_fprintfv: printf.h + * @file: a stdio.h FILE* stream. + * @format: a % delimited format string. + * @args: a vector of argument addresses to match @format. + * + * Format the elements of @args according to @format, and write + * the results to @file. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +int +snv_fprintfv (FILE *file, const char *format, snv_constpointer const args[]) +{ + int result; + STREAM *out = stream_new (file, SNV_UNLIMITED, NULL, snv_fileputc_unlocked); + int tmp; + + SNV_WITH_LOCKED_FP (file, tmp) + result = stream_printfv (out, format, args); + + stream_delete (out); + return result; +} + + +/** + * snv_bufputc: printf.h + * @ch: A single character to be added to @stream. + * @stream: The stream in which to write @ch. + * + * A StreamPut function for use in putting characters + * into STREAMs holding a char buffer. + * + * Return value: + * The value of @ch that has been put in @stream. + **/ +int +snv_bufputc (int ch, STREAM * stream) +{ + char **ppbuffer = (char **) stream_details (stream); + **ppbuffer = (char) ch; + (*ppbuffer)++; + return ch; +} + +/** + * snv_sprintf: printf.h + * @buffer: a preallocated char* buffer. + * @format: a % delimited format string. + * @va_alist: a varargs/stdargs va_list. + * + * Format the elements of @va_alist according to @format, and write + * the results to the string @buffer. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +int +snv_sprintf (char buffer[], const char *format, ...) +{ + int count_or_errorcode; + va_list ap; + + va_start (ap, format); + count_or_errorcode = snv_vsprintf (buffer, format, ap); + va_end (ap); + + return count_or_errorcode; +} + +/** + * snv_vsprintf: printf.h + * @buffer: a preallocated char* buffer. + * @format: a % delimited format string. + * @ap: a varargs/stdargs va_list. + * + * Format the elements of @ap according to @format, and write + * the results to the string @buffer. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +int +snv_vsprintf (char buffer[], const char *format, va_list ap) +{ + int count_or_errorcode; + STREAM *out = stream_new (&buffer, SNV_UNLIMITED, NULL, snv_bufputc); + count_or_errorcode = stream_vprintf (out, format, ap); + + /* Terminate with an EOS without incrementing the counter. */ + stream_put (EOS, out); + + stream_delete (out); + return count_or_errorcode; +} + +/** + * snv_sprintfv: printf.h + * @buffer: a preallocated char* buffer. + * @format: a % delimited format string. + * @args: a vector of argument addresses to match @format. + * + * Format the elements of @args according to @format, and write + * the results to the string @buffer. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +int +snv_sprintfv (char buffer[], const char *format, snv_constpointer const args[]) +{ + int count_or_errorcode; + STREAM *out = stream_new (&buffer, SNV_UNLIMITED, NULL, snv_bufputc); + count_or_errorcode = stream_printfv (out, format, args); + + /* Terminate with an EOS without incrementing the counter. */ + stream_put (EOS, out); + + stream_delete (out); + return count_or_errorcode; +} + +/** + * snv_snprintf: printf.h + * @buffer: a preallocated char* buffer. + * @limit: the maximum number of characters to write into @buffer. + * @format: a % delimited format string. + * @va_alist: a varargs/stdargs va_list. + * + * Format the elements of @va_alist according to @format, and write + * the results to the string @buffer, truncating the formatted string + * if it reaches @limit characters in length. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +int +snv_snprintf (char buffer[], unsigned long limit, const char *format, ...) +{ + int count_or_errorcode; + va_list ap; + + va_start (ap, format); + count_or_errorcode = snv_vsnprintf (buffer, limit, format, ap); + va_end (ap); + + return count_or_errorcode; +} + +/** + * snv_vsnprintf: printf.h + * @buffer: a preallocated char* buffer. + * @limit: the maximum number of characters to write into @buffer. + * @format: a % delimited format string. + * @ap: a varargs/stdargs va_list. + * + * Format the elements of @ap according to @format, and write + * the results to the string @buffer, truncating the formatted string + * if it reaches @limit characters in length. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +int +snv_vsnprintf (char buffer[], unsigned long limit, const char *format, va_list ap) +{ + int count_or_errorcode; + STREAM *out = stream_new (&buffer, limit - 1, NULL, snv_bufputc); + count_or_errorcode = stream_vprintf (out, format, ap); + *buffer = EOS; + + stream_delete (out); + return count_or_errorcode; +} + +/** + * snv_snprintfv: printf.h + * @buffer: a preallocated char* buffer. + * @limit: the maximum number of characters to write into @buffer. + * @format: a % delimited format string. + * @args: a vector of argument addresses to match @format. + * + * Format the elements of @args according to @format, and write + * the results to the string @buffer, truncating the formatted string + * if it reaches @limit characters in length. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +int +snv_snprintfv (char buffer[], unsigned long limit, const char *format, + snv_constpointer const args[]) +{ + int count_or_errorcode; + STREAM *out = stream_new (&buffer, limit - 1, NULL, snv_bufputc); + count_or_errorcode = stream_printfv (out, format, args); + *buffer = EOS; + + stream_delete (out); + return count_or_errorcode; +} + + +/** + * snv_filputc: printf.h + * @ch: A single character to be added to @stream. + * @stream: The stream in which to write @ch. + * + * A StreamPut function for use in putting characters + * into STREAMs holding a Filament*. + * + * Return value: + * The value of @ch that has been put in @stream. + **/ +int +snv_filputc (int ch, STREAM * stream) +{ + return filccat ((Filament *) stream_details (stream), ch), ch; +} + +/** + * snv_asprintf: printf.h + * @result: the address of a char * variable. + * @format: a % delimited format string. + * @va_alist: a varargs/stdargs va_list. + * + * Format the elements of @va_alist according to @format, and write + * the results to an internally allocated buffer whose address is + * stored in @result (and should be freed by the caller) unless + * there is an error. + * + * Yes, this interface is cumbersome and totally useless. It would + * have been better to simply return the allocated address, but + * it turns out that somebody wasn't thinking much when adding + * asprintf to libiberty a few years ago. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +int +snv_asprintf (char **result, const char *format, ...) +{ + int count; + va_list ap; + + va_start (ap, format); + count = snv_vasprintf (result, format, ap); + va_end (ap); + + return count; +} + +/** + * snv_vasprintf: printf.h + * @result: the address of a char * variable. + * @format: a % delimited format string. + * @ap: a varargs/stdargs va_list. + * + * Format the elements of @ap according to @format, and write + * the results to an internally allocated buffer whose address is + * stored in @result (and should be freed by the caller) unless + * there is an error. + * + * Above moaning for asprintf applies here too. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +int +snv_vasprintf (char **result, const char *format, va_list ap) +{ + int count_or_errorcode; + char *base; + Filament *fil = filnew (NULL, (size_t)0); + STREAM *out = stream_new (fil, SNV_UNLIMITED, NULL, snv_filputc); + count_or_errorcode = stream_vprintf (out, format, ap); + + base = fildelete (fil); + stream_delete (out); + + *result = (count_or_errorcode < 0) ? NULL : base; + return count_or_errorcode; +} + +/** + * snv_asprintfv: printf.h + * @result: the address of a char * variable. + * @format: a % delimited format string. + * @args: a vector of argument addresses to match @format. + * + * Format the elements of @args according to @format, and write + * the results to an internally allocated buffer whose address is + * stored in @result (and should be freed by the caller) unless + * there is an error. + * + * Above moaning for asprintf applies here too. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +int +snv_asprintfv (char **result, const char *format, snv_constpointer const args[]) +{ + int count_or_errorcode; + char *base; + Filament *fil = filnew (NULL, (size_t)0); + STREAM *out = stream_new (fil, SNV_UNLIMITED, NULL, snv_filputc); + count_or_errorcode = stream_printfv (out, format, args); + + base = fildelete (fil); + stream_delete (out); + + *result = (count_or_errorcode < 0) ? NULL : base; + return count_or_errorcode; +} + +/* + * Local Variables: + * mode: C + * c-file-style: "gnu" + * indent-tabs-mode: nil + * End: + * end of snprintfv/printfv.c */ diff --git a/snprintfv/printf.h b/snprintfv/printf.h new file mode 100644 index 0000000..784ec46 --- /dev/null +++ b/snprintfv/printf.h @@ -0,0 +1,845 @@ +/* -*- Mode: C -*- */ + +/* printf.in --- printf clone for argv arrays + * Copyright (C) 1998, 1999, 2000, 2002 Gary V. Vaughan + * Originally by Gary V. Vaughan, 1998 + * This file is part of Snprintfv + * + * Snprintfv 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. + * + * Snprintfv program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * As a special exception to the GNU General Public License, if you + * distribute this file as part of a program that also links with and + * uses the libopts library from AutoGen, you may include it under + * the same distribution terms used by the libopts library. + */ + +/* Code: */ + +#ifndef SNPRINTFV_SNPRINTFV_H +#define SNPRINTFV_SNPRINTFV_H 1 + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* The type of each element in the table of printf specifiers. */ +struct spec_entry; + +typedef enum +{ + SNV_ERROR = -1, + SNV_OK +} +snv_status; + +/* Basic states required by the parser. On initialisation the parser + will be in SNV_STATE_BEGIN, and tokens will be parsed by the registered + functions until the parser reached SNV_STATE_END. */ +#define SNV_STATE_BEGIN 1 +#define SNV_STATE_END 0 + +/* States needed to support: + %[$][|\*][.|\*] */ +#define SNV_STATE_FLAG (1 << 1) +#define SNV_STATE_WIDTH (1 << 2) +#define SNV_STATE_PRECISION (1 << 3) +#define SNV_STATE_MODIFIER (1 << 4) +#define SNV_STATE_SPECIFIER (1 << 5) + +/* First state available to the user */ +#define SNV_STATE_USER_FIRST (1 << 8) + +/* Mask for states available to the user */ +#define SNV_STATE_USER_MASK ~(SNV_STATE_USER_FIRST - 1) + +typedef struct printf_info +{ + int count; /* accumulated count, or SNV_ERROR */ + int state; /* one of the defines above */ + Filament *error; /* accumulated error details */ + + const char *format; /* pointer to format string */ + int argc; /* number of arguments used by format */ + int argindex; /* number of non-dollar arguments used so far */ + + int dollar; /* standard parser state, as in glibc */ + int prec; /* from this field on, as in glibc */ + int width; + + snv_pointer extra; + int type; + + char spec; + char pad; + unsigned is_long_double:1; + unsigned is_char:1; + unsigned is_short:1; + unsigned is_long:1; + unsigned alt:1; + unsigned space:1; + unsigned left:1; + unsigned showsign:1; + unsigned group:1; + unsigned wide:1; + + const union printf_arg *args; +} printf_info; + +/** + * printf_arg: + * @pa_char: an unsigned %char + * @pa_wchar: a %wchar_t + * @pa_short_int: a %short integer + * @pa_int: an %int + * @pa_long_int: a %long integer + * @pa_long_long_int: the widest signed integer type in use on the host + * @pa_u_short_int: an unsigned %short integer + * @pa_u_int: an unsigned %int + * @pa_u_long_int: an unsigned %long integer + * @pa_u_long_long_int: the widest unsigned integer type in use on the host + * @pa_float: a %float + * @pa_double: a %double + * @pa_long_double: a long %double, or a simple %double if it is the widest floating-point type in use on the host + * @pa_string: a %const pointer to %char + * @pa_wstring: a %const pointer to %wchar_t + * @pa_pointer: a generic pointer + * + * The various kinds of arguments that can be passed to printf. + */ +typedef union printf_arg +{ + unsigned char pa_char; + snv_wchar_t pa_wchar; + short int pa_short_int; + int pa_int; + long int pa_long_int; + intmax_t pa_long_long_int; + unsigned short int pa_u_short_int; + unsigned int pa_u_int; + unsigned long int pa_u_long_int; + uintmax_t pa_u_long_long_int; + float pa_float; + double pa_double; + long double pa_long_double; + const char *pa_string; + const snv_wchar_t *pa_wstring; + snv_constpointer pa_pointer; +} printf_arg; + +/** + * PRINTF_ERROR: + * @pi: A pointer to the current state for the parser + * @str: The error message + * + * Append an error that will be returned by printf_strerror. + */ +#define PRINTF_ERROR(pi, str) \ + printf_error(pi, __FILE__, __LINE__, SNV_ASSERT_FCN, str); + +typedef int printf_function (STREAM *stream, struct printf_info *pparser, + union printf_arg const * args); + +typedef int printf_arginfo_function (struct printf_info *pparser, size_t n, + int *argtypes); + +/** + * spec_entry: + * @spec: the specifier character that was matched + * @type: when @arg is NULL, the type of the only argument to the specifier + * @fmt: the handler function to actually print the arguments to the specifier + * @arg: the handler function to tell %printf about the types of the arguments to the specifier + * @user: the user data for the specifier, accessible to the handler function + * + * This is returned by register_printf_function. + */ +typedef struct spec_entry +{ + unsigned int spec_key; + int unused; /* for binary compatibility */ + int type; + printf_function *fmt; + printf_arginfo_function *arg; + snv_pointer user; +} +spec_entry; + +/** + * register_callback_function: printf.h + * @spec: the character which will trigger the functions, cast to an unsigned int. + * @fmt: the handler function to actually print the arguments to the specifier + * @arg: the handler function to tell %printf about the types of the arguments to the specifier + * + * Register the pair made of @fmt and @arg, so that it is called + * when @spec is encountered in a format string. If you create + * a shared library with an entry point named + * %snv_register_printf_funcs, and put the library in the + * search path given by the environment library %LTDL_LIBRARY_PATH, + * that entry point will be called when %libsnprintfv is initialized, + * passing a pointer to this kind of function (actually, a pointer + * to %register_printf_function) to it. This functionality is only + * present when the library is installed, not when it is built as + * a convenience library. + * + * Return value: + * Returns %NULL if @func was not successfully registered, a + * %spec_entry with the information on the function if it was. + **/ +typedef spec_entry *register_callback_function (unsigned spec, printf_function *func, printf_arginfo_function *arginfo); + +/* Codes to determine basic types. + + These values cover all the standard format specifications. + Users can add new values after PA_LAST for their own types. */ + +enum +{ + PA_INT, /* int */ + PA_CHAR, /* int, cast to char */ + PA_WCHAR, /* wide char */ + PA_STRING, /* const char *, a '\0'-terminated string */ + PA_WSTRING, /* const wchar_t *, wide character string */ + PA_POINTER, /* void * */ + PA_FLOAT, /* float */ + PA_DOUBLE, /* double */ + PA_LAST, + PA_UNKNOWN = -1 +}; + +/* Flag bits that can be set in a type. */ +#define PA_TYPE_MASK 0x00ff +#define PA_FLAG_MASK ~SNV_TYPE_MASK + +#define PA_FLAG_LONG_LONG (1 << 8) +#define PA_FLAG_LONG_DOUBLE PA_FLAG_LONG_LONG +#define PA_FLAG_LONG (1 << 9) +#define PA_FLAG_SHORT (1 << 10) +#define PA_FLAG_UNSIGNED (1 << 11) +#define PA_FLAG_CHAR (1 << 12) +#define PA_FLAG_PTR (1 << 13) + +/** + * SNV_EMIT: + * @ch: the character to be printed + * @stream: the stream on which to print + * @count: a variable to be updated with the count of printed + * characters + * + * Maintain the count while putting @ch in @stream, also be careful about + * handling %NULL stream if the handler is being called purely to count + * output size. + **/ +#define SNV_EMIT(ch, stream, count) \ + SNV_STMT_START { \ + if ((stream)) \ + { \ + if ((count) >= 0) \ + { \ + int m_status = stream_put((unsigned char) (ch), (stream)); \ + (count) = m_status < 0 ? m_status : (count) + m_status; \ + } \ + } \ + else \ + { \ + (void)(ch); \ + (count)++; \ + } \ + } SNV_STMT_END + +#line 266 "printf.in" +/** + * printf_generic_info: + * @pinfo: the current state information for the format + * string parser. + * @n: the number of available slots in the @argtypes array + * @argtypes: the pointer to the first slot to be filled by the + * function + * + * An example implementation of a %printf_arginfo_function, which + * takes the basic type from the type given in the %spec_entry + * and adds flags depending on what was parsed (e.g. %PA_FLAG_SHORT + * is %pparser->is_short and so on). + * + * Return value: + * Always 1. + */ +extern int +printf_generic_info (struct printf_info *const pinfo, size_t n, int *argtypes); + +/** + * printf_generic: + * @stream: the stream (possibly a struct printfv_stream appropriately + * cast) on which to write output. + * @pinfo: the current state information for the format string parser. + * @args: the pointer to the first argument to be read by the handler + * + * An example implementation of a %printf_function, used to provide easy + * access to justification, width and precision options. + * + * Return value: + * The number of characters output. + **/ +extern int +printf_generic (STREAM *stream, struct printf_info *const pinfo, union printf_arg const *args); + +#line 267 "printf.in" +/** + * register_printf_function: printf.h + * @spec: the character which will trigger @func, cast to an unsigned int. + * @fmt: the handler function to actually print the arguments to the specifier + * @arg: the handler function to tell %printf about the types of the arguments + * to the specifier + * + * Register the pair made of @fmt and @arg, so that it is called + * when @spec is encountered in a format string. + * + * Return value: + * Returns %NULL if @func was not successfully registered, a + * %spec_entry with the information on the function if it was. + **/ +extern spec_entry * +register_printf_function (unsigned spec, printf_function *fmt, + printf_arginfo_function *arg); + +/** + * printf_strerror: printf.h + * + * Communicate information on the last error in a printf + * format string. + * + * Return value: + * A string describing the last error which occurred during the + * parsing of a printf format string. It is the responsibility + * of the caller to free the string. + */ +extern char * +printf_strerror (void); + +/** + * printf_error: printf.h + * @pinfo: pointer to the current parser state. + * @file: file where error was detected. + * @line: line where error was detected. + * @func1: " (" if function is supplied by compiler. + * @func2: function where error was detected, if supplied by compiler. + * @func3: ")" if function is supplied by compiler. + * @error_message: new error message to append to @pinfo. + * + * The contents of @error_message are appended to the @pinfo internal + * error string, so it is safe to pass static strings or recycle the + * original when this function returns. + * + * Return value: + * The address of the full accumulated error message in @pinfo is + * returned. + **/ +extern char * +printf_error (struct printf_info *pinfo, const char *file, int line, + const char *func1, const char *func2, const char *func3, + const char *error_message); + +/** + * parse_printf_format: printf.h + * @format: a % delimited format string. + * @n: the size of the @argtypes vector + * @argtypes: a vector of ints, to be filled with the argument types from @format + * + * Returns information about the number and types of + * arguments expected by the template string @format. + * The argument @n specifies the number of elements in the array + * @argtypes. This is the maximum number of elements that + * the function will try to write. + * + * Return value: + * The total number of arguments required by @format. If this + * number is greater than @n, then the information returned + * describes only the first @n arguments. If you want information + * about additional arguments, allocate a bigger array and call + * this function again. If there is an error, then %SNV_ERROR + * is returned instead. + **/ +extern size_t +parse_printf_format (const char *format, int n, int *argtypes); + +/** + * stream_printfv: printf.h + * @stream: an initialised stream structure. + * @format: a % delimited format string. + * @args: a vector of argument addresses to match @format. + * + * Format the elements of @args according to @format, and write + * the results to @stream. If @stream is %NULL, only count the + * number of characters needed to output the format. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +extern int +stream_printfv (STREAM *stream, const char *format, snv_constpointer const *ap); + +/** + * stream_vprintf: printf.h + * @stream: an initialised stream structure. + * @format: a % delimited format string. + * @ap: a varargs/stdargs va_list. + * + * Format the elements of @ap according to @format, and write + * the results to @stream. If @stream is %NULL, only count the + * number of characters needed to output the format. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +extern int +stream_vprintf (STREAM *stream, const char *format, va_list ap); + +/** + * stream_printf: printf.h + * @stream: an initialised stream structure. + * @format: a % delimited format string. + * @va_alist: a varargs/stdargs va_list. + * + * Format the elements of @va_alist according to @format, and write + * the results to @stream. If @stream is %NULL, only count the + * number of characters needed to output the format. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +extern int +stream_printf (STREAM * stream, const char *format, ...); + +/** + * snv_fdputc: printf.h + * @ch: A single character to be added to @stream. + * @stream: The stream in which to write @ch. + * + * A StreamPut function for use in putting characters + * into STREAMs holding a file descriptor. + * + * Return value: + * The value of @ch that has been put in @stream, or -1 in case of + * an error (errno will be set to indicate the type of error). + **/ +extern int +snv_fdputc (int ch, STREAM *stream); + +/** + * snv_dprintf: printf.h + * @fd: an open file descriptor. + * @format: a % delimited format string. + * @va_alist: a varargs/stdargs va_list. + * + * Format the elements of @va_alist according to @format, and write + * the results to the file descriptor @fd. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +extern int +snv_dprintf (int fd, const char *format, ...); + +/** + * snv_vdprintf: printf.h + * @fd: an open file descriptor. + * @format: a % delimited format string. + * @ap: a varargs/stdargs va_list. + * + * Format the elements of @ap according to @format, and write + * the results to the file descriptor @fd. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +extern int +snv_vdprintf (int fd, const char *format, va_list ap); + +/** + * snv_dprintfv: printf.h + * @fd: an open file descriptor. + * @format: a % delimited format string. + * @args: a vector of argument addresses to match @format. + * + * Format the elements of @args according to @format, and write + * the results to file descriptor @fd. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +extern int +snv_dprintfv (int fd, const char *format, snv_constpointer const args[]); + +/** + * snv_fileputc: printf.h + * @ch: A single character to be added to @stream. + * @stream: The stream in which to write @ch. + * + * A StreamPut function for use in putting characters + * into STREAMs holding a FILE*. + * + * Return value: + * The value of @ch that has been put in @stream. + **/ +extern int +snv_fileputc (int ch, STREAM *stream); + +/** + * snv_printf: printf.h + * @format: a % delimited format string. + * @va_alist: a varargs/stdargs va_list. + * + * Format the elements of @va_alist according to @format, and write + * the results to the standard output stream. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +extern int +snv_printf (const char *format, ...); + +/** + * snv_vprintf: printf.h + * @format: a % delimited format string. + * @ap: a varargs/stdargs va_list. + * + * Format the elements of @ap according to @format, and write + * the results to the standard output stream. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +extern int +snv_vprintf (const char *format, va_list ap); + +/** + * snv_printfv: printf.h + * @format: a % delimited format string. + * @args: a vector of argument addresses to match @format. + * + * Format the elements of @args according to the string @format, + * and write the result to the standard output stream. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +extern int +snv_printfv (const char *format, snv_constpointer const args[]); + +/** + * snv_fprintf: printf.h + * @file: a stdio.h FILE* stream. + * @format: a % delimited format string. + * @va_alist: a varargs/stdargs va_list. + * + * Format the elements of @va_alist according to @format, and write + * the results to the @file stream. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +extern int +snv_fprintf (FILE * file, const char *format, ...); + +/** + * snv_vfprintf: printf.h + * @file: a stdio.h FILE* stream. + * @format: a % delimited format string. + * @ap: a varargs/stdargs va_list. + * + * Format the elements of @ap according to @format, and write + * the results to the @file stream. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +extern int +snv_vfprintf (FILE *file, const char *format, va_list ap); + +/** + * snv_fprintfv: printf.h + * @file: a stdio.h FILE* stream. + * @format: a % delimited format string. + * @args: a vector of argument addresses to match @format. + * + * Format the elements of @args according to @format, and write + * the results to @file. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +extern int +snv_fprintfv (FILE *file, const char *format, snv_constpointer const args[]); + +/** + * snv_bufputc: printf.h + * @ch: A single character to be added to @stream. + * @stream: The stream in which to write @ch. + * + * A StreamPut function for use in putting characters + * into STREAMs holding a char buffer. + * + * Return value: + * The value of @ch that has been put in @stream. + **/ +extern int +snv_bufputc (int ch, STREAM * stream); + +/** + * snv_sprintf: printf.h + * @buffer: a preallocated char* buffer. + * @format: a % delimited format string. + * @va_alist: a varargs/stdargs va_list. + * + * Format the elements of @va_alist according to @format, and write + * the results to the string @buffer. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +extern int +snv_sprintf (char buffer[], const char *format, ...); + +/** + * snv_vsprintf: printf.h + * @buffer: a preallocated char* buffer. + * @format: a % delimited format string. + * @ap: a varargs/stdargs va_list. + * + * Format the elements of @ap according to @format, and write + * the results to the string @buffer. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +extern int +snv_vsprintf (char buffer[], const char *format, va_list ap); + +/** + * snv_sprintfv: printf.h + * @buffer: a preallocated char* buffer. + * @format: a % delimited format string. + * @args: a vector of argument addresses to match @format. + * + * Format the elements of @args according to @format, and write + * the results to the string @buffer. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +extern int +snv_sprintfv (char buffer[], const char *format, snv_constpointer const args[]); + +/** + * snv_snprintf: printf.h + * @buffer: a preallocated char* buffer. + * @limit: the maximum number of characters to write into @buffer. + * @format: a % delimited format string. + * @va_alist: a varargs/stdargs va_list. + * + * Format the elements of @va_alist according to @format, and write + * the results to the string @buffer, truncating the formatted string + * if it reaches @limit characters in length. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +extern int +snv_snprintf (char buffer[], unsigned long limit, const char *format, ...); + +/** + * snv_vsnprintf: printf.h + * @buffer: a preallocated char* buffer. + * @limit: the maximum number of characters to write into @buffer. + * @format: a % delimited format string. + * @ap: a varargs/stdargs va_list. + * + * Format the elements of @ap according to @format, and write + * the results to the string @buffer, truncating the formatted string + * if it reaches @limit characters in length. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +extern int +snv_vsnprintf (char buffer[], unsigned long limit, const char *format, va_list ap); + +/** + * snv_snprintfv: printf.h + * @buffer: a preallocated char* buffer. + * @limit: the maximum number of characters to write into @buffer. + * @format: a % delimited format string. + * @args: a vector of argument addresses to match @format. + * + * Format the elements of @args according to @format, and write + * the results to the string @buffer, truncating the formatted string + * if it reaches @limit characters in length. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +extern int +snv_snprintfv (char buffer[], unsigned long limit, const char *format, + snv_constpointer const args[]); + +/** + * snv_filputc: printf.h + * @ch: A single character to be added to @stream. + * @stream: The stream in which to write @ch. + * + * A StreamPut function for use in putting characters + * into STREAMs holding a Filament*. + * + * Return value: + * The value of @ch that has been put in @stream. + **/ +extern int +snv_filputc (int ch, STREAM * stream); + +/** + * snv_asprintf: printf.h + * @result: the address of a char * variable. + * @format: a % delimited format string. + * @va_alist: a varargs/stdargs va_list. + * + * Format the elements of @va_alist according to @format, and write + * the results to an internally allocated buffer whose address is + * stored in @result (and should be freed by the caller) unless + * there is an error. + * + * Yes, this interface is cumbersome and totally useless. It would + * have been better to simply return the allocated address, but + * it turns out that somebody wasn't thinking much when adding + * asprintf to libiberty a few years ago. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +extern int +snv_asprintf (char **result, const char *format, ...); + +/** + * snv_vasprintf: printf.h + * @result: the address of a char * variable. + * @format: a % delimited format string. + * @ap: a varargs/stdargs va_list. + * + * Format the elements of @ap according to @format, and write + * the results to an internally allocated buffer whose address is + * stored in @result (and should be freed by the caller) unless + * there is an error. + * + * Above moaning for asprintf applies here too. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +extern int +snv_vasprintf (char **result, const char *format, va_list ap); + +/** + * snv_asprintfv: printf.h + * @result: the address of a char * variable. + * @format: a % delimited format string. + * @args: a vector of argument addresses to match @format. + * + * Format the elements of @args according to @format, and write + * the results to an internally allocated buffer whose address is + * stored in @result (and should be freed by the caller) unless + * there is an error. + * + * Above moaning for asprintf applies here too. + * + * Return value: + * The number of characters written is returned, unless there is + * an error, when %SNV_ERROR is returned. + **/ +extern int +snv_asprintfv (char **result, const char *format, snv_constpointer const args[]); + +#line 268 "printf.in" + +/* If you don't want to use snprintfv functions for *all* of your string + formatting API, then define COMPILING_SNPRINTFV_C and use the snv_ + prefix for the entry points below. */ +#ifndef COMPILING_PRINTF_C +#undef printf +#undef vprintf +#undef dprintf +#undef vdprintf +#undef fprintf +#undef vfprintf +#undef sprintf +#undef vsprintf +#undef snprintf +#undef vsnprintf +#undef asprintf +#undef vasprintf +#undef asprintfv +#undef dprintfv +#undef fprintfv +#undef sprintfv +#undef printfv +#undef snprintfv + +#define printf snv_printf +#define vprintf snv_vprintf +#define dprintf snv_dprintf +#define vdprintf snv_vdprintf +#define fprintf snv_fprintf +#define vfprintf snv_vfprintf +#define sprintf snv_sprintf +#define vsprintf snv_vsprintf +#define snprintf snv_snprintf +#define vsnprintf snv_vsnprintf +#define asprintf snv_asprintf +#define vasprintf snv_vasprintf +#define asprintfv snv_asprintfv +#define dprintfv snv_dprintfv +#define fprintfv snv_fprintfv +#define sprintfv snv_sprintfv +#define printfv snv_printfv +#define snprintfv snv_snprintfv +#endif /* !COMPILING_SNPRINTFV_C */ +#ifdef __cplusplus +} +#endif + +#endif /* SNPRINTFV_SNPRINTFV_H */ + +/* snprintfv.h ends here */ diff --git a/snprintfv/printf.in b/snprintfv/printf.in new file mode 100644 index 0000000..8fef02c --- /dev/null +++ b/snprintfv/printf.in @@ -0,0 +1,317 @@ +/* -*- Mode: C -*- */ + +/* printf.in --- printf clone for argv arrays + * Copyright (C) 1998, 1999, 2000, 2002 Gary V. Vaughan + * Originally by Gary V. Vaughan, 1998 + * This file is part of Snprintfv + * + * Snprintfv 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. + * + * Snprintfv program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * As a special exception to the GNU General Public License, if you + * distribute this file as part of a program that also links with and + * uses the libopts library from AutoGen, you may include it under + * the same distribution terms used by the libopts library. + */ + +/* Code: */ + +#ifndef SNPRINTFV_SNPRINTFV_H +#define SNPRINTFV_SNPRINTFV_H 1 + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* The type of each element in the table of printf specifiers. */ +struct spec_entry; + +typedef enum +{ + SNV_ERROR = -1, + SNV_OK +} +snv_status; + +/* Basic states required by the parser. On initialisation the parser + will be in SNV_STATE_BEGIN, and tokens will be parsed by the registered + functions until the parser reached SNV_STATE_END. */ +#define SNV_STATE_BEGIN 1 +#define SNV_STATE_END 0 + +/* States needed to support: + %[$][|\*][.|\*] */ +#define SNV_STATE_FLAG (1 << 1) +#define SNV_STATE_WIDTH (1 << 2) +#define SNV_STATE_PRECISION (1 << 3) +#define SNV_STATE_MODIFIER (1 << 4) +#define SNV_STATE_SPECIFIER (1 << 5) + +/* First state available to the user */ +#define SNV_STATE_USER_FIRST (1 << 8) + +/* Mask for states available to the user */ +#define SNV_STATE_USER_MASK ~(SNV_STATE_USER_FIRST - 1) + +typedef struct printf_info +{ + int count; /* accumulated count, or SNV_ERROR */ + int state; /* one of the defines above */ + Filament *error; /* accumulated error details */ + + const char *format; /* pointer to format string */ + int argc; /* number of arguments used by format */ + int argindex; /* number of non-dollar arguments used so far */ + + int dollar; /* standard parser state, as in glibc */ + int prec; /* from this field on, as in glibc */ + int width; + + snv_pointer extra; + int type; + + char spec; + char pad; + unsigned is_long_double:1; + unsigned is_char:1; + unsigned is_short:1; + unsigned is_long:1; + unsigned alt:1; + unsigned space:1; + unsigned left:1; + unsigned showsign:1; + unsigned group:1; + unsigned wide:1; + + const union printf_arg *args; +} printf_info; + +/** + * printf_arg: + * @pa_char: an unsigned %char + * @pa_wchar: a %wchar_t + * @pa_short_int: a %short integer + * @pa_int: an %int + * @pa_long_int: a %long integer + * @pa_long_long_int: the widest signed integer type in use on the host + * @pa_u_short_int: an unsigned %short integer + * @pa_u_int: an unsigned %int + * @pa_u_long_int: an unsigned %long integer + * @pa_u_long_long_int: the widest unsigned integer type in use on the host + * @pa_float: a %float + * @pa_double: a %double + * @pa_long_double: a long %double, or a simple %double if it is the widest floating-point type in use on the host + * @pa_string: a %const pointer to %char + * @pa_wstring: a %const pointer to %wchar_t + * @pa_pointer: a generic pointer + * + * The various kinds of arguments that can be passed to printf. + */ +typedef union printf_arg +{ + unsigned char pa_char; + snv_wchar_t pa_wchar; + short int pa_short_int; + int pa_int; + long int pa_long_int; + intmax_t pa_long_long_int; + unsigned short int pa_u_short_int; + unsigned int pa_u_int; + unsigned long int pa_u_long_int; + uintmax_t pa_u_long_long_int; + float pa_float; + double pa_double; + long double pa_long_double; + const char *pa_string; + const snv_wchar_t *pa_wstring; + snv_constpointer pa_pointer; +} printf_arg; + +/** + * PRINTF_ERROR: + * @pi: A pointer to the current state for the parser + * @str: The error message + * + * Append an error that will be returned by printf_strerror. + */ +#define PRINTF_ERROR(pi, str) \ + printf_error(pi, __FILE__, __LINE__, SNV_ASSERT_FCN, str); + +typedef int printf_function (STREAM *stream, struct printf_info *pparser, + union printf_arg const * args); + +typedef int printf_arginfo_function (struct printf_info *pparser, size_t n, + int *argtypes); + +/** + * spec_entry: + * @spec: the specifier character that was matched + * @type: when @arg is NULL, the type of the only argument to the specifier + * @fmt: the handler function to actually print the arguments to the specifier + * @arg: the handler function to tell %printf about the types of the arguments to the specifier + * @user: the user data for the specifier, accessible to the handler function + * + * This is returned by register_printf_function. + */ +typedef struct spec_entry +{ + unsigned int spec_key; + int unused; /* for binary compatibility */ + int type; + printf_function *fmt; + printf_arginfo_function *arg; + snv_pointer user; +} +spec_entry; + +/** + * register_callback_function: printf.h + * @spec: the character which will trigger the functions, cast to an unsigned int. + * @fmt: the handler function to actually print the arguments to the specifier + * @arg: the handler function to tell %printf about the types of the arguments to the specifier + * + * Register the pair made of @fmt and @arg, so that it is called + * when @spec is encountered in a format string. If you create + * a shared library with an entry point named + * %snv_register_printf_funcs, and put the library in the + * search path given by the environment library %LTDL_LIBRARY_PATH, + * that entry point will be called when %libsnprintfv is initialized, + * passing a pointer to this kind of function (actually, a pointer + * to %register_printf_function) to it. This functionality is only + * present when the library is installed, not when it is built as + * a convenience library. + * + * Return value: + * Returns %NULL if @func was not successfully registered, a + * %spec_entry with the information on the function if it was. + **/ +typedef spec_entry *register_callback_function (unsigned spec, printf_function *func, printf_arginfo_function *arginfo); + +/* Codes to determine basic types. + + These values cover all the standard format specifications. + Users can add new values after PA_LAST for their own types. */ + +enum +{ + PA_INT, /* int */ + PA_CHAR, /* int, cast to char */ + PA_WCHAR, /* wide char */ + PA_STRING, /* const char *, a '\0'-terminated string */ + PA_WSTRING, /* const wchar_t *, wide character string */ + PA_POINTER, /* void * */ + PA_FLOAT, /* float */ + PA_DOUBLE, /* double */ + PA_LAST, + PA_UNKNOWN = -1 +}; + +/* Flag bits that can be set in a type. */ +#define PA_TYPE_MASK 0x00ff +#define PA_FLAG_MASK ~SNV_TYPE_MASK + +#define PA_FLAG_LONG_LONG (1 << 8) +#define PA_FLAG_LONG_DOUBLE PA_FLAG_LONG_LONG +#define PA_FLAG_LONG (1 << 9) +#define PA_FLAG_SHORT (1 << 10) +#define PA_FLAG_UNSIGNED (1 << 11) +#define PA_FLAG_CHAR (1 << 12) +#define PA_FLAG_PTR (1 << 13) + +/** + * SNV_EMIT: + * @ch: the character to be printed + * @stream: the stream on which to print + * @count: a variable to be updated with the count of printed + * characters + * + * Maintain the count while putting @ch in @stream, also be careful about + * handling %NULL stream if the handler is being called purely to count + * output size. + **/ +#define SNV_EMIT(ch, stream, count) \ + SNV_STMT_START { \ + if ((stream)) \ + { \ + if ((count) >= 0) \ + { \ + int m_status = stream_put((unsigned char) (ch), (stream)); \ + (count) = m_status < 0 ? m_status : (count) + m_status; \ + } \ + } \ + else \ + { \ + (void)(ch); \ + (count)++; \ + } \ + } SNV_STMT_END + +@protos format.c +@protos custom.c +@protos printf.c + +/* If you don't want to use snprintfv functions for *all* of your string + formatting API, then define COMPILING_SNPRINTFV_C and use the snv_ + prefix for the entry points below. */ +#ifndef COMPILING_PRINTF_C +#undef printf +#undef vprintf +#undef dprintf +#undef vdprintf +#undef fprintf +#undef vfprintf +#undef sprintf +#undef vsprintf +#undef snprintf +#undef vsnprintf +#undef asprintf +#undef vasprintf +#undef asprintfv +#undef dprintfv +#undef fprintfv +#undef sprintfv +#undef printfv +#undef snprintfv + +#define printf snv_printf +#define vprintf snv_vprintf +#define dprintf snv_dprintf +#define vdprintf snv_vdprintf +#define fprintf snv_fprintf +#define vfprintf snv_vfprintf +#define sprintf snv_sprintf +#define vsprintf snv_vsprintf +#define snprintf snv_snprintf +#define vsnprintf snv_vsnprintf +#define asprintf snv_asprintf +#define vasprintf snv_vasprintf +#define asprintfv snv_asprintfv +#define dprintfv snv_dprintfv +#define fprintfv snv_fprintfv +#define sprintfv snv_sprintfv +#define printfv snv_printfv +#define snprintfv snv_snprintfv +#endif /* !COMPILING_SNPRINTFV_C */ +#ifdef __cplusplus +} +#endif + +#endif /* SNPRINTFV_SNPRINTFV_H */ + +/* snprintfv.h ends here */ diff --git a/snprintfv/printf.stamp b/snprintfv/printf.stamp new file mode 100644 index 0000000..e69de29 diff --git a/snprintfv/stream.c b/snprintfv/stream.c new file mode 100644 index 0000000..17a441f --- /dev/null +++ b/snprintfv/stream.c @@ -0,0 +1,225 @@ +/* -*- Mode: C -*- */ + +/* stream.c --- customizable stream routines + * Copyright (C) 1998, 1999, 2000, 2002, 2003 Gary V. Vaughan + * Originally by Gary V. Vaughan, 1998 + * This file is part of Snprintfv + * + * Snprintfv 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. + * + * Snprintfv program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * As a special exception to the GNU General Public License, if you + * distribute this file as part of a program that also links with and + * uses the libopts library from AutoGen, you may include it under + * the same distribution terms used by the libopts library. + */ + +/* Code: */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef WITH_DMALLOC +# include +#endif + +#include "compat.h" +#include "stream.h" +#include "mem.h" + +struct stream +{ + snv_pointer stream; + unsigned long limit; + + StreamGet get_func; + StreamPut put_func; +}; + +static int +stream_not_readable (STREAM *stream) +{ + (void)stream; + return -1; +} + +static int +stream_not_writable (int ch, STREAM *stream) +{ + (void)stream; + (void)ch; + return -1; +} + +/** + * stream_new: constructor + * @dets: user supplied stream details to be passed into the various funcs. + * @limit: the maximum number of consecutive bytes to fit in @dets. + * @get_func: function to get a character from @dets stream. + * @put_func: function to put a character in @dets stream. + * + * Allocate and initialize a new %STREAM data type. The @get_func + * and @put_func can be NULL if you intend to create a non-readable + * or non-writable stream, respectively. + * + * Return value: + * The address of the newly allocated and initialised stream is returned. + **/ +STREAM * +stream_new (snv_pointer dets, unsigned long limit, StreamGet get_func, StreamPut put_func) +{ + STREAM *new = snv_new (STREAM, 1); + + new->stream = dets; + new->limit = limit; + + new->get_func = get_func ? get_func : stream_not_readable; + new->put_func = put_func ? put_func : stream_not_writable; + + return new; +} + + +/** + * stream_delete: destructor + * @stream: The stream pending deletion + * + * The memory associated with @stream is recycled. + + * Return value: + * The %dets supplied by the user when the stream was created are + * returned for handling by the calling function. + **/ +snv_pointer +stream_delete (STREAM *stream) +{ + snv_pointer dets = stream->stream; + snv_delete (stream); + return dets; +} + +/** + * stream_details: + * @stream: the stream being queried. + * + * The finalization function specified when @stream was created (if any) + * is called, and then the memory associated with @stream is recycled. + * It is the responsibility of the finalization function to recycle, or + * otherwise manage, any memory associated with the user supplied %dets. + * Return value: + * This function returns the stream details associated with @stream + * when it was originally created. + **/ +snv_pointer +stream_details (STREAM *stream) +{ + return stream ? stream->stream : NULL; +} + +/** + * stream_put: + * @ch: A single character to be placed in @stream. + * @stream: The stream to be written to. + * + * This function will @ch in @stream if that stream's output limit will + * not be exceeded. + * + * Return value: + * If @stream is full, return 1. Otherwise, if any other error occurs, + * that error code is returned unchanged. This is of course dependant + * on what the handler function uses to indicate an error. If the stream + * is not full and the stream's writing function succeeds, 1 (the number of + * characters emitted!) is returned. + **/ +int +stream_put (int ch, STREAM *stream) +{ + int ch_or_errorcode; + + if (!stream) + return -1; + + if (stream->limit < 1) + return 1; + + stream->limit -= 1; + ch_or_errorcode = (*stream->put_func) ((unsigned char) ch, stream); + + return (ch_or_errorcode < 0) ? ch_or_errorcode : 1; +} + +/** + * stream_puts: + * @s: A string to be placed in @stream. + * @stream: The stream to be written to. + * + * This function will @ch in @stream if that stream's output limit will + * not be exceeded. + * + * Return value: + * If any other error occurs, that error code is returned unchanged. + * This is of course dependant on what the handler function uses to + * indicate an error. If the stream becomes full, the remaining + * characters are not printed. If the stream's writing function + * always succeeds, the number of characters emitted or skipped is + * returned. + **/ +int +stream_puts (char *s, STREAM *stream) +{ + int ch_or_errorcode; + int num; + + if (!stream) + return -1; + + for (num = 0; *s; num++, s++) + { + if (stream->limit < 1) + return (int)((size_t)num + strlen (s)); + + stream->limit -= 1; + ch_or_errorcode = (*stream->put_func) ((unsigned char) *s, stream); + + if (ch_or_errorcode < 0) + return ch_or_errorcode; + } + + return num; +} + +/** + * stream_get: + * @stream: The stream to be read from. + * + * This function will try to read a single character from @stream. + * + * Return value: + * If an error occurs or the end of @stream is reached, -1 is returned. + * Under normal circumstances the value if the character read (cast to + * an int) is returned. + **/ +int +stream_get (STREAM *stream) +{ + return (*stream->get_func) (stream); +} + +/* + * Local Variables: + * mode: C + * c-file-style: "gnu" + * indent-tabs-mode: nil + * End: + * end of snprintfv/stream.c */ diff --git a/snprintfv/stream.h b/snprintfv/stream.h new file mode 100644 index 0000000..e4a5cd1 --- /dev/null +++ b/snprintfv/stream.h @@ -0,0 +1,191 @@ +/* -*- Mode: C -*- */ + +/* stream.h --- customizable stream routines + * Copyright (C) 1998, 1999, 2000, 2002 Gary V. Vaughan + * Originally by Gary V. Vaughan, 1998 + * This file is part of Snprintfv + * + * Snprintfv 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. + * + * Snprintfv program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * As a special exception to the GNU General Public License, if you + * distribute this file as part of a program that also links with and + * uses the libopts library from AutoGen, you may include it under + * the same distribution terms used by the libopts library. + */ + +/* Code: */ + +#ifndef STREAM_H +#define STREAM_H 1 + +#define STREAM_READABLE (1 << 0) +#define STREAM_WRITABLE (1 << 1) + +/** + * SNV_UNLIMITED: + * Used to denote that there is no upper limit to the number of characters + * that can safely be written to a stream. + **/ +#define SNV_UNLIMITED (~0UL) + +#ifdef __cplusplus +extern "C" +{ +#if 0 +/* This brace is so that emacs can still indent properly: */ } +#endif +#endif /* __cplusplus */ + +/** + * STREAM: + * Data type used to pass details of streams between functions, + * much like stdio's %FILE, but more flexible. A %STREAM can be uni- or + * bi-directional depending on how it is initialised. + **/ +typedef struct stream STREAM; + +/** + * StreamPut: + * @ch: The character to write to @stream cast to an int. + * @stream: The stream being written to. + * + * Type of the function to put a character in a writeable stream. + * + * Return value: + * The function should return the character written to the + * stream, cast to an int if it was written successfully, or + * else %EOF, if the write failed. + **/ +typedef int (*StreamPut) (int ch, STREAM * stream); + +/** + * StreamGet: + * @stream: The stream being read from. + * + * Type of the function to get a character from a readable stream. + * + * Return value: + * The function should return the character read from the + * stream, cast to an int if it was read successfully, or + * else %EOF, if the read failed. + **/ +typedef int (*StreamGet) (STREAM * stream); + + +/** + * stream_new: constructor + * @dets: user supplied stream details to be passed into the various funcs. + * @limit: the maximum number of consecutive bytes to fit in @dets. + * @get_func: function to get a character from @dets stream. + * @put_func: function to put a character in @dets stream. + * + * Allocate and initialize a new %STREAM data type. The @get_func + * and @put_func can be NULL if you intend to create a non-readable + * or non-writable stream, respectively. + * + * Return value: + * The address of the newly allocated and initialised stream is returned. + **/ +extern STREAM * +stream_new (snv_pointer dets, unsigned long limit, StreamGet get_func, StreamPut put_func); + +/** + * stream_delete: destructor + * @stream: The stream pending deletion + * + * The memory associated with @stream is recycled. + + * Return value: + * The %dets supplied by the user when the stream was created are + * returned for handling by the calling function. + **/ +extern snv_pointer +stream_delete (STREAM *stream); + +/** + * stream_details: + * @stream: the stream being queried. + * + * The finalization function specified when @stream was created (if any) + * is called, and then the memory associated with @stream is recycled. + * It is the responsibility of the finalization function to recycle, or + * otherwise manage, any memory associated with the user supplied %dets. + * Return value: + * This function returns the stream details associated with @stream + * when it was originally created. + **/ +extern snv_pointer +stream_details (STREAM *stream); + +/** + * stream_put: + * @ch: A single character to be placed in @stream. + * @stream: The stream to be written to. + * + * This function will @ch in @stream if that stream's output limit will + * not be exceeded. + * + * Return value: + * If @stream is full, return 1. Otherwise, if any other error occurs, + * that error code is returned unchanged. This is of course dependant + * on what the handler function uses to indicate an error. If the stream + * is not full and the stream's writing function succeeds, 1 (the number of + * characters emitted!) is returned. + **/ +extern int +stream_put (int ch, STREAM *stream); + +/** + * stream_puts: + * @s: A string to be placed in @stream. + * @stream: The stream to be written to. + * + * This function will @ch in @stream if that stream's output limit will + * not be exceeded. + * + * Return value: + * If any other error occurs, that error code is returned unchanged. + * This is of course dependant on what the handler function uses to + * indicate an error. If the stream becomes full, the remaining + * characters are not printed. If the stream's writing function + * always succeeds, the number of characters emitted or skipped is + * returned. + **/ +extern int +stream_puts (char *s, STREAM *stream); + +/** + * stream_get: + * @stream: The stream to be read from. + * + * This function will try to read a single character from @stream. + * + * Return value: + * If an error occurs or the end of @stream is reached, -1 is returned. + * Under normal circumstances the value if the character read (cast to + * an int) is returned. + **/ +extern int +stream_get (STREAM *stream); + +#line 87 "stream.in" +#ifdef __cplusplus +#if 0 +/* This brace is so that emacs can still indent properly: */ +{ +#endif +} +#endif /* __cplusplus */ + +#endif /* STREAM_H */ diff --git a/snprintfv/stream.in b/snprintfv/stream.in new file mode 100644 index 0000000..41be8f2 --- /dev/null +++ b/snprintfv/stream.in @@ -0,0 +1,95 @@ +/* -*- Mode: C -*- */ + +/* stream.h --- customizable stream routines + * Copyright (C) 1998, 1999, 2000, 2002 Gary V. Vaughan + * Originally by Gary V. Vaughan, 1998 + * This file is part of Snprintfv + * + * Snprintfv 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. + * + * Snprintfv program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * As a special exception to the GNU General Public License, if you + * distribute this file as part of a program that also links with and + * uses the libopts library from AutoGen, you may include it under + * the same distribution terms used by the libopts library. + */ + +/* Code: */ + +#ifndef STREAM_H +#define STREAM_H 1 + +#define STREAM_READABLE (1 << 0) +#define STREAM_WRITABLE (1 << 1) + +/** + * SNV_UNLIMITED: + * Used to denote that there is no upper limit to the number of characters + * that can safely be written to a stream. + **/ +#define SNV_UNLIMITED (~0UL) + +#ifdef __cplusplus +extern "C" +{ +#if 0 +/* This brace is so that emacs can still indent properly: */ } +#endif +#endif /* __cplusplus */ + +/** + * STREAM: + * Data type used to pass details of streams between functions, + * much like stdio's %FILE, but more flexible. A %STREAM can be uni- or + * bi-directional depending on how it is initialised. + **/ +typedef struct stream STREAM; + +/** + * StreamPut: + * @ch: The character to write to @stream cast to an int. + * @stream: The stream being written to. + * + * Type of the function to put a character in a writeable stream. + * + * Return value: + * The function should return the character written to the + * stream, cast to an int if it was written successfully, or + * else %EOF, if the write failed. + **/ +typedef int (*StreamPut) (int ch, STREAM * stream); + +/** + * StreamGet: + * @stream: The stream being read from. + * + * Type of the function to get a character from a readable stream. + * + * Return value: + * The function should return the character read from the + * stream, cast to an int if it was read successfully, or + * else %EOF, if the read failed. + **/ +typedef int (*StreamGet) (STREAM * stream); + + +@protos stream.c +#ifdef __cplusplus +#if 0 +/* This brace is so that emacs can still indent properly: */ +{ +#endif +} +#endif /* __cplusplus */ + +#endif /* STREAM_H */ diff --git a/snprintfv/stream.stamp b/snprintfv/stream.stamp new file mode 100644 index 0000000..e69de29 diff --git a/xml2ag/Makefile.am b/xml2ag/Makefile.am new file mode 100644 index 0000000..d2d05d2 --- /dev/null +++ b/xml2ag/Makefile.am @@ -0,0 +1,111 @@ +## -*- Mode: Makefile -*- +## --------------------------------------------------------------------- +## Makefile.am -- process this file with automake to produce Makefile.in +## +## Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . +## +TARG = xml2ag + +bin_PROGRAMS = xml2ag +csrcs = xml2ag.c +gsrcs = xmlopts.c fork.c +BUILT_SOURCES = x.c +nodist_xml2ag_SOURCES = $(BUILT_SOURCES) +SUBDIRS = test +EXTRA_DIST = xmlopts.def fork.tpl $(gsrcs) $(csrcs) +xml2ag_LDADD = $(top_builddir)/autoopts/libopts.la $(LIBXML2_LIBS) +man_MANS = $(TARG).1 +TEXI_FILES = invoke-$(TARG).texi invoke-$(TARG).menu +DOCFILES = $(TEXI_FILES) $(man_MANS) +DISTCLEANFILES = $(DOCFILES) $(nodist_xml2ag_SOURCES) stamp-* +AM_CPPFLAGS = @INCLIST@ $(LIBXML2_CFLAGS) +AM_CFLAGS = @WARN_CFLAGS@ +AG_ENV = top_builddir="$(top_builddir)" top_srcdir="$(top_srcdir)" \ + VERBOSE="$(V)" +RUN_AG = $(AG_ENV) $(SHELL) "${top_srcdir}/build-aux/run-ag.sh" +DOC_TIMEOUT = -DLEVEL=section --timeout=`expr $(AG_TIMEOUT) '*' 3` + +all : gen +gen : $(gsrcs) $(DOCFILES) + +if AMDEP +DEPFL_OPTS = $(DEPDIR)/opts-dep.mk +DEPFL_MAN = $(DEPDIR)/man-dep.mk +DEPFL_TEXI = $(DEPDIR)/texi-dep.mk +DEPFL_FORK = $(DEPDIR)/fork-dep.mk + +$(DEPFL_OPTS) : + $(RUN_AG) "$@" + +$(DEPFL_MAN) : + $(RUN_AG) "$@" + +$(DEPFL_TEXI) : + $(RUN_AG) "$@" + +$(DEPFL_FORK) : + $(RUN_AG) "$@" + +include $(DEPDIR)/opts-dep.mk +include $(DEPDIR)/man-dep.mk +include $(DEPDIR)/texi-dep.mk +include $(DEPDIR)/fork-dep.mk +else +DEPFL_OPTS = $@ +DEPFL_MAN = $@ +DEPFL_TEXI = $@ +DEPFL_FORK = $@ +endif + +AGARG_OPTS = -MF$(DEPFL_OPTS) -MT$@ -MP +AGARG_MAN = -MF$(DEPFL_MAN) -MT$@ -MP -Tagman-cmd +AGARG_TEXI = -MF$(DEPFL_TEXI) -MT$@ -MP -Tagtexi-cmd $(DOC_TIMEOUT) +AGARG_FORK = -MF$(DEPFL_FORK) -MT$@ -MP -L$(srcdir) -Tfork.tpl + +$(getdefs_OBJECTS) xmlopts.c xmlopts.h : stamp-opts +stamp-opts : xmlopts.def + $(RUN_AG) $(AGARG_OPTS) "$(srcdir)/xmlopts.def" + +$(TARG).1 : stamp-man +stamp-man : xmlopts.def $(TARG)$(EXEEXT) ../columns/columns$(EXEEXT) + $(RUN_AG) $(AGARG_MAN) "$(srcdir)/xmlopts.def" + +invoke-$(TARG).texi invoke-$(TARG).menu : stamp-texi +stamp-texi : xmlopts.def $(TARG)$(EXEEXT) ../columns/columns$(EXEEXT) + $(RUN_AG) $(AGARG_TEXI) "$(srcdir)/xmlopts.def" + +fork.c : stamp-fork +stamp-fork : fork.tpl xmlopts.def $(CLexe) + $(RUN_AG) $(AGARG_FORK) "$(srcdir)/xmlopts.def" + +$(CLexe) : + cd ../columns ; $(MAKE) $(CLnam) + +x.c : $(gsrcs) $(csrcs) + exec > $@ ; \ + echo '#undef PKGDATADIR' ; \ + echo '#define PKGDATADIR "$(pkgdatadir)"' ; \ + echo ; echo '#define DEFINING 1' ; \ + echo '#include "autoopts/project.h"' ; \ + for f in $(gsrcs) $(csrcs) ; \ + do echo "#include \"$$f\"" ; done + +.NOTPARALLEL: + +# end of Makefile.am diff --git a/xml2ag/Makefile.in b/xml2ag/Makefile.in new file mode 100644 index 0000000..5b85e95 --- /dev/null +++ b/xml2ag/Makefile.in @@ -0,0 +1,985 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 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. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +bin_PROGRAMS = xml2ag$(EXEEXT) +subdir = xml2ag +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/ag_macros.m4 \ + $(top_srcdir)/config/asm-underscore.m4 \ + $(top_srcdir)/config/extensions.m4 \ + $(top_srcdir)/config/guile.m4 \ + $(top_srcdir)/config/host-cpu-c-abi.m4 \ + $(top_srcdir)/config/lib-ld.m4 \ + $(top_srcdir)/config/lib-link.m4 \ + $(top_srcdir)/config/lib-prefix.m4 \ + $(top_srcdir)/config/libopts.m4 \ + $(top_srcdir)/config/libtool.m4 \ + $(top_srcdir)/config/ltoptions.m4 \ + $(top_srcdir)/config/ltsugar.m4 \ + $(top_srcdir)/config/ltversion.m4 \ + $(top_srcdir)/config/lt~obsolete.m4 \ + $(top_srcdir)/config/onceonly.m4 $(top_srcdir)/config/pkg.m4 \ + $(top_srcdir)/config/snprintfv.m4 \ + $(top_srcdir)/config/stdnoreturn.m4 \ + $(top_srcdir)/config/unlocked-io.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" +PROGRAMS = $(bin_PROGRAMS) +am__objects_1 = x.$(OBJEXT) +nodist_xml2ag_OBJECTS = $(am__objects_1) +xml2ag_OBJECTS = $(nodist_xml2ag_OBJECTS) +am__DEPENDENCIES_1 = +xml2ag_DEPENDENCIES = $(top_builddir)/autoopts/libopts.la \ + $(am__DEPENDENCIES_1) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/config/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/x.Po +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(nodist_xml2ag_SOURCES) +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +man1dir = $(mandir)/man1 +NROFF = nroff +MANS = $(man_MANS) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir distdir-am +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/config/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +AGEN5_TESTS = @AGEN5_TESTS@ +AG_LDFLAGS = @AG_LDFLAGS@ +AG_MAJOR_VERSION = @AG_MAJOR_VERSION@ +AG_MINOR_VERSION = @AG_MINOR_VERSION@ +AG_STATIC_AUTOGEN = @AG_STATIC_AUTOGEN@ +AG_TIMEOUT = @AG_TIMEOUT@ +AG_VERSION = @AG_VERSION@ +AG_XML2 = @AG_XML2@ +AGexe = @AGexe@ +AGnam = @AGnam@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AO_AGE = @AO_AGE@ +AO_CURRENT = @AO_CURRENT@ +AO_REVISION = @AO_REVISION@ +AO_TEMPLATE_VERSION = @AO_TEMPLATE_VERSION@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLexe = @CLexe@ +CLnam = @CLnam@ +CONFIG_SHELL = @CONFIG_SHELL@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBUG_ENABLED = @DEBUG_ENABLED@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +DYNAMIC_AG = @DYNAMIC_AG@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_STATIC = @ENABLE_STATIC@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GDexe = @GDexe@ +GDnam = @GDnam@ +GO_AGE = @GO_AGE@ +GO_CURRENT = @GO_CURRENT@ +GO_REVISION = @GO_REVISION@ +GREP = @GREP@ +GUILE_CFLAGS = @GUILE_CFLAGS@ +GUILE_EFFECTIVE_VERSION = @GUILE_EFFECTIVE_VERSION@ +GUILE_LDFLAGS = @GUILE_LDFLAGS@ +GUILE_LIBS = @GUILE_LIBS@ +GUILE_LTLIBS = @GUILE_LTLIBS@ +HOST_CPU = @HOST_CPU@ +HOST_CPU_C_ABI = @HOST_CPU_C_ABI@ +INCLIST = @INCLIST@ +INCSNPRINTFV = @INCSNPRINTFV@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSNPRINTFV = @LIBSNPRINTFV@ +LIBTOOL = @LIBTOOL@ +LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ +LIBXML2_LIBS = @LIBXML2_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +M4_SRC = @M4_SRC@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPTS_TESTDIR = @OPTS_TESTDIR@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSIX_SHELL = @POSIX_SHELL@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STDNORETURN_H = @STDNORETURN_H@ +STRIP = @STRIP@ +TEXI2HTML = @TEXI2HTML@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_aux_dir = @ac_aux_dir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +TARG = xml2ag +csrcs = xml2ag.c +gsrcs = xmlopts.c fork.c +BUILT_SOURCES = x.c +nodist_xml2ag_SOURCES = $(BUILT_SOURCES) +SUBDIRS = test +EXTRA_DIST = xmlopts.def fork.tpl $(gsrcs) $(csrcs) +xml2ag_LDADD = $(top_builddir)/autoopts/libopts.la $(LIBXML2_LIBS) +man_MANS = $(TARG).1 +TEXI_FILES = invoke-$(TARG).texi invoke-$(TARG).menu +DOCFILES = $(TEXI_FILES) $(man_MANS) +DISTCLEANFILES = $(DOCFILES) $(nodist_xml2ag_SOURCES) stamp-* +AM_CPPFLAGS = @INCLIST@ $(LIBXML2_CFLAGS) +AM_CFLAGS = @WARN_CFLAGS@ +AG_ENV = top_builddir="$(top_builddir)" top_srcdir="$(top_srcdir)" \ + VERBOSE="$(V)" + +RUN_AG = $(AG_ENV) $(SHELL) "${top_srcdir}/build-aux/run-ag.sh" +DOC_TIMEOUT = -DLEVEL=section --timeout=`expr $(AG_TIMEOUT) '*' 3` +@AMDEP_FALSE@DEPFL_OPTS = $@ +@AMDEP_TRUE@DEPFL_OPTS = $(DEPDIR)/opts-dep.mk +@AMDEP_FALSE@DEPFL_MAN = $@ +@AMDEP_TRUE@DEPFL_MAN = $(DEPDIR)/man-dep.mk +@AMDEP_FALSE@DEPFL_TEXI = $@ +@AMDEP_TRUE@DEPFL_TEXI = $(DEPDIR)/texi-dep.mk +@AMDEP_FALSE@DEPFL_FORK = $@ +@AMDEP_TRUE@DEPFL_FORK = $(DEPDIR)/fork-dep.mk +AGARG_OPTS = -MF$(DEPFL_OPTS) -MT$@ -MP +AGARG_MAN = -MF$(DEPFL_MAN) -MT$@ -MP -Tagman-cmd +AGARG_TEXI = -MF$(DEPFL_TEXI) -MT$@ -MP -Tagtexi-cmd $(DOC_TIMEOUT) +AGARG_FORK = -MF$(DEPFL_FORK) -MT$@ -MP -L$(srcdir) -Tfork.tpl +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu xml2ag/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu xml2ag/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ + fi; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p \ + || test -f $$p1 \ + ; then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' \ + -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' \ + `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + +xml2ag$(EXEEXT): $(xml2ag_OBJECTS) $(xml2ag_DEPENDENCIES) $(EXTRA_xml2ag_DEPENDENCIES) + @rm -f xml2ag$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(xml2ag_OBJECTS) $(xml2ag_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/x.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-man1: $(man_MANS) + @$(NORMAL_INSTALL) + @list1=''; \ + list2='$(man_MANS)'; \ + test -n "$(man1dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.1[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ + done; } + +uninstall-man1: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man1dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.1[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) + +# 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. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-recursive +all-am: Makefile $(PROGRAMS) $(MANS) +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +clean: clean-recursive + +clean-am: clean-binPROGRAMS clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f ./$(DEPDIR)/x.Po + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: install-man + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: install-binPROGRAMS + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: install-man1 + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f ./$(DEPDIR)/x.Po + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-man + +uninstall-man: uninstall-man1 + +.MAKE: $(am__recursive_targets) all check install install-am \ + install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ + am--depfiles check check-am clean clean-binPROGRAMS \ + clean-generic clean-libtool cscopelist-am ctags ctags-am \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-binPROGRAMS \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-man1 \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-binPROGRAMS uninstall-man \ + uninstall-man1 + +.PRECIOUS: Makefile + + +all : gen +gen : $(gsrcs) $(DOCFILES) + +@AMDEP_TRUE@$(DEPFL_OPTS) : +@AMDEP_TRUE@ $(RUN_AG) "$@" + +@AMDEP_TRUE@$(DEPFL_MAN) : +@AMDEP_TRUE@ $(RUN_AG) "$@" + +@AMDEP_TRUE@$(DEPFL_TEXI) : +@AMDEP_TRUE@ $(RUN_AG) "$@" + +@AMDEP_TRUE@$(DEPFL_FORK) : +@AMDEP_TRUE@ $(RUN_AG) "$@" + +@AMDEP_TRUE@include $(DEPDIR)/opts-dep.mk +@AMDEP_TRUE@include $(DEPDIR)/man-dep.mk +@AMDEP_TRUE@include $(DEPDIR)/texi-dep.mk +@AMDEP_TRUE@include $(DEPDIR)/fork-dep.mk + +$(getdefs_OBJECTS) xmlopts.c xmlopts.h : stamp-opts +stamp-opts : xmlopts.def + $(RUN_AG) $(AGARG_OPTS) "$(srcdir)/xmlopts.def" + +$(TARG).1 : stamp-man +stamp-man : xmlopts.def $(TARG)$(EXEEXT) ../columns/columns$(EXEEXT) + $(RUN_AG) $(AGARG_MAN) "$(srcdir)/xmlopts.def" + +invoke-$(TARG).texi invoke-$(TARG).menu : stamp-texi +stamp-texi : xmlopts.def $(TARG)$(EXEEXT) ../columns/columns$(EXEEXT) + $(RUN_AG) $(AGARG_TEXI) "$(srcdir)/xmlopts.def" + +fork.c : stamp-fork +stamp-fork : fork.tpl xmlopts.def $(CLexe) + $(RUN_AG) $(AGARG_FORK) "$(srcdir)/xmlopts.def" + +$(CLexe) : + cd ../columns ; $(MAKE) $(CLnam) + +x.c : $(gsrcs) $(csrcs) + exec > $@ ; \ + echo '#undef PKGDATADIR' ; \ + echo '#define PKGDATADIR "$(pkgdatadir)"' ; \ + echo ; echo '#define DEFINING 1' ; \ + echo '#include "autoopts/project.h"' ; \ + for f in $(gsrcs) $(csrcs) ; \ + do echo "#include \"$$f\"" ; done + +.NOTPARALLEL: + +# end of Makefile.am + +# 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/xml2ag/fork.c b/xml2ag/fork.c new file mode 100644 index 0000000..6f43785 --- /dev/null +++ b/xml2ag/fork.c @@ -0,0 +1,315 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * DO NOT EDIT THIS FILE (fork.c) + * + * It has been AutoGen-ed + * From the definitions ./xmlopts.def + * and the template file fork.tpl + * + * This module will fire up autogen and have it read definitions + * from its standard-in. + */ + +static char const fs_err_fmt[] = "%s fs ERROR %d (%s) on %s\n"; + +/** + * increase size of argument vector. Allocation will always be a + * multiple of 8 times sizeof(void *). + */ +static void +get_argv_space(void) +{ + static void * av = NULL; //!< static arg vector + int act = (int)xml2agOptions.origArgCt; //!< current count + + /* + * First time through, use "malloc" not "realloc". + */ + if (av == NULL) { + size_t csz = act * sizeof(void *); //! current size + /* + * "act" will always be one less than a multiple of 8 and + * at least one larger than before. After first time through, + * each call will increment by 8. + */ + act = (act + 10) & ~0x0007; + av = malloc(act-- * sizeof(void *)); + if (av == NULL) + goto no_memory; + memcpy(av, xml2agOptions.origArgVect, csz); + + } else { + act += 8; + av = realloc(av, (act + 1) * sizeof(void *)); + if (av == NULL) + goto no_memory; + } + + xml2agOptions.origArgCt = act; + xml2agOptions.origArgVect = av; + return; + + no_memory: + fprintf(stderr, "No memory for %d args\n", act+1); + exit(EXIT_FAILURE); +} + +static void +add_arg(char const * arg, int ix) +{ + if (ix >= (int)xml2agOptions.origArgCt) + get_argv_space(); + + xml2agOptions.origArgVect[ix] = VOIDP(arg); +} + +static int +become_child(int * fd, char const * in_file) +{ + if (pipe(fd) != 0) { + fprintf(stderr, fs_err_fmt, xml2agOptions.pzProgName, + errno, strerror( errno ), "pipe(2)"); + exit(EXIT_FAILURE); + } + + fflush(stdout); + fflush(stdin); + + switch (fork()) { + case -1: + fprintf(stderr, fs_err_fmt, xml2agOptions.pzProgName, + errno, strerror( errno ), "fork(2)"); + exit(EXIT_FAILURE); + + case 0: + fclose(stdin); + if (dup2(fd[0], STDIN_FILENO) != STDIN_FILENO) { + fprintf(stderr, fs_err_fmt, xml2agOptions.pzProgName, + errno, strerror( errno ), "dup2(2) w/ STDIN_FILENO"); + exit(EXIT_FAILURE); + } + close(fd[1]); + break; + + default: + errno = 0; + ag_pipe_fp = fdopen(fd[1], "w"); + if (ag_pipe_fp == NULL) { + fprintf(stderr, fs_err_fmt, xml2agOptions.pzProgName, + errno, strerror( errno ), "fdopen(2) w/ pipe[1]"); + exit(EXIT_FAILURE); + } + close(fd[0]); + return 0; + } + + if (! HAVE_OPT( BASE_NAME )) { + if (in_file == NULL) + in_file = "stdin"; + else { + char * pz = strrchr(in_file, '.'); + if (pz != NULL) { + in_file = pz = strdup(in_file); + pz = strrchr(pz, '.'); + *pz = '\0'; + } + } + SET_OPT_BASE_NAME(in_file); + } + + return 1; +} + +void +fork_ag(char const * in_file) +{ + int fd[2]; + + if (! become_child(fd, in_file)) + return; // parent process returns + + get_argv_space(); + + { + static char const zAg[] = "autogen"; + char * pzArg; + int ix = 1; + + { + char * pz = malloc(strlen( xml2agOptions.pzProgPath ) + 7); + char * p = strrchr(xml2agOptions.pzProgPath, '/'); + + if (p == NULL) { + strcpy(pz, zAg); + } else { + size_t len = (size_t)(p - xml2agOptions.pzProgPath) + 1; + memcpy(pz, xml2agOptions.pzProgPath, len); + strcpy(pz + len, zAg); + } + + add_arg(pz, 0); + } + + if (HAVE_OPT(TEMPL_DIRS)) { + int optCt = STACKCT_OPT(TEMPL_DIRS); + char const ** ppOA = STACKLST_OPT(TEMPL_DIRS); + do { + char const * pA = *(ppOA++); + pzArg = malloc(14 + strlen(pA)); + sprintf(pzArg, "--templ-dirs=%s", pA); + add_arg(pzArg, ix++); + } while (--optCt > 0); + } + + if (HAVE_OPT(DEFINITIONS)) { + pzArg = malloc(15 + strlen( OPT_ARG( DEFINITIONS ))); + sprintf(pzArg, "--definitions=%s", OPT_ARG( DEFINITIONS )); + add_arg(pzArg, ix++); + } + + if (HAVE_OPT(SHELL)) { + pzArg = malloc(9 + strlen( OPT_ARG( SHELL ))); + sprintf(pzArg, "--shell=%s", OPT_ARG( SHELL )); + add_arg(pzArg, ix++); + } + + if (HAVE_OPT(NO_FMEMOPEN)) { + add_arg("--no-fmemopen", ix++); + } + + if (HAVE_OPT(EQUATE)) { + pzArg = malloc(10 + strlen( OPT_ARG( EQUATE ))); + sprintf(pzArg, "--equate=%s", OPT_ARG( EQUATE )); + add_arg(pzArg, ix++); + } + + if (HAVE_OPT(BASE_NAME)) { + pzArg = malloc(13 + strlen( OPT_ARG( BASE_NAME ))); + sprintf(pzArg, "--base-name=%s", OPT_ARG( BASE_NAME )); + add_arg(pzArg, ix++); + } + + if (HAVE_OPT(SOURCE_TIME)) { + add_arg("--source-time", ix++); + } + + if (HAVE_OPT(WRITABLE)) { + add_arg("--writable", ix++); + } + + if (HAVE_OPT(LOOP_LIMIT)) { + pzArg = malloc((size_t)26); + sprintf(pzArg, "--loop-limit=%d", (int)OPT_VALUE_LOOP_LIMIT); + add_arg(pzArg, ix++); + } + + if (HAVE_OPT(TIMEOUT)) { + pzArg = malloc((size_t)23); + sprintf(pzArg, "--timeout=%d", (int)OPT_VALUE_TIMEOUT); + add_arg(pzArg, ix++); + } + + if (HAVE_OPT(TRACE)) { + static char const * kwlist[] = { + "nothing", "debug-message", "server-shell", + "templates", "block-macros", "expressions", + "everything" }; + pzArg = malloc(9 + strlen( kwlist[ OPT_VALUE_TRACE ] )); + sprintf(pzArg, "--trace=%s", kwlist[ OPT_VALUE_TRACE ]); + add_arg(pzArg, ix++); + } + + if (HAVE_OPT(TRACE_OUT)) { + pzArg = malloc(13 + strlen( OPT_ARG( TRACE_OUT ))); + sprintf(pzArg, "--trace-out=%s", OPT_ARG( TRACE_OUT )); + add_arg(pzArg, ix++); + } + + if (HAVE_OPT(SHOW_DEFS)) { + add_arg("--show-defs", ix++); + } + + if (HAVE_OPT(USED_DEFINES)) { + add_arg("--used-defines", ix++); + } + + if (HAVE_OPT(CORE)) { + add_arg("--core", ix++); + } + + if (HAVE_OPT(SKIP_SUFFIX)) { + int optCt = STACKCT_OPT(SKIP_SUFFIX); + char const ** ppOA = STACKLST_OPT(SKIP_SUFFIX); + do { + char const * pA = *(ppOA++); + pzArg = malloc(15 + strlen(pA)); + sprintf(pzArg, "--skip-suffix=%s", pA); + add_arg(pzArg, ix++); + } while (--optCt > 0); + } + + if (HAVE_OPT(SELECT_SUFFIX)) { + int optCt = STACKCT_OPT(SELECT_SUFFIX); + char const ** ppOA = STACKLST_OPT(SELECT_SUFFIX); + do { + char const * pA = *(ppOA++); + pzArg = malloc(17 + strlen(pA)); + sprintf(pzArg, "--select-suffix=%s", pA); + add_arg(pzArg, ix++); + } while (--optCt > 0); + } + + if (HAVE_OPT(DEFINE)) { + int optCt = STACKCT_OPT(DEFINE); + char const ** ppOA = STACKLST_OPT(DEFINE); + do { + char const * pA = *(ppOA++); + pzArg = malloc(10 + strlen(pA)); + sprintf(pzArg, "--define=%s", pA); + add_arg(pzArg, ix++); + } while (--optCt > 0); + } + + if (HAVE_OPT(UNDEFINE)) { + int optCt = STACKCT_OPT(UNDEFINE); + char const ** ppOA = STACKLST_OPT(UNDEFINE); + do { + char const * pA = *(ppOA++); + pzArg = malloc(12 + strlen(pA)); + sprintf(pzArg, "--undefine=%s", pA); + add_arg(pzArg, ix++); + } while (--optCt > 0); + } + + if (HAVE_OPT(MAKE_DEP)) { + int optCt = STACKCT_OPT(MAKE_DEP); + char const ** ppOA = STACKLST_OPT(MAKE_DEP); + do { + char const * pA = *(ppOA++); + pzArg = malloc(12 + strlen(pA)); + sprintf(pzArg, "--make-dep=%s", pA); + add_arg(pzArg, ix++); + } while (--optCt > 0); + } + + xml2agOptions.origArgVect[ix] = NULL; + execvp(xml2agOptions.origArgVect[0], xml2agOptions.origArgVect); + + /* + * IF the first try fails, it may be because xml2ag and autogen have + * different paths. Try again with just plain "autogen" and let + * the OS search "PATH" for the program. + */ + execvp(zAg, xml2agOptions.origArgVect); + fprintf(stderr, fs_err_fmt, xml2agOptions.pzProgName, + errno, strerror(errno), "execvp(2)"); + exit(EXIT_FAILURE); + } +} + +/* + * Local Variables: + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of fork.c */ diff --git a/xml2ag/fork.tpl b/xml2ag/fork.tpl new file mode 100644 index 0000000..737a843 --- /dev/null +++ b/xml2ag/fork.tpl @@ -0,0 +1,259 @@ +[= AutoGen5 Template c=fork.c -*- Mode: C -*- =] +[= # + * fork.tpl: template for passing arguments to autogen forked process. + * + * This file is part of AutoGen. + * AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoGen is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AutoGen is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + =][= + +(define up-c-name (lambda (ag-name) + (string-upcase! (string->c-name! (get ag-name))) )) + +(dne " * " "/* ")=] + * + * This module will fire up autogen and have it read definitions + * from its standard-in. + */ + +static char const fs_err_fmt[] = "%s fs ERROR %d (%s) on %s\n"; + +/** + * increase size of argument vector. Allocation will always be a + * multiple of 8 times sizeof(void *). + */ +static void +get_argv_space(void) +{ + static void * av = NULL; //!< static arg vector + int act = (int)xml2agOptions.origArgCt; //!< current count + + /* + * First time through, use "malloc" not "realloc". + */ + if (av == NULL) { + size_t csz = act * sizeof(void *); //! current size + /* + * "act" will always be one less than a multiple of 8 and + * at least one larger than before. After first time through, + * each call will increment by 8. + */ + act = (act + 10) & ~0x0007; + av = malloc(act-- * sizeof(void *)); + if (av == NULL) + goto no_memory; + memcpy(av, xml2agOptions.origArgVect, csz); + + } else { + act += 8; + av = realloc(av, (act + 1) * sizeof(void *)); + if (av == NULL) + goto no_memory; + } + + xml2agOptions.origArgCt = act; + xml2agOptions.origArgVect = av; + return; + + no_memory: + fprintf(stderr, "No memory for %d args\n", act+1); + exit(EXIT_FAILURE); +} + +static void +add_arg(char const * arg, int ix) +{ + if (ix >= (int)xml2agOptions.origArgCt) + get_argv_space(); + + xml2agOptions.origArgVect[ix] = VOIDP(arg); +} + +static int +become_child(int * fd, char const * in_file) +{ + if (pipe(fd) != 0) { + fprintf(stderr, fs_err_fmt, xml2agOptions.pzProgName, + errno, strerror( errno ), "pipe(2)"); + exit(EXIT_FAILURE); + } + + fflush(stdout); + fflush(stdin); + + switch (fork()) { + case -1: + fprintf(stderr, fs_err_fmt, xml2agOptions.pzProgName, + errno, strerror( errno ), "fork(2)"); + exit(EXIT_FAILURE); + + case 0: + fclose(stdin); + if (dup2(fd[0], STDIN_FILENO) != STDIN_FILENO) { + fprintf(stderr, fs_err_fmt, xml2agOptions.pzProgName, + errno, strerror( errno ), "dup2(2) w/ STDIN_FILENO"); + exit(EXIT_FAILURE); + } + close(fd[1]); + break; + + default: + errno = 0; + ag_pipe_fp = fdopen(fd[1], "w"); + if (ag_pipe_fp == NULL) { + fprintf(stderr, fs_err_fmt, xml2agOptions.pzProgName, + errno, strerror( errno ), "fdopen(2) w/ pipe[1]"); + exit(EXIT_FAILURE); + } + close(fd[0]); + return 0; + } + + if (! HAVE_OPT( BASE_NAME )) { + if (in_file == NULL) + in_file = "stdin"; + else { + char * pz = strrchr(in_file, '.'); + if (pz != NULL) { + in_file = pz = strdup(in_file); + pz = strrchr(pz, '.'); + *pz = '\0'; + } + } + SET_OPT_BASE_NAME(in_file); + } + + return 1; +} + +void +fork_ag(char const * in_file) +{ + int fd[2]; + + if (! become_child(fd, in_file)) + return; // parent process returns + + get_argv_space(); + + { + static char const zAg[] = "autogen"; + char * pzArg; + int ix = 1; + + { + char * pz = malloc(strlen( xml2agOptions.pzProgPath ) + 7); + char * p = strrchr(xml2agOptions.pzProgPath, '/'); + + if (p == NULL) { + strcpy(pz, zAg); + } else { + size_t len = (size_t)(p - xml2agOptions.pzProgPath) + 1; + memcpy(pz, xml2agOptions.pzProgPath, len); + strcpy(pz + len, zAg); + } + + add_arg(pz, 0); + }[= + + FOR flag =][= + IF (define opt-name (up-c-name "name")) + + (and + (not (~~ opt-name "OVERRIDE_TPL|OUTPUT")) + (not (exist? "documentation")) + ) =][= + + INVOKE handle-option =][= + ENDIF (not override) =][= + ENDFOR =] + + xml2agOptions.origArgVect[ix] = NULL; + execvp(xml2agOptions.origArgVect[0], xml2agOptions.origArgVect); + + /* + * IF the first try fails, it may be because xml2ag and autogen have + * different paths. Try again with just plain "autogen" and let + * the OS search "PATH" for the program. + */ + execvp(zAg, xml2agOptions.origArgVect); + fprintf(stderr, fs_err_fmt, xml2agOptions.pzProgName, + errno, strerror(errno), "execvp(2)"); + exit(EXIT_FAILURE); + } +} + +/* + * Local Variables: + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of [= (out-name) =] */ +[= + +DEFINE handle-option =] + + if (HAVE_OPT([=(. opt-name)=])) {[= + + CASE arg-type =][= + + ==* key =] + static char const * kwlist[] = { +[=(shellf "${CLexe:-columns} -I16 -f'\"%%s\"' -S, --spread=2 <<_EOF_\n%s\n_EOF_" + (join "\n" (stack "keyword")) )=] }; + pzArg = malloc([= (+ 4 (string-length (get "name"))) + =] + strlen( kwlist[ OPT_VALUE_[=(. opt-name)=] ] )); + sprintf(pzArg, "--[=name=]=%s", kwlist[ OPT_VALUE_[= + (. opt-name)=] ]); + add_arg(pzArg, ix++);[= + + ==* num =] + pzArg = malloc((size_t)[= (+ 16 (string-length (get "name"))) =]); + sprintf(pzArg, "--[=name=]=%d", (int)OPT_VALUE_[=(. opt-name)=]); + add_arg(pzArg, ix++);[= + + ==* bool =] + static char z[] = "--[=name=]=false"; + if (OPT_VALUE_[=(. opt-name)=]) + strcpy(z + [= (+ 3 (string-length (get "name"))) =], "true"); + add_arg(z, ix++);[= + + ==* str =][= + IF (exist? "max") =] + int optCt = STACKCT_OPT([=(. opt-name)=]); + char const ** ppOA = STACKLST_OPT([=(. opt-name)=]); + do { + char const * pA = *(ppOA++); + pzArg = malloc([= (+ 4 (string-length (get "name"))) + =] + strlen(pA)); + sprintf(pzArg, "--[=name=]=%s", pA); + add_arg(pzArg, ix++); + } while (--optCt > 0);[= + ELSE !exists-max =] + pzArg = malloc([= (+ 4 (string-length (get "name"))) + =] + strlen( OPT_ARG( [=(. opt-name)=] ))); + sprintf(pzArg, "--[=name=]=%s", OPT_ARG( [=(. opt-name)=] )); + add_arg(pzArg, ix++);[= + ENDIF exists-max =][= + + == "" =] + add_arg("--[=name=]", ix++);[= + + ESAC arg-type =] + }[= + +ENDDEF handle-option + +end of fork.tpl \=] diff --git a/xml2ag/test/Makefile.am b/xml2ag/test/Makefile.am new file mode 100644 index 0000000..88a3f53 --- /dev/null +++ b/xml2ag/test/Makefile.am @@ -0,0 +1,40 @@ +## -*- Mode: Makefile -*- +## +## Makefile.am -- process this file with automake to produce Makefile.in +## +## Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . + +TESTS = convert.test +EXTRA_DIST = $(TESTS) + +TESTS_ENVIRONMENT = \ + X2Aexe=`\cd $(top_builddir)/xml2ag ; pwd`/xml2ag$(EXEEXT) \ + srcdir=$(srcdir) top_srcdir=$(top_srcdir) + +distclean-local: + -rm -rf testdir FAILURES + +check : perm-stamp + +$(TESTS) : perm-stamp + +perm-stamp : + cd $(srcdir) ; chmod +x *.test + +# end of Makefile.am diff --git a/xml2ag/test/Makefile.in b/xml2ag/test/Makefile.in new file mode 100644 index 0000000..139c702 --- /dev/null +++ b/xml2ag/test/Makefile.in @@ -0,0 +1,887 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 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. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = xml2ag/test +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/config/ag_macros.m4 \ + $(top_srcdir)/config/asm-underscore.m4 \ + $(top_srcdir)/config/extensions.m4 \ + $(top_srcdir)/config/guile.m4 \ + $(top_srcdir)/config/host-cpu-c-abi.m4 \ + $(top_srcdir)/config/lib-ld.m4 \ + $(top_srcdir)/config/lib-link.m4 \ + $(top_srcdir)/config/lib-prefix.m4 \ + $(top_srcdir)/config/libopts.m4 \ + $(top_srcdir)/config/libtool.m4 \ + $(top_srcdir)/config/ltoptions.m4 \ + $(top_srcdir)/config/ltsugar.m4 \ + $(top_srcdir)/config/ltversion.m4 \ + $(top_srcdir)/config/lt~obsolete.m4 \ + $(top_srcdir)/config/onceonly.m4 $(top_srcdir)/config/pkg.m4 \ + $(top_srcdir)/config/snprintfv.m4 \ + $(top_srcdir)/config/stdnoreturn.m4 \ + $(top_srcdir)/config/unlocked-io.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +am__tty_colors_dummy = \ + mgn= red= grn= lgn= blu= brg= std=; \ + am__color_tests=no +am__tty_colors = { \ + $(am__tty_colors_dummy); \ + if test "X$(AM_COLOR_TESTS)" = Xno; then \ + am__color_tests=no; \ + elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ + am__color_tests=yes; \ + elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ + am__color_tests=yes; \ + fi; \ + if test $$am__color_tests = yes; then \ + red=''; \ + grn=''; \ + lgn=''; \ + blu=''; \ + mgn=''; \ + brg=''; \ + std=''; \ + fi; \ +} +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__recheck_rx = ^[ ]*:recheck:[ ]* +am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* +am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* +# A command that, given a newline-separated list of test names on the +# standard input, print the name of the tests that are to be re-run +# upon "make recheck". +am__list_recheck_tests = $(AWK) '{ \ + recheck = 1; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + { \ + if ((getline line2 < ($$0 ".log")) < 0) \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ + { \ + recheck = 0; \ + break; \ + } \ + else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ + { \ + break; \ + } \ + }; \ + if (recheck) \ + print $$0; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# A command that, given a newline-separated list of test names on the +# standard input, create the global log from their .trs and .log files. +am__create_global_log = $(AWK) ' \ +function fatal(msg) \ +{ \ + print "fatal: making $@: " msg | "cat >&2"; \ + exit 1; \ +} \ +function rst_section(header) \ +{ \ + print header; \ + len = length(header); \ + for (i = 1; i <= len; i = i + 1) \ + printf "="; \ + printf "\n\n"; \ +} \ +{ \ + copy_in_global_log = 1; \ + global_test_result = "RUN"; \ + while ((rc = (getline line < ($$0 ".trs"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".trs"); \ + if (line ~ /$(am__global_test_result_rx)/) \ + { \ + sub("$(am__global_test_result_rx)", "", line); \ + sub("[ ]*$$", "", line); \ + global_test_result = line; \ + } \ + else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ + copy_in_global_log = 0; \ + }; \ + if (copy_in_global_log) \ + { \ + rst_section(global_test_result ": " $$0); \ + while ((rc = (getline line < ($$0 ".log"))) != 0) \ + { \ + if (rc < 0) \ + fatal("failed to read from " $$0 ".log"); \ + print line; \ + }; \ + printf "\n"; \ + }; \ + close ($$0 ".trs"); \ + close ($$0 ".log"); \ +}' +# Restructured Text title. +am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } +# Solaris 10 'make', and several other traditional 'make' implementations, +# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it +# by disabling -e (using the XSI extension "set +e") if it's set. +am__sh_e_setup = case $$- in *e*) set +e;; esac +# Default flags passed to test drivers. +am__common_driver_flags = \ + --color-tests "$$am__color_tests" \ + --enable-hard-errors "$$am__enable_hard_errors" \ + --expect-failure "$$am__expect_failure" +# To be inserted before the command running the test. Creates the +# directory for the log if needed. Stores in $dir the directory +# containing $f, in $tst the test, in $log the log. Executes the +# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and +# passes TESTS_ENVIRONMENT. Set up options for the wrapper that +# will run the test scripts (or their associated LOG_COMPILER, if +# thy have one). +am__check_pre = \ +$(am__sh_e_setup); \ +$(am__vpath_adj_setup) $(am__vpath_adj) \ +$(am__tty_colors); \ +srcdir=$(srcdir); export srcdir; \ +case "$@" in \ + */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ + *) am__odir=.;; \ +esac; \ +test "x$$am__odir" = x"." || test -d "$$am__odir" \ + || $(MKDIR_P) "$$am__odir" || exit $$?; \ +if test -f "./$$f"; then dir=./; \ +elif test -f "$$f"; then dir=; \ +else dir="$(srcdir)/"; fi; \ +tst=$$dir$$f; log='$@'; \ +if test -n '$(DISABLE_HARD_ERRORS)'; then \ + am__enable_hard_errors=no; \ +else \ + am__enable_hard_errors=yes; \ +fi; \ +case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ + am__expect_failure=yes;; \ + *) \ + am__expect_failure=no;; \ +esac; \ +$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) +# A shell command to get the names of the tests scripts with any registered +# extension removed (i.e., equivalently, the names of the test logs, with +# the '.log' extension removed). The result is saved in the shell variable +# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, +# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", +# since that might cause problem with VPATH rewrites for suffix-less tests. +# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. +am__set_TESTS_bases = \ + bases='$(TEST_LOGS)'; \ + bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ + bases=`echo $$bases` +RECHECK_LOGS = $(TEST_LOGS) +AM_RECURSIVE_TARGETS = check recheck +TEST_SUITE_LOG = test-suite.log +TEST_EXTENSIONS = @EXEEXT@ .test +am__test_logs1 = $(TESTS:=.log) +am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) +TEST_LOGS = $(am__test_logs2:.test.log=.log) +TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/config/test-driver +TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ + $(TEST_LOG_FLAGS) +am__set_b = \ + case '$@' in \ + */*) \ + case '$*' in \ + */*) b='$*';; \ + *) b=`echo '$@' | sed 's/\.log$$//'`; \ + esac;; \ + *) \ + b='$*';; \ + esac +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/config/test-driver +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AGEN5_TESTS = @AGEN5_TESTS@ +AG_LDFLAGS = @AG_LDFLAGS@ +AG_MAJOR_VERSION = @AG_MAJOR_VERSION@ +AG_MINOR_VERSION = @AG_MINOR_VERSION@ +AG_STATIC_AUTOGEN = @AG_STATIC_AUTOGEN@ +AG_TIMEOUT = @AG_TIMEOUT@ +AG_VERSION = @AG_VERSION@ +AG_XML2 = @AG_XML2@ +AGexe = @AGexe@ +AGnam = @AGnam@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AO_AGE = @AO_AGE@ +AO_CURRENT = @AO_CURRENT@ +AO_REVISION = @AO_REVISION@ +AO_TEMPLATE_VERSION = @AO_TEMPLATE_VERSION@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CLexe = @CLexe@ +CLnam = @CLnam@ +CONFIG_SHELL = @CONFIG_SHELL@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEBUG_ENABLED = @DEBUG_ENABLED@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +DYNAMIC_AG = @DYNAMIC_AG@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ENABLE_STATIC = @ENABLE_STATIC@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GDexe = @GDexe@ +GDnam = @GDnam@ +GO_AGE = @GO_AGE@ +GO_CURRENT = @GO_CURRENT@ +GO_REVISION = @GO_REVISION@ +GREP = @GREP@ +GUILE_CFLAGS = @GUILE_CFLAGS@ +GUILE_EFFECTIVE_VERSION = @GUILE_EFFECTIVE_VERSION@ +GUILE_LDFLAGS = @GUILE_LDFLAGS@ +GUILE_LIBS = @GUILE_LIBS@ +GUILE_LTLIBS = @GUILE_LTLIBS@ +HOST_CPU = @HOST_CPU@ +HOST_CPU_C_ABI = @HOST_CPU_C_ABI@ +INCLIST = @INCLIST@ +INCSNPRINTFV = @INCSNPRINTFV@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSNPRINTFV = @LIBSNPRINTFV@ +LIBTOOL = @LIBTOOL@ +LIBXML2_CFLAGS = @LIBXML2_CFLAGS@ +LIBXML2_LIBS = @LIBXML2_LIBS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +M4_SRC = @M4_SRC@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OPTS_TESTDIR = @OPTS_TESTDIR@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSIX_SHELL = @POSIX_SHELL@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STDNORETURN_H = @STDNORETURN_H@ +STRIP = @STRIP@ +TEXI2HTML = @TEXI2HTML@ +VERSION = @VERSION@ +WARN_CFLAGS = @WARN_CFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_aux_dir = @ac_aux_dir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +TESTS = convert.test +EXTRA_DIST = $(TESTS) +TESTS_ENVIRONMENT = \ + X2Aexe=`\cd $(top_builddir)/xml2ag ; pwd`/xml2ag$(EXEEXT) \ + srcdir=$(srcdir) top_srcdir=$(top_srcdir) + +all: all-am + +.SUFFIXES: +.SUFFIXES: .log .test .test$(EXEEXT) .trs +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu xml2ag/test/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu xml2ag/test/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: + + +# Recover from deleted '.trs' file; this should ensure that +# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create +# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells +# to avoid problems with "make -n". +.log.trs: + rm -f $< $@ + $(MAKE) $(AM_MAKEFLAGS) $< + +# Leading 'am--fnord' is there to ensure the list of targets does not +# expand to empty, as could happen e.g. with make check TESTS=''. +am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) +am--force-recheck: + @: + +$(TEST_SUITE_LOG): $(TEST_LOGS) + @$(am__set_TESTS_bases); \ + am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ + redo_bases=`for i in $$bases; do \ + am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ + done`; \ + if test -n "$$redo_bases"; then \ + redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ + redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ + if $(am__make_dryrun); then :; else \ + rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ + fi; \ + fi; \ + if test -n "$$am__remaking_logs"; then \ + echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ + "recursion detected" >&2; \ + elif test -n "$$redo_logs"; then \ + am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ + fi; \ + if $(am__make_dryrun); then :; else \ + st=0; \ + errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ + for i in $$redo_bases; do \ + test -f $$i.trs && test -r $$i.trs \ + || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ + test -f $$i.log && test -r $$i.log \ + || { echo "$$errmsg $$i.log" >&2; st=1; }; \ + done; \ + test $$st -eq 0 || exit 1; \ + fi + @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ + ws='[ ]'; \ + results=`for b in $$bases; do echo $$b.trs; done`; \ + test -n "$$results" || results=/dev/null; \ + all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ + pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ + fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ + skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ + xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ + xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ + error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ + if test `expr $$fail + $$xpass + $$error` -eq 0; then \ + success=true; \ + else \ + success=false; \ + fi; \ + br='==================='; br=$$br$$br$$br$$br; \ + result_count () \ + { \ + if test x"$$1" = x"--maybe-color"; then \ + maybe_colorize=yes; \ + elif test x"$$1" = x"--no-color"; then \ + maybe_colorize=no; \ + else \ + echo "$@: invalid 'result_count' usage" >&2; exit 4; \ + fi; \ + shift; \ + desc=$$1 count=$$2; \ + if test $$maybe_colorize = yes && test $$count -gt 0; then \ + color_start=$$3 color_end=$$std; \ + else \ + color_start= color_end=; \ + fi; \ + echo "$${color_start}# $$desc $$count$${color_end}"; \ + }; \ + create_testsuite_report () \ + { \ + result_count $$1 "TOTAL:" $$all "$$brg"; \ + result_count $$1 "PASS: " $$pass "$$grn"; \ + result_count $$1 "SKIP: " $$skip "$$blu"; \ + result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ + result_count $$1 "FAIL: " $$fail "$$red"; \ + result_count $$1 "XPASS:" $$xpass "$$red"; \ + result_count $$1 "ERROR:" $$error "$$mgn"; \ + }; \ + { \ + echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ + $(am__rst_title); \ + create_testsuite_report --no-color; \ + echo; \ + echo ".. contents:: :depth: 2"; \ + echo; \ + for b in $$bases; do echo $$b; done \ + | $(am__create_global_log); \ + } >$(TEST_SUITE_LOG).tmp || exit 1; \ + mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ + if $$success; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ + fi; \ + echo "$${col}$$br$${std}"; \ + echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ + echo "$${col}$$br$${std}"; \ + create_testsuite_report --maybe-color; \ + echo "$$col$$br$$std"; \ + if $$success; then :; else \ + echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ + if test -n "$(PACKAGE_BUGREPORT)"; then \ + echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ + fi; \ + echo "$$col$$br$$std"; \ + fi; \ + $$success || exit 1 + +check-TESTS: + @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list + @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + trs_list=`for i in $$bases; do echo $$i.trs; done`; \ + log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ + exit $$?; +recheck: all + @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + @set +e; $(am__set_TESTS_bases); \ + bases=`for i in $$bases; do echo $$i; done \ + | $(am__list_recheck_tests)` || exit 1; \ + log_list=`for i in $$bases; do echo $$i.log; done`; \ + log_list=`echo $$log_list`; \ + $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ + am__force_recheck=am--force-recheck \ + TEST_LOGS="$$log_list"; \ + exit $$? +.test.log: + @p='$<'; \ + $(am__set_b); \ + $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) +@am__EXEEXT_TRUE@.test$(EXEEXT).log: +@am__EXEEXT_TRUE@ @p='$<'; \ +@am__EXEEXT_TRUE@ $(am__set_b); \ +@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ +@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ +@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ +@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) + -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) + -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-local + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: check-am install-am install-strip + +.PHONY: all all-am check check-TESTS check-am clean clean-generic \ + clean-libtool cscopelist-am ctags-am distclean \ + distclean-generic distclean-libtool distclean-local distdir \ + dvi dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am recheck tags-am \ + uninstall uninstall-am + +.PRECIOUS: Makefile + + +distclean-local: + -rm -rf testdir FAILURES + +check : perm-stamp + +$(TESTS) : perm-stamp + +perm-stamp : + cd $(srcdir) ; chmod +x *.test + +# end of Makefile.am + +# 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/xml2ag/test/convert.test b/xml2ag/test/convert.test new file mode 100755 index 0000000..36a6734 --- /dev/null +++ b/xml2ag/test/convert.test @@ -0,0 +1,101 @@ +#! /bin/sh +# -*- Mode: Shell-script -*- +# ---------------------------------------------------------------------- +# convert.test --- test XML -> AutoGen conversion +# +## Author: Bruce Korb +## +## This file is part of AutoGen. +## AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved +## +## AutoGen is free software: you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## AutoGen is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +## See the GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License along +## with this program. If not, see . + +case "X${VERBOSE}" in +X | X[nNfF]* ) VERBOSE=false ;; +* ) set -x ; VERBOSE=true ;; +esac + +# A standard failure function +failure() +{ + cd ${testsubdir} + test -d ../FAILURES || mkdir ../FAILURES + l=`echo *` + ( \cd ../FAILURES ; rm -f $l ) + mv -f * ../FAILURES + echo "$*" + exit 1 +} + +srcdir=`pwd` +testname=convert +[ -d testdir ] || mkdir testdir +cd testdir +testsubdir=`pwd` + +${X2Aexe} -O ${testname}.out <<'_EndOfXML_' + + + + + <stumble around the 'XML'.> + + mumble-1 + + mumble-2 + + grumble & "grumble" & grumble. + + mumble, mumble + + + +_EndOfXML_ + +cat > ${testname}.samp <<'_EndOfSample_' +/* Parsed from stdin */ +AutoGen Definitions sample.tpl; +XML-version = '1.0'; +XML-standalone = 'true'; +template = 'sample.tpl'; +mumble = { + content = ''; + attr = 'foo'; + grumble = { + content = ''; + text = ''; + }; + text = 'mumble-1'; + /* This is just a + /* multi-line comment * / */ + text = 'mumble-2'; + grumble = { + content = ''; + text = 'grumble & "grumble" & grumble.'; + }; + text = 'mumble, mumble'; +}; +stumble = { + content = ''; + upon = 'rough going'; +}; +_EndOfSample_ + +cmp -s ${testname}.samp ${testname}.out || \ + failure "`diff -u ${testname}.samp ${testname}.out`" + +${VERBOSE} || { cd ${srcdir} ; rm -rf ${testsubdir} ; } + +# end of convert.test diff --git a/xml2ag/xml2ag.c b/xml2ag/xml2ag.c new file mode 100644 index 0000000..867a4b1 --- /dev/null +++ b/xml2ag/xml2ag.c @@ -0,0 +1,462 @@ + +/** + * @file xml2ag.c + * + * This is the main routine for xml2ag. + * + * @group xml2ag + * @{ + */ +/* + * xml2ag Copyright (C) 2002-2018 by Bruce Korb - all rights reserved + * This file is part of AutoGen. + * AutoGen Copyright (C) 1992-2017 by Bruce Korb - all rights reserved + * + * AutoGen is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AutoGen is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +static char const zConflict[] = + "the file name operand conflicts with the definitions option.\n"; + +static char const zTextFmt[] = + "text = '%s';\n"; + +static char const * typeName[] = { + "0 - inval", + "ELEMENT_NODE", + "ATTRIBUTE_NODE", + "TEXT_NODE", + "CDATA_SECTION_NODE", + "ENTITY_REF_NODE", + "ENTITY_NODE", + "PI_NODE", + "COMMENT_NODE", + "DOCUMENT_NODE", + "DOCUMENT_TYPE_NODE", + "DOCUMENT_FRAG_NODE", + "NOTATION_NODE", + "HTML_DOCUMENT_NODE", + "DTD_NODE", + "ELEMENT_DECL", + "ATTRIBUTE_DECL", + "ENTITY_DECL", + "NAMESPACE_DECL", + "XINCLUDE_START", + "XINCLUDE_END", + "DOCB_DOCUMENT_NODE" }; + +int level = 0; +FILE * ag_pipe_fp; + +#define CHUNK_SZ 4096 + +#define TRIM(s,psz) trim( (char const *)(s), (size_t *)(psz) ) + +extern void fork_ag(char const * pzInput); +static char * loadFile(FILE * fp, size_t * pzSize); +static xmlNodePtr printHeader(xmlDocPtr pDoc); +static void printAttrs(xmlAttrPtr pAttr); +static void printChildren(xmlNodePtr pNode); + +int +main(int argc, char ** argv) +{ + xmlDocPtr pDoc; + char const * pzFile = NULL; + + { + int ct = optionProcess( &xml2agOptions, argc, argv ); + argc -= ct; + argv += ct; + + switch (argc) { + case 1: + if (strcmp( *argv, "-" ) != 0) { + if (HAVE_OPT( DEFINITIONS )) { + fprintf(stderr, zConflict); + USAGE( EXIT_FAILURE ); + } + pzFile = *argv; + break; + } + /* FALLTHROUGH */ + case 0: + if ( HAVE_OPT( DEFINITIONS ) + && (strcmp( OPT_ARG( DEFINITIONS ), "-" ) != 0) ) + + pzFile = OPT_ARG( DEFINITIONS ); + break; + + default: + fprintf(stderr, "only one argument allowed\n"); + return EXIT_FAILURE; + } + } + + if (! HAVE_OPT( OUTPUT )) + fork_ag(pzFile); + else + ag_pipe_fp = stdout; + + if (pzFile != NULL) { + fprintf(ag_pipe_fp, "/* Parsing file %s */\n", pzFile); + pDoc = xmlParseFile( pzFile ); + } + else { + size_t sz; + char * pz = loadFile( stdin, &sz ); + pDoc = xmlParseMemory( pz, (int)sz ); + fprintf(ag_pipe_fp, "/* Parsed from stdin */\n"); + } + + { + static char const z_not_doc[] = + "/* type %d doc is not DOCUMENT or HTML_DOCUMENT */\n"; + + xmlNodePtr pRoot = printHeader( pDoc ); + printAttrs( pRoot->properties ); + switch (pDoc->type) { + case XML_DOCUMENT_NODE: + case XML_HTML_DOCUMENT_NODE: + printChildren( pRoot->children ); + break; + default: + fprintf(ag_pipe_fp, z_not_doc, pDoc->type); + } + } + + xmlCleanupParser(); + return 0; +} + + +static char * +loadFile(FILE * fp, size_t * pzSize) +{ + size_t asz = CHUNK_SZ; + size_t usz = 0; + char * mem = malloc( asz ); + + for (;;) { + + if ((usz + CHUNK_SZ) > asz) { + asz += CHUNK_SZ; + mem = realloc( mem, asz ); + } + + if (mem == NULL) { + fprintf(stderr, "Cannot allocate %d byte bufer\n", (int)asz); + exit( EXIT_FAILURE ); + } + + { + size_t rdct = fread(mem + usz, (size_t)1, (size_t)CHUNK_SZ, fp); + usz += rdct; + if (rdct < CHUNK_SZ) + break; + } + } + + *pzSize = usz; + return mem; +} + + +static void +emitIndentation( void ) +{ + int indent = level * 2; + while (--indent >= 0) fputc( ' ', ag_pipe_fp ); +} + + +static char * +trim(char const * pzSrc, size_t * pSz) +{ + static char zNil[1] = ""; + static char * pzData = NULL; + static size_t dataLen = 0; + size_t strSize; + + if (pzSrc == NULL) { + if (pSz != NULL) *pSz = 0; + return zNil; + } + + /* + * Trim leading and trailing white space. + */ + while (isspace( *pzSrc )) pzSrc++; + + { + char const * pzEnd = pzSrc + strlen( pzSrc ); + while ((pzEnd > pzSrc) && isspace( pzEnd[-1] )) pzEnd--; + + if (pzEnd <= pzSrc) { + if (pSz != NULL) *pSz = 0; + return zNil; + } + strSize = (size_t)(pzEnd - pzSrc); + } + + /* + * Count the extra backslashes required and ensure our buffer is + * big enough to hold the newly formed string. + */ + { + char const * pz = pzSrc; + for (;;) { + pz += strcspn( pz, "'\\" ); + if (*(pz++) == NUL) + break; + strSize++; + } + } + + if (dataLen <= strSize) { + size_t sz = (strSize + 0x1000) & ~0x0FFFUL; + if (pzData == NULL) + pzData = malloc( sz ); + else pzData = realloc( pzData, sz ); + if (pzData == NULL) { + fprintf(stderr, "ENOMEM allocating 0x%X bytes", (unsigned)sz); + exit( EXIT_FAILURE ); + } + dataLen = sz; + } + + /* + * Copy the data, adding backslashes in front of + * single quotes and backslashes. + */ + { + char * pzDest = pzData; + for (;;) { + switch (*(pzDest++) = *(pzSrc++)) { + case '\'': pzDest[-1] = '\\'; *(pzDest++) = '\''; break; + case '\\': *(pzDest++) = '\\'; break; + case NUL: goto set_size; + } + if (pzDest == pzData + strSize) + break; + } + + *pzDest = '\0'; + } + + set_size: + if (pSz != NULL) *pSz = strSize; + return pzData; +} + +static xmlNodePtr +printHeader(xmlDocPtr pDoc) +{ + static char const def_hdr[] = "AutoGen Definitions %s%s;\n"; + static char const xml_fmt[] = "XML-%s = '%s';\n"; + + char const * suffx = ".tpl"; + + xmlNodePtr root_node = xmlDocGetRootElement( pDoc ); + xmlChar * tmp_tpl = NULL; + xmlChar * tpl_nm; + + if (root_node == NULL) { + fprintf(stderr, "Root node not found\n"); + exit( EXIT_FAILURE ); + } + + if (HAVE_OPT( OVERRIDE_TPL )) { + if (strchr( OPT_ARG( OVERRIDE_TPL ), '.' ) != NULL) + suffx = ""; + tpl_nm = (xmlChar *)VOIDP(OPT_ARG( OVERRIDE_TPL )); + } + else { + tmp_tpl = xmlGetProp(root_node, (xmlChar *)VOIDP("template")); + if (tmp_tpl == NULL) { + fprintf(stderr, "No template was specified.\n"); + exit( EXIT_FAILURE ); + } + + tpl_nm = tmp_tpl; + if (strchr( (char *)tpl_nm, '.' ) != NULL) + suffx = ""; + } + + fprintf(ag_pipe_fp, def_hdr, tpl_nm, suffx); + if (tmp_tpl != NULL) + free(tmp_tpl); + + if (pDoc->name != NULL) + fprintf(ag_pipe_fp, xml_fmt, "name", TRIM(pDoc->name, NULL)); + + if (pDoc->version != NULL) + fprintf(ag_pipe_fp, xml_fmt, "version", TRIM(pDoc->version, NULL)); + + if (pDoc->encoding != NULL) + fprintf(ag_pipe_fp, xml_fmt, "encoding", TRIM(pDoc->encoding, NULL)); + + if (pDoc->URL != NULL) + fprintf(ag_pipe_fp, xml_fmt, "URL", TRIM(pDoc->URL, NULL)); + + if (pDoc->standalone) + fprintf(ag_pipe_fp, xml_fmt, "standalone", "true"); + + return root_node; +} + +static void +printAttrs(xmlAttrPtr pAttr) +{ + while (pAttr != NULL) { + char * pzCont = (char *)pAttr->children->content; + + emitIndentation(); + fputs( (char *)VOIDP(pAttr->name), ag_pipe_fp ); + fputs( " = ", ag_pipe_fp ); + if (pAttr->children->children == NULL) + fprintf(ag_pipe_fp, "'%s';\n", TRIM(pzCont, NULL)); + else { + fputs( "{\n", ag_pipe_fp ); + level++; + if (pzCont != NULL) { + emitIndentation(); + fprintf(ag_pipe_fp, zTextFmt, TRIM(pzCont, NULL)); + } + printChildren( pAttr->children->children ); + level--; + emitIndentation(); + fputs( "};\n", ag_pipe_fp ); + } + + pAttr = pAttr->next; + } +} + + +static void +printNode(xmlNodePtr pNode) +{ + switch (pNode->type) { + case XML_ELEMENT_NODE: + { + size_t sz; + char * pzTxt; + emitIndentation(); + fputs( (char *)VOIDP(pNode->name), ag_pipe_fp ); + pzTxt = TRIM(pNode->content, &sz); + + if ( (pNode->properties == NULL) + && (pNode->children == NULL)) { + + if (sz == 0) + fputs( ";\n", ag_pipe_fp ); + else fprintf(ag_pipe_fp, " = '%s';\n", pzTxt); + break; + } + + fputs( " = {\n", ag_pipe_fp ); + level++; + emitIndentation(); + fprintf(ag_pipe_fp, "content = '%s';\n", pzTxt); + printAttrs( pNode->properties ); + printChildren( pNode->children ); + level--; + emitIndentation(); + fputs( "};\n", ag_pipe_fp ); + break; + } + + case XML_ATTRIBUTE_NODE: + fputs( "Misplaced attribute\n", ag_pipe_fp ); + exit( EXIT_FAILURE ); + + case XML_TEXT_NODE: + { + size_t sz; + char * pzTxt = TRIM(pNode->content, &sz); + if (sz == 0) + break; + emitIndentation(); + fprintf(ag_pipe_fp, zTextFmt, pzTxt); + break; + } + + case XML_COMMENT_NODE: + { + size_t sz; + char * pzTxt = TRIM(pNode->content, &sz); + if (sz == 0) + break; + + emitIndentation(); + fputs( "/* ", ag_pipe_fp ); + for (;;) { + char * pz = strstr( pzTxt, "*/" ); + if (pz == NULL) + break; + fwrite(pzTxt, (size_t)((pz - pzTxt) + 1), (size_t)1, ag_pipe_fp); + pzTxt = pz+1; + fputc( ' ', ag_pipe_fp ); + } + fprintf(ag_pipe_fp, "%s */\n", pzTxt); + break; + } + + case XML_CDATA_SECTION_NODE: + case XML_ENTITY_REF_NODE: + case XML_ENTITY_NODE: + case XML_PI_NODE: + + case XML_DOCUMENT_NODE: + case XML_HTML_DOCUMENT_NODE: + case XML_DOCUMENT_TYPE_NODE: + case XML_DOCUMENT_FRAG_NODE: + case XML_NOTATION_NODE: + case XML_DTD_NODE: + case XML_ELEMENT_DECL: + case XML_ATTRIBUTE_DECL: + case XML_ENTITY_DECL: + case XML_NAMESPACE_DECL: + case XML_XINCLUDE_START: + case XML_XINCLUDE_END: + emitIndentation(); + fprintf(ag_pipe_fp, "/* Unsupported XML node type: %s */\n", + typeName[ pNode->type ]); + break; + + default: + emitIndentation(); + fprintf(ag_pipe_fp, "/* Unknown XML node type %d */\n", pNode->type); + break; + } +} + + +static void +printChildren(xmlNodePtr pNode) +{ + while (pNode != NULL) { + printNode( pNode ); + pNode = pNode->next; + } +} + +/* + * Local Variables: + * mode: C + * c-file-style: "stroustrup" + * indent-tabs-mode: nil + * End: + * end of xml2ag/xml2ag.c */ diff --git a/xml2ag/xmlopts.c b/xml2ag/xmlopts.c new file mode 100644 index 0000000..e65317b --- /dev/null +++ b/xml2ag/xmlopts.c @@ -0,0 +1,1118 @@ +/* -*- buffer-read-only: t -*- vi: set ro: + * + * DO NOT EDIT THIS FILE (xmlopts.c) + * + * It has been AutoGen-ed + * From the definitions ./xmlopts.def + * and the template file options + * + * Generated from AutoOpts 42:1:17 templates. + * + * AutoOpts is a copyrighted work. This source file is not encumbered + * by AutoOpts licensing, but is provided under the licensing terms chosen + * by the xml2ag author or copyright holder. AutoOpts is + * licensed under the terms of the LGPL. The redistributable library + * (``libopts'') is licensed under the terms of either the LGPL or, at the + * users discretion, the BSD license. See the AutoOpts and/or libopts sources + * for details. + * + * The xml2ag program is copyrighted and licensed + * under the following terms: + * + * Copyright (C) 1992-2018 Bruce Korb, all rights reserved. + * This is free software. It is licensed for use, modification and + * redistribution under the terms of the GNU General Public License, + * version 3 or later + * + * xml2ag is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * xml2ag is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ +/** \file xmlopts.c + * \addtogroup xml2ag + * @{ + */ + +#ifndef __doxygen__ +#define OPTION_CODE_COMPILE 1 +#include "xmlopts.h" +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif +extern FILE * option_usage_fp; +#define zCopyright (xml2ag_opt_strs+0) +#define zLicenseDescrip (xml2ag_opt_strs+271) + +/* + * global included definitions + */ + + +#ifndef NULL +# define NULL 0 +#endif + +/** + * static const strings for xml2ag options + */ +static char const xml2ag_opt_strs[2872] = +/* 0 */ "xml2ag (GNU AutoGen) 5.18.16\n" + "Copyright (C) 1992-2018 Bruce Korb, all rights reserved.\n" + "This is free software. It is licensed for use, modification and\n" + "redistribution under the terms of the GNU General Public License,\n" + "version 3 or later \n\0" +/* 271 */ "xml2ag is free software: you can redistribute it and/or modify it under the\n" + "terms of the GNU General Public License as published by the Free Software\n" + "Foundation, either version 3 of the License, or (at your option) any later\n" + "version.\n\n" + "xml2ag is distributed in the hope that it will be useful, but WITHOUT ANY\n" + "WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\n" + "FOR A PARTICULAR PURPOSE. See the GNU General Public License for more\n" + "details.\n\n" + "You should have received a copy of the GNU General Public License along\n" + "with this program. If not, see .\n\0" +/* 872 */ "All other options are derived from autogen:\0" +/* 916 */ "Output file in lieu of AutoGen processing\0" +/* 958 */ "OUTPUT\0" +/* 965 */ "output\0" +/* 972 */ "All other options:\0" +/* 991 */ "Search for templates in DIR\0" +/* 1019 */ "TEMPL_DIRS\0" +/* 1030 */ "templ-dirs\0" +/* 1041 */ "Use TPL-FILE for the template\0" +/* 1071 */ "OVERRIDE_TPL\0" +/* 1084 */ "override-tpl\0" +/* 1097 */ "Read definitions from FILE\0" +/* 1124 */ "DEFINITIONS\0" +/* 1136 */ "definitions\0" +/* 1148 */ "name or path name of shell to use\0" +/* 1182 */ "SHELL\0" +/* 1188 */ "shell\0" +/* 1194 */ "Do not use in-mem streams\0" +/* 1220 */ "NO_FMEMOPEN\0" +/* 1232 */ "no-fmemopen\0" +/* 1244 */ "characters considered equivalent\0" +/* 1277 */ "EQUATE\0" +/* 1284 */ "equate\0" +/* 1291 */ "Specify NAME as the base name for output\0" +/* 1332 */ "BASE_NAME\0" +/* 1342 */ "base-name\0" +/* 1352 */ "set mod times to latest source\0" +/* 1383 */ "SOURCE_TIME\0" +/* 1395 */ "source-time\0" +/* 1407 */ "Allow output files to be writable\0" +/* 1441 */ "WRITABLE\0" +/* 1450 */ "not-writable\0" +/* 1463 */ "not\0" +/* 1467 */ "Limit on increment loops\0" +/* 1492 */ "LOOP_LIMIT\0" +/* 1503 */ "loop-limit\0" +/* 1514 */ "Limit server shell operations to SECONDS\0" +/* 1555 */ "TIMEOUT\0" +/* 1563 */ "timeout\0" +/* 1571 */ "tracing level of detail\0" +/* 1595 */ "TRACE\0" +/* 1601 */ "trace\0" +/* 1607 */ "tracing output file or filter\0" +/* 1637 */ "TRACE_OUT\0" +/* 1647 */ "trace-out\0" +/* 1657 */ "Show the definition tree\0" +/* 1682 */ "SHOW_DEFS\0" +/* 1692 */ "show-defs\0" +/* 1702 */ "Show the definitions used\0" +/* 1728 */ "USED_DEFINES\0" +/* 1741 */ "used-defines\0" +/* 1754 */ "Leave a core dump on a failure exit\0" +/* 1790 */ "CORE\0" +/* 1795 */ "core\0" +/* 1800 */ "Skip the file with this SUFFIX\0" +/* 1831 */ "SKIP_SUFFIX\0" +/* 1843 */ "skip-suffix\0" +/* 1855 */ "specify this output suffix\0" +/* 1882 */ "SELECT_SUFFIX\0" +/* 1896 */ "select-suffix\0" +/* 1910 */ "name to add to definition list\0" +/* 1941 */ "DEFINE\0" +/* 1948 */ "define\0" +/* 1955 */ "definition list removal pattern\0" +/* 1987 */ "UNDEFINE\0" +/* 1996 */ "undefine\0" +/* 2005 */ "emit make dependency file\0" +/* 2031 */ "MAKE_DEP\0" +/* 2040 */ "make-dep\0" +/* 2049 */ "display extended usage information and exit\0" +/* 2093 */ "help\0" +/* 2098 */ "extended usage information passed thru pager\0" +/* 2143 */ "more-help\0" +/* 2153 */ "output version information and exit\0" +/* 2189 */ "version\0" +/* 2197 */ "XML2AG\0" +/* 2204 */ "xml2ag (GNU AutoGen) - XML to AutoGen Definiton Converter - Ver. 5.18.16\n" + "Usage: %s [ - [] | --[{=| }] ]... [ ]\n\0" +/* 2350 */ "autogen-users@lists.sourceforge.net\0" +/* 2386 */ "This program will convert any arbitrary XML file into equivalent AutoGen\n" + "definitions, and invoke AutoGen.\n\0" +/* 2493 */ "The template will be derived from either: * the ``--override-tpl'' command\n" + "line option * a top level XML attribute named, \"template\"\n\n" + "The ``base-name'' for the output will similarly be either: * the\n" + "``--base-name'' command line option * the base name of the .xml file\n\0" +/* 2762 */ "xml2ag (GNU AutoGen) 5.18.16\0" +/* 2791 */ "nothing\0" +/* 2799 */ "debug-message\0" +/* 2813 */ "server-shell\0" +/* 2826 */ "templates\0" +/* 2836 */ "block-macros\0" +/* 2849 */ "expressions\0" +/* 2861 */ "everything"; + +/** + * the-xml2ag-option option description: + */ +/** the-xml2ag-option option separation text */ +#define THE_XML2AG_OPTION_DESC (xml2ag_opt_strs+872) +#define THE_XML2AG_OPTION_FLAGS (OPTST_DOCUMENT | OPTST_NO_INIT) + +/** + * output option description: + */ +/** Descriptive text for the output option */ +#define OUTPUT_DESC (xml2ag_opt_strs+916) +/** Upper-cased name for the output option */ +#define OUTPUT_NAME (xml2ag_opt_strs+958) +/** Name string for the output option */ +#define OUTPUT_name (xml2ag_opt_strs+965) +/** Compiled in flag settings for the output option */ +#define OUTPUT_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/** + * autogen-options option description: + */ +/** autogen-options option separation text */ +#define AUTOGEN_OPTIONS_DESC (xml2ag_opt_strs+972) +#define AUTOGEN_OPTIONS_FLAGS (OPTST_DOCUMENT | OPTST_NO_INIT) + +/** + * templ-dirs option description: + */ +/* TRANSLATORS: the option argument is a file name */ +/** Descriptive text for the templ-dirs option */ +#define TEMPL_DIRS_DESC (xml2ag_opt_strs+991) +/** Upper-cased name for the templ-dirs option */ +#define TEMPL_DIRS_NAME (xml2ag_opt_strs+1019) +/** Name string for the templ-dirs option */ +#define TEMPL_DIRS_name (xml2ag_opt_strs+1030) +/** Compiled in flag settings for the templ-dirs option */ +#define TEMPL_DIRS_FLAGS (OPTST_DISABLED | OPTST_STACKED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/** + * override-tpl option description: + */ +/** Descriptive text for the override-tpl option */ +#define OVERRIDE_TPL_DESC (xml2ag_opt_strs+1041) +/** Upper-cased name for the override-tpl option */ +#define OVERRIDE_TPL_NAME (xml2ag_opt_strs+1071) +/** Name string for the override-tpl option */ +#define OVERRIDE_TPL_name (xml2ag_opt_strs+1084) +/** Compiled in flag settings for the override-tpl option */ +#define OVERRIDE_TPL_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/** + * definitions option description: + */ +/** Descriptive text for the definitions option */ +#define DEFINITIONS_DESC (xml2ag_opt_strs+1097) +/** Upper-cased name for the definitions option */ +#define DEFINITIONS_NAME (xml2ag_opt_strs+1124) +/** Name string for the definitions option */ +#define DEFINITIONS_name (xml2ag_opt_strs+1136) +/** Compiled in flag settings for the definitions option */ +#define DEFINITIONS_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/** + * shell option description: + */ +/** Descriptive text for the shell option */ +#define SHELL_DESC (xml2ag_opt_strs+1148) +/** Upper-cased name for the shell option */ +#define SHELL_NAME (xml2ag_opt_strs+1182) +/** Name string for the shell option */ +#define SHELL_name (xml2ag_opt_strs+1188) +/** Compiled in flag settings for the shell option */ +#define SHELL_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/** + * no-fmemopen option description: + */ +/** Descriptive text for the no-fmemopen option */ +#define NO_FMEMOPEN_DESC (xml2ag_opt_strs+1194) +/** Upper-cased name for the no-fmemopen option */ +#define NO_FMEMOPEN_NAME (xml2ag_opt_strs+1220) +/** Name string for the no-fmemopen option */ +#define NO_FMEMOPEN_name (xml2ag_opt_strs+1232) +/** Compiled in flag settings for the no-fmemopen option */ +#define NO_FMEMOPEN_FLAGS (OPTST_DISABLED) + +/** + * equate option description: + */ +/** Descriptive text for the equate option */ +#define EQUATE_DESC (xml2ag_opt_strs+1244) +/** Upper-cased name for the equate option */ +#define EQUATE_NAME (xml2ag_opt_strs+1277) +/** Name string for the equate option */ +#define EQUATE_name (xml2ag_opt_strs+1284) +/** Compiled in flag settings for the equate option */ +#define EQUATE_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/** + * base-name option description: + */ +/** Descriptive text for the base-name option */ +#define BASE_NAME_DESC (xml2ag_opt_strs+1291) +/** Upper-cased name for the base-name option */ +#define BASE_NAME_NAME (xml2ag_opt_strs+1332) +/** Name string for the base-name option */ +#define BASE_NAME_name (xml2ag_opt_strs+1342) +/** Compiled in flag settings for the base-name option */ +#define BASE_NAME_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/** + * source-time option description: + */ +/** Descriptive text for the source-time option */ +#define SOURCE_TIME_DESC (xml2ag_opt_strs+1352) +/** Upper-cased name for the source-time option */ +#define SOURCE_TIME_NAME (xml2ag_opt_strs+1383) +/** Name string for the source-time option */ +#define SOURCE_TIME_name (xml2ag_opt_strs+1395) +/** Compiled in flag settings for the source-time option */ +#define SOURCE_TIME_FLAGS (OPTST_DISABLED) + +/** + * writable option description: + */ +/** Descriptive text for the writable option */ +#define WRITABLE_DESC (xml2ag_opt_strs+1407) +/** Upper-cased name for the writable option */ +#define WRITABLE_NAME (xml2ag_opt_strs+1441) +/** disablement name for the writable option */ +#define NOT_WRITABLE_name (xml2ag_opt_strs+1450) +/** disablement prefix for the writable option */ +#define NOT_WRITABLE_PFX (xml2ag_opt_strs+1463) +/** Name string for the writable option */ +#define WRITABLE_name (NOT_WRITABLE_name + 4) +/** Compiled in flag settings for the writable option */ +#define WRITABLE_FLAGS (OPTST_DISABLED) + +/** + * loop-limit option description: + */ +/** Descriptive text for the loop-limit option */ +#define LOOP_LIMIT_DESC (xml2ag_opt_strs+1467) +/** Upper-cased name for the loop-limit option */ +#define LOOP_LIMIT_NAME (xml2ag_opt_strs+1492) +/** Name string for the loop-limit option */ +#define LOOP_LIMIT_name (xml2ag_opt_strs+1503) +/** The compiled in default value for the loop-limit option argument */ +#define LOOP_LIMIT_DFT_ARG ((char const*)256) +/** Compiled in flag settings for the loop-limit option */ +#define LOOP_LIMIT_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_NUMERIC) \ + | OPTST_SCALED_NUM) + +/** + * timeout option description: + */ +/** Descriptive text for the timeout option */ +#define TIMEOUT_DESC (xml2ag_opt_strs+1514) +/** Upper-cased name for the timeout option */ +#define TIMEOUT_NAME (xml2ag_opt_strs+1555) +/** Name string for the timeout option */ +#define TIMEOUT_name (xml2ag_opt_strs+1563) +/** Compiled in flag settings for the timeout option */ +#define TIMEOUT_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_NUMERIC)) + +/** + * trace option description: + */ +/** Descriptive text for the trace option */ +#define TRACE_DESC (xml2ag_opt_strs+1571) +/** Upper-cased name for the trace option */ +#define TRACE_NAME (xml2ag_opt_strs+1595) +/** Name string for the trace option */ +#define TRACE_name (xml2ag_opt_strs+1601) +/** The compiled in default value for the trace option argument */ +#define TRACE_DFT_ARG ((char const*)TRACE_NOTHING) +/** Compiled in flag settings for the trace option */ +#define TRACE_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_ENUMERATION)) + +/** + * trace-out option description: + */ +/** Descriptive text for the trace-out option */ +#define TRACE_OUT_DESC (xml2ag_opt_strs+1607) +/** Upper-cased name for the trace-out option */ +#define TRACE_OUT_NAME (xml2ag_opt_strs+1637) +/** Name string for the trace-out option */ +#define TRACE_OUT_name (xml2ag_opt_strs+1647) +/** Compiled in flag settings for the trace-out option */ +#define TRACE_OUT_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/** + * show-defs option description: + */ +/** Descriptive text for the show-defs option */ +#define SHOW_DEFS_DESC (xml2ag_opt_strs+1657) +/** Upper-cased name for the show-defs option */ +#define SHOW_DEFS_NAME (xml2ag_opt_strs+1682) +/** Name string for the show-defs option */ +#define SHOW_DEFS_name (xml2ag_opt_strs+1692) +/** Compiled in flag settings for the show-defs option */ +#define SHOW_DEFS_FLAGS (OPTST_DISABLED) + +/** + * used-defines option description: + */ +/** Descriptive text for the used-defines option */ +#define USED_DEFINES_DESC (xml2ag_opt_strs+1702) +/** Upper-cased name for the used-defines option */ +#define USED_DEFINES_NAME (xml2ag_opt_strs+1728) +/** Name string for the used-defines option */ +#define USED_DEFINES_name (xml2ag_opt_strs+1741) +/** Compiled in flag settings for the used-defines option */ +#define USED_DEFINES_FLAGS (OPTST_DISABLED) + +/** + * core option description: + */ +#ifdef HAVE_SYS_RESOURCE_H +/** Descriptive text for the core option */ +#define CORE_DESC (xml2ag_opt_strs+1754) +/** Upper-cased name for the core option */ +#define CORE_NAME (xml2ag_opt_strs+1790) +/** Name string for the core option */ +#define CORE_name (xml2ag_opt_strs+1795) +/** Compiled in flag settings for the core option */ +#define CORE_FLAGS (OPTST_DISABLED) + +#else /* disable core */ +#define CORE_FLAGS (OPTST_OMITTED | OPTST_NO_INIT) +#define CORE_NAME NULL +#define CORE_DESC NULL +#define CORE_name NULL +#endif /* HAVE_SYS_RESOURCE_H */ + +/** + * skip-suffix option description with + * "Must also have options" and "Incompatible options": + */ +/** Descriptive text for the skip-suffix option */ +#define SKIP_SUFFIX_DESC (xml2ag_opt_strs+1800) +/** Upper-cased name for the skip-suffix option */ +#define SKIP_SUFFIX_NAME (xml2ag_opt_strs+1831) +/** Name string for the skip-suffix option */ +#define SKIP_SUFFIX_name (xml2ag_opt_strs+1843) +/** Other options that appear in conjunction with the skip-suffix option */ +static int const aSkip_SuffixCantList[] = { + INDEX_OPT_SELECT_SUFFIX, NO_EQUIVALENT }; +/** Compiled in flag settings for the skip-suffix option */ +#define SKIP_SUFFIX_FLAGS (OPTST_DISABLED | OPTST_STACKED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/** + * select-suffix option description: + */ +/** Descriptive text for the select-suffix option */ +#define SELECT_SUFFIX_DESC (xml2ag_opt_strs+1855) +/** Upper-cased name for the select-suffix option */ +#define SELECT_SUFFIX_NAME (xml2ag_opt_strs+1882) +/** Name string for the select-suffix option */ +#define SELECT_SUFFIX_name (xml2ag_opt_strs+1896) +/** Compiled in flag settings for the select-suffix option */ +#define SELECT_SUFFIX_FLAGS (OPTST_DISABLED | OPTST_STACKED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/** + * define option description: + */ +/** Descriptive text for the define option */ +#define DEFINE_DESC (xml2ag_opt_strs+1910) +/** Upper-cased name for the define option */ +#define DEFINE_NAME (xml2ag_opt_strs+1941) +/** Name string for the define option */ +#define DEFINE_name (xml2ag_opt_strs+1948) +/** Compiled in flag settings for the define option */ +#define DEFINE_FLAGS (OPTST_DISABLED | OPTST_STACKED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/** + * undefine option description: + */ +/** Descriptive text for the undefine option */ +#define UNDEFINE_DESC (xml2ag_opt_strs+1955) +/** Upper-cased name for the undefine option */ +#define UNDEFINE_NAME (xml2ag_opt_strs+1987) +/** Name string for the undefine option */ +#define UNDEFINE_name (xml2ag_opt_strs+1996) +/** Compiled in flag settings for the undefine option */ +#define UNDEFINE_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/** + * make-dep option description: + */ +/** Descriptive text for the make-dep option */ +#define MAKE_DEP_DESC (xml2ag_opt_strs+2005) +/** Upper-cased name for the make-dep option */ +#define MAKE_DEP_NAME (xml2ag_opt_strs+2031) +/** Name string for the make-dep option */ +#define MAKE_DEP_name (xml2ag_opt_strs+2040) +/** Compiled in flag settings for the make-dep option */ +#define MAKE_DEP_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING) | OPTST_ARG_OPTIONAL) + +/* + * Help/More_Help/Version option descriptions: + */ +#define HELP_DESC (xml2ag_opt_strs+2049) +#define HELP_name (xml2ag_opt_strs+2093) +#ifdef HAVE_WORKING_FORK +#define MORE_HELP_DESC (xml2ag_opt_strs+2098) +#define MORE_HELP_name (xml2ag_opt_strs+2143) +#define MORE_HELP_FLAGS (OPTST_IMM | OPTST_NO_INIT) +#else +#define MORE_HELP_DESC HELP_DESC +#define MORE_HELP_name HELP_name +#define MORE_HELP_FLAGS (OPTST_OMITTED | OPTST_NO_INIT) +#endif +#ifdef NO_OPTIONAL_OPT_ARGS +# define VER_FLAGS (OPTST_IMM | OPTST_NO_INIT) +#else +# define VER_FLAGS (OPTST_SET_ARGTYPE(OPARG_TYPE_STRING) | \ + OPTST_ARG_OPTIONAL | OPTST_IMM | OPTST_NO_INIT) +#endif +#define VER_DESC (xml2ag_opt_strs+2153) +#define VER_name (xml2ag_opt_strs+2189) +/** + * Declare option callback procedures + */ +extern tOptProc + optionBooleanVal, optionNestedVal, optionNumericVal, + optionPagedUsage, optionPrintVersion, optionResetOpt, + optionStackArg, optionTimeDate, optionTimeVal, + optionUnstackArg, optionVendorOption; +static tOptProc + doOptLoop_Limit, doOptOutput, doOptTimeout, doOptTrace, doUsageOpt; +#define VER_PROC optionPrintVersion + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Define the xml2ag Option Descriptions. + * This is an array of OPTION_CT entries, one for each + * option that the xml2ag program responds to. + */ +static tOptDesc optDesc[OPTION_CT] = { + { /* entry idx, value */ 0, 0, + /* equiv idx, value */ 0, 0, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 0, 0, + /* opt state flags */ THE_XML2AG_OPTION_FLAGS, 0, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ THE_XML2AG_OPTION_DESC, NULL, NULL, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 1, VALUE_OPT_OUTPUT, + /* equiv idx, value */ 1, VALUE_OPT_OUTPUT, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ OUTPUT_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --output */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ doOptOutput, + /* desc, NAME, name */ OUTPUT_DESC, OUTPUT_NAME, OUTPUT_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 0, 0, + /* equiv idx, value */ 0, 0, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 0, 0, + /* opt state flags */ AUTOGEN_OPTIONS_FLAGS, 0, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ AUTOGEN_OPTIONS_DESC, NULL, NULL, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 3, VALUE_OPT_TEMPL_DIRS, + /* equiv idx, value */ 3, VALUE_OPT_TEMPL_DIRS, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, NOLIMIT, 0, + /* opt state flags */ TEMPL_DIRS_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --templ-dirs */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ optionStackArg, + /* desc, NAME, name */ TEMPL_DIRS_DESC, TEMPL_DIRS_NAME, TEMPL_DIRS_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 4, VALUE_OPT_OVERRIDE_TPL, + /* equiv idx, value */ 4, VALUE_OPT_OVERRIDE_TPL, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ OVERRIDE_TPL_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --override-tpl */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ OVERRIDE_TPL_DESC, OVERRIDE_TPL_NAME, OVERRIDE_TPL_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 5, VALUE_OPT_DEFINITIONS, + /* equiv idx, value */ 5, VALUE_OPT_DEFINITIONS, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ DEFINITIONS_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --definitions */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ DEFINITIONS_DESC, DEFINITIONS_NAME, DEFINITIONS_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 6, VALUE_OPT_SHELL, + /* equiv idx, value */ 6, VALUE_OPT_SHELL, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ SHELL_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --shell */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ SHELL_DESC, SHELL_NAME, SHELL_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 7, VALUE_OPT_NO_FMEMOPEN, + /* equiv idx, value */ 7, VALUE_OPT_NO_FMEMOPEN, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ NO_FMEMOPEN_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --no-fmemopen */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ NO_FMEMOPEN_DESC, NO_FMEMOPEN_NAME, NO_FMEMOPEN_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 8, VALUE_OPT_EQUATE, + /* equiv idx, value */ 8, VALUE_OPT_EQUATE, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ EQUATE_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --equate */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ EQUATE_DESC, EQUATE_NAME, EQUATE_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 9, VALUE_OPT_BASE_NAME, + /* equiv idx, value */ 9, VALUE_OPT_BASE_NAME, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ BASE_NAME_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --base-name */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ BASE_NAME_DESC, BASE_NAME_NAME, BASE_NAME_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 10, VALUE_OPT_SOURCE_TIME, + /* equiv idx, value */ 10, VALUE_OPT_SOURCE_TIME, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ SOURCE_TIME_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --source-time */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ SOURCE_TIME_DESC, SOURCE_TIME_NAME, SOURCE_TIME_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 11, VALUE_OPT_WRITABLE, + /* equiv idx, value */ 11, VALUE_OPT_WRITABLE, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ WRITABLE_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --writable */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ WRITABLE_DESC, WRITABLE_NAME, WRITABLE_name, + /* disablement strs */ NOT_WRITABLE_name, NOT_WRITABLE_PFX }, + + { /* entry idx, value */ 12, VALUE_OPT_LOOP_LIMIT, + /* equiv idx, value */ 12, VALUE_OPT_LOOP_LIMIT, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ LOOP_LIMIT_FLAGS, 0, + /* last opt argumnt */ { LOOP_LIMIT_DFT_ARG }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ doOptLoop_Limit, + /* desc, NAME, name */ LOOP_LIMIT_DESC, LOOP_LIMIT_NAME, LOOP_LIMIT_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 13, VALUE_OPT_TIMEOUT, + /* equiv idx, value */ 13, VALUE_OPT_TIMEOUT, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ TIMEOUT_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --timeout */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ doOptTimeout, + /* desc, NAME, name */ TIMEOUT_DESC, TIMEOUT_NAME, TIMEOUT_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 14, VALUE_OPT_TRACE, + /* equiv idx, value */ 14, VALUE_OPT_TRACE, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ TRACE_FLAGS, 0, + /* last opt argumnt */ { TRACE_DFT_ARG }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ doOptTrace, + /* desc, NAME, name */ TRACE_DESC, TRACE_NAME, TRACE_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 15, VALUE_OPT_TRACE_OUT, + /* equiv idx, value */ 15, VALUE_OPT_TRACE_OUT, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ TRACE_OUT_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --trace-out */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ TRACE_OUT_DESC, TRACE_OUT_NAME, TRACE_OUT_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 16, VALUE_OPT_SHOW_DEFS, + /* equiv idx, value */ 16, VALUE_OPT_SHOW_DEFS, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ SHOW_DEFS_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --show-defs */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ SHOW_DEFS_DESC, SHOW_DEFS_NAME, SHOW_DEFS_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 17, VALUE_OPT_USED_DEFINES, + /* equiv idx, value */ 17, VALUE_OPT_USED_DEFINES, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ USED_DEFINES_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --used-defines */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ USED_DEFINES_DESC, USED_DEFINES_NAME, USED_DEFINES_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 18, VALUE_OPT_CORE, + /* equiv idx, value */ 18, VALUE_OPT_CORE, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ CORE_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --core */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ CORE_DESC, CORE_NAME, CORE_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 19, VALUE_OPT_SKIP_SUFFIX, + /* equiv idx, value */ 19, VALUE_OPT_SKIP_SUFFIX, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, NOLIMIT, 0, + /* opt state flags */ SKIP_SUFFIX_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --skip-suffix */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, aSkip_SuffixCantList, + /* option proc */ optionStackArg, + /* desc, NAME, name */ SKIP_SUFFIX_DESC, SKIP_SUFFIX_NAME, SKIP_SUFFIX_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 20, VALUE_OPT_SELECT_SUFFIX, + /* equiv idx, value */ 20, VALUE_OPT_SELECT_SUFFIX, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, NOLIMIT, 0, + /* opt state flags */ SELECT_SUFFIX_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --select-suffix */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ optionStackArg, + /* desc, NAME, name */ SELECT_SUFFIX_DESC, SELECT_SUFFIX_NAME, SELECT_SUFFIX_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 21, VALUE_OPT_DEFINE, + /* equiv idx, value */ 21, VALUE_OPT_DEFINE, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, NOLIMIT, 0, + /* opt state flags */ DEFINE_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --define */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ optionStackArg, + /* desc, NAME, name */ DEFINE_DESC, DEFINE_NAME, DEFINE_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 22, VALUE_OPT_UNDEFINE, + /* equiv idx, value */ NOLIMIT, NOLIMIT, + /* equivalenced to */ INDEX_OPT_DEFINE, + /* min, max, act ct */ 0, NOLIMIT, 0, + /* opt state flags */ UNDEFINE_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --undefine */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ optionUnstackArg, + /* desc, NAME, name */ UNDEFINE_DESC, UNDEFINE_NAME, UNDEFINE_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 23, VALUE_OPT_MAKE_DEP, + /* equiv idx, value */ 23, VALUE_OPT_MAKE_DEP, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, NOLIMIT, 0, + /* opt state flags */ MAKE_DEP_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* --make-dep */ + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ MAKE_DEP_DESC, MAKE_DEP_NAME, MAKE_DEP_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ INDEX_OPT_VERSION, VALUE_OPT_VERSION, + /* equiv idx value */ NO_EQUIVALENT, VALUE_OPT_VERSION, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ VER_FLAGS, AOUSE_VERSION, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ VER_PROC, + /* desc, NAME, name */ VER_DESC, NULL, VER_name, + /* disablement strs */ NULL, NULL }, + + + + { /* entry idx, value */ INDEX_OPT_HELP, VALUE_OPT_HELP, + /* equiv idx value */ NO_EQUIVALENT, VALUE_OPT_HELP, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ OPTST_IMM | OPTST_NO_INIT, AOUSE_HELP, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ doUsageOpt, + /* desc, NAME, name */ HELP_DESC, NULL, HELP_name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ INDEX_OPT_MORE_HELP, VALUE_OPT_MORE_HELP, + /* equiv idx value */ NO_EQUIVALENT, VALUE_OPT_MORE_HELP, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ MORE_HELP_FLAGS, AOUSE_MORE_HELP, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ optionPagedUsage, + /* desc, NAME, name */ MORE_HELP_DESC, NULL, MORE_HELP_name, + /* disablement strs */ NULL, NULL } +}; + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** Reference to the upper cased version of xml2ag. */ +#define zPROGNAME (xml2ag_opt_strs+2197) +/** Reference to the title line for xml2ag usage. */ +#define zUsageTitle (xml2ag_opt_strs+2204) +/** There is no xml2ag configuration file. */ +#define zRcName NULL +/** There are no directories to search for xml2ag config files. */ +#define apzHomeList NULL +/** The xml2ag program bug email address. */ +#define zBugsAddr (xml2ag_opt_strs+2350) +/** Clarification/explanation of what xml2ag does. */ +#define zExplain (xml2ag_opt_strs+2386) +/** Extra detail explaining what xml2ag does. */ +#define zDetail (xml2ag_opt_strs+2493) +/** The full version string for xml2ag. */ +#define zFullVersion (xml2ag_opt_strs+2762) +/* extracted from optcode.tlib near line 342 */ + +#define OPTPROC_BASE OPTPROC_NONE +#define translate_option_strings NULL + +#define xml2ag_full_usage (NULL) +#define xml2ag_short_usage (NULL) + +#endif /* not defined __doxygen__ */ + +/* + * Create the static procedure(s) declared above. + */ +/** + * The callout function that invokes the optionUsage function. + * + * @param[in] opts the AutoOpts option description structure + * @param[in] od the descriptor for the "help" (usage) option. + * @noreturn + */ +static void +doUsageOpt(tOptions * opts, tOptDesc * od) +{ + int ex_code; + ex_code = XML2AG_EXIT_SUCCESS; + optionUsage(&xml2agOptions, ex_code); + /* NOTREACHED */ + exit(XML2AG_EXIT_FAILURE); + (void)opts; + (void)od; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Code to handle the output option. + * By default, the output is handed to an AutoGen for processing. + * However, you may save the definitions to a file instead. + * @param[in] pOptions the xml2ag options data structure + * @param[in,out] pOptDesc the option descriptor for this option. + */ +static void +doOptOutput(tOptions* pOptions, tOptDesc* pOptDesc) +{ + /* + * Be sure the flag-code[0] handles special values for the options pointer + * viz. (poptions <= OPTPROC_EMIT_LIMIT) *and also* the special flag bit + * ((poptdesc->fOptState & OPTST_RESET) != 0) telling the option to + * reset its state. + */ + /* extracted from xmlopts.def, line 70 */ + if (strcmp(pOptDesc->optArg.argString, "-") == 0) + return; + + if (freopen(pOptDesc->optArg.argString, "w", stdout) == NULL) { + fprintf(stderr, "Error %d (%s) opening `%s' for output", + errno, strerror(errno), pOptDesc->optArg.argString); + exit(EXIT_FAILURE); + } + (void)pOptions; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Code to handle the loop-limit option. + * Pass-through AutoGen argument + * @param[in] pOptions the xml2ag options data structure + * @param[in,out] pOptDesc the option descriptor for this option. + */ +static void +doOptLoop_Limit(tOptions* pOptions, tOptDesc* pOptDesc) +{ + static struct {long rmin, rmax;} const rng[2] = { + { -1, LONG_MIN }, { 1, 0x1000000 } }; + int ix; + + if (pOptions <= OPTPROC_EMIT_LIMIT) + goto emit_ranges; + optionNumericVal(pOptions, pOptDesc); + + for (ix = 0; ix < 2; ix++) { + if (pOptDesc->optArg.argInt < rng[ix].rmin) + continue; /* ranges need not be ordered. */ + if (pOptDesc->optArg.argInt == rng[ix].rmin) + return; + if (rng[ix].rmax == LONG_MIN) + continue; + if (pOptDesc->optArg.argInt <= rng[ix].rmax) + return; + } + + option_usage_fp = stderr; + + emit_ranges: +optionShowRange(pOptions, pOptDesc, VOIDP(rng), 2); +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Code to handle the timeout option. + * Pass-through AutoGen argument + * @param[in] pOptions the xml2ag options data structure + * @param[in,out] pOptDesc the option descriptor for this option. + */ +static void +doOptTimeout(tOptions* pOptions, tOptDesc* pOptDesc) +{ + static struct {long rmin, rmax;} const rng[1] = { + { 0, 3600 } }; + int ix; + + if (pOptions <= OPTPROC_EMIT_LIMIT) + goto emit_ranges; + optionNumericVal(pOptions, pOptDesc); + + for (ix = 0; ix < 1; ix++) { + if (pOptDesc->optArg.argInt < rng[ix].rmin) + continue; /* ranges need not be ordered. */ + if (pOptDesc->optArg.argInt == rng[ix].rmin) + return; + if (rng[ix].rmax == LONG_MIN) + continue; + if (pOptDesc->optArg.argInt <= rng[ix].rmax) + return; + } + + option_usage_fp = stderr; + + emit_ranges: +optionShowRange(pOptions, pOptDesc, VOIDP(rng), 1); +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/** + * Code to handle the trace option. + * Pass-through AutoGen argument + * @param[in] pOptions the xml2ag options data structure + * @param[in,out] pOptDesc the option descriptor for this option. + */ +static void +doOptTrace(tOptions* pOptions, tOptDesc* pOptDesc) +{ + +/* extracted from optmain.tlib near line 945 */ + static char const * const names[7] = { + xml2ag_opt_strs+2791, xml2ag_opt_strs+2799, xml2ag_opt_strs+2813, + xml2ag_opt_strs+2826, xml2ag_opt_strs+2836, xml2ag_opt_strs+2849, + xml2ag_opt_strs+2861 }; + + if (pOptions <= OPTPROC_EMIT_LIMIT) { + (void) optionEnumerationVal(pOptions, pOptDesc, names, 7); + return; /* protect AutoOpts client code from internal callbacks */ + } + + pOptDesc->optArg.argEnum = + optionEnumerationVal(pOptions, pOptDesc, names, 7); +} +/* extracted from optmain.tlib near line 1250 */ + +/** + * The directory containing the data associated with xml2ag. + */ +#ifndef PKGDATADIR +# define PKGDATADIR "" +#endif + +/** + * Information about the person or institution that packaged xml2ag + * for the current distribution. + */ +#ifndef WITH_PACKAGER +# define xml2ag_packager_info NULL +#else +/** Packager information for xml2ag. */ +static char const xml2ag_packager_info[] = + "Packaged by " WITH_PACKAGER + +# ifdef WITH_PACKAGER_VERSION + " ("WITH_PACKAGER_VERSION")" +# endif + +# ifdef WITH_PACKAGER_BUG_REPORTS + "\nReport xml2ag bugs to " WITH_PACKAGER_BUG_REPORTS +# endif + "\n"; +#endif +#ifndef __doxygen__ + +#endif /* __doxygen__ */ +/** + * The option definitions for xml2ag. The one structure that + * binds them all. + */ +tOptions xml2agOptions = { + OPTIONS_STRUCT_VERSION, + 0, NULL, /* original argc + argv */ + ( OPTPROC_BASE + + OPTPROC_ERRSTOP + + OPTPROC_SHORTOPT + + OPTPROC_LONGOPT + + OPTPROC_NO_REQ_OPT + + OPTPROC_NEGATIONS ), + 0, NULL, /* current option index, current option */ + NULL, NULL, zPROGNAME, + zRcName, zCopyright, zLicenseDescrip, + zFullVersion, apzHomeList, zUsageTitle, + zExplain, zDetail, optDesc, + zBugsAddr, /* address to send bugs to */ + NULL, NULL, /* extensions/saved state */ + optionUsage, /* usage procedure */ + translate_option_strings, /* translation procedure */ + /* + * Indexes to special options + */ + { INDEX_OPT_MORE_HELP, /* more-help option index */ + NO_EQUIVALENT, /* save option index */ + NO_EQUIVALENT, /* '-#' option index */ + NO_EQUIVALENT /* index of default opt */ + }, + 27 /* full option count */, 24 /* user option count */, + xml2ag_full_usage, xml2ag_short_usage, + NULL, NULL, + PKGDATADIR, xml2ag_packager_info +}; + +#ifdef __cplusplus +} +#endif +/** @} */ +/* xmlopts.c ends here */ diff --git a/xml2ag/xmlopts.def b/xml2ag/xmlopts.def new file mode 100644 index 0000000..b2e6a9c --- /dev/null +++ b/xml2ag/xmlopts.def @@ -0,0 +1,180 @@ +/* -*- Mode: conf -*- */ + +autogen definitions options; +addtogroup = xml2ag; + +/* xmlopts.def: option definitions for xml2ag + * + * This file is part of AutoGen. + * AutoGen Copyright (C) 1992-2018 by Bruce Korb - all rights reserved + * + * AutoGen is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AutoGen is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ +export = <<- EOExport + #include + #include + + #ifndef __USE_POSIX + # define __USE_POSIX /* for glib's pedantic needs */ + #endif + #ifndef __USE_XOPEN_EXTENDED + # define __USE_XOPEN_EXTENDED /* ditto */ + #endif + #include + #include + #include + #include + #include + #include + #include + #include + + #include + #include + + extern FILE * ag_pipe_fp; + #ifndef NUL + # define NUL '\0' + #endif + extern void fork_ag(char const * pzInput); + EOExport; + +flag = { + name = the-xml2ag-option; + documentation; + descrip = 'All other options are derived from autogen'; +}; + +flag = { + name = output; + value = O; + arg-type = string; + arg-name = file; + descrip = "Output file in lieu of AutoGen processing"; + doc = + "By default, the output is handed to an AutoGen for processing.\n" + "However, you may save the definitions to a file instead."; + + flag_code = <<- FLAG_CODE_END + if (strcmp(pOptDesc->optArg.argString, "-") == 0) + return; + + if (freopen(pOptDesc->optArg.argString, "w", stdout) == NULL) { + fprintf(stderr, "Error %d (%s) opening `%s' for output", + errno, strerror(errno), pOptDesc->optArg.argString); + exit(EXIT_FAILURE); + } + FLAG_CODE_END ; +}; + +flag = { + name = autogen-options; + documentation = <<- _EODoc_ + These options are @i{mostly} just passed throug to @code{autogen}. + The one exception is @code{--override-tpl} which replaces the + default template in the output definitions. It does not get passed + through on the command line. + _EODoc_; + + descrip = 'All other options'; +}; + +#define XML2AG +#option templ-dir $top_srcdir/agen5 +#option templ-dir $top_srcdir/autoopts +#include opts.def + +explain = <<- END_EXPLAIN + This program will convert any arbitrary XML file into equivalent + AutoGen definitions, and invoke AutoGen. + END_EXPLAIN ; + +detail = <<- END_DETAIL + The template will be derived from either: + * the ``--override-tpl'' command line option + * a top level XML attribute named, "template" + + The ``base-name'' for the output will similarly be either: + * the ``--base-name'' command line option + * the base name of the .xml file + END_DETAIL ; + +prog-man-descrip = <<- END_DETAIL + The template will be derived from either: + .br + * the \fB--override-tpl\fP command line option + .br + * a top level XML attribute named, "template" + .br + One or the other \fBmust\fP be provided, or the program will + exit with a failure message. + .sp 1 + The ``base-name'' for the output will similarly be either: + .br + * the \fB--base-name\fP command line option + .br + * the base name of the .xml file + END_DETAIL ; + +prog-info-descrip = <<- END_DETAIL + The template used will be derived from either: + @itemize @bullet + @item + The @strong{--override-tpl} command line option + @item + A top level XML attribute named, "@code{template}" + @end itemize + @noindent + One or the other @strong{must} be provided, or the program will + exit with a failure message. + + The @emph{base-name} for the output will similarly be either: + @itemize @bullet + @item + The @strong{--base-name} command line option. + @item + The base name of the @file{.xml} file. + @end itemize + + The definitions derived from XML generally have an extra layer + of definition. Specifically, this XML input: + @example + + mumble-1 + + grumble, grumble, grumble. + mumble, mumble + + @end example + Will get converted into this: + @example + mumble = @{ + grumble = @{ + text = 'grumble, grumble, grumble'; + @}; + text = 'mumble-1'; + text = 'mumble, mumble'; + @}; + @end example + Please notice that some information is lost. AutoGen cannot tell that + "grumble" used to lie between the mumble texts. Also please note that + you cannot assign: + @example + grumble = 'grumble, grumble, grumble.'; + @end example + because if another "grumble" has an attribute or multiple texts, + it becomes impossible to have the definitions be the same type + (compound or text values). + END_DETAIL ; +/* end of xmlopts.def */ -- 2.34.1