summaryrefslogtreecommitdiff
path: root/autoopts
diff options
context:
space:
mode:
Diffstat (limited to 'autoopts')
-rw-r--r--autoopts/Makefile.am207
-rw-r--r--autoopts/Makefile.in1193
-rw-r--r--autoopts/ag-char-map.h510
-rw-r--r--autoopts/alias.c108
-rw-r--r--autoopts/ao-strs.c323
-rw-r--r--autoopts/ao-strs.def429
-rw-r--r--autoopts/ao-strs.h250
-rw-r--r--autoopts/ao_string_tokenize.386
-rw-r--r--autoopts/autogen.map81
-rw-r--r--autoopts/autoopts-config.1161
-rw-r--r--autoopts/autoopts-config.in114
-rw-r--r--autoopts/autoopts.c729
-rw-r--r--autoopts/autoopts.h335
-rw-r--r--autoopts/autoopts.m4225
-rw-r--r--autoopts/autoopts/options.h1110
-rw-r--r--autoopts/autoopts/usage-txt.h435
-rw-r--r--autoopts/boolean.c97
-rw-r--r--autoopts/bootstrap.dir232
-rw-r--r--autoopts/check.c166
-rw-r--r--autoopts/configFileLoad.350
-rw-r--r--autoopts/configfile.c1433
-rw-r--r--autoopts/cook.c311
-rw-r--r--autoopts/enum.c546
-rw-r--r--autoopts/env.c264
-rw-r--r--autoopts/file.c208
-rw-r--r--autoopts/find.c579
-rw-r--r--autoopts/funcs.def1620
-rw-r--r--autoopts/genshell.c452
-rw-r--r--autoopts/genshell.def79
-rw-r--r--autoopts/genshell.h184
-rw-r--r--autoopts/gettext.h288
-rw-r--r--autoopts/install-hook.sh124
-rw-r--r--autoopts/load.c519
-rw-r--r--autoopts/makeshell.c873
-rw-r--r--autoopts/mk-autoopts-pc.in78
-rwxr-xr-xautoopts/mk-tpl-config.sh140
-rw-r--r--autoopts/nested.c849
-rw-r--r--autoopts/numeric.c165
-rw-r--r--autoopts/optionFileLoad.352
-rw-r--r--autoopts/optionFindNextValue.350
-rw-r--r--autoopts/optionFindValue.346
-rw-r--r--autoopts/optionFree.331
-rw-r--r--autoopts/optionGetValue.347
-rw-r--r--autoopts/optionLoadLine.345
-rw-r--r--autoopts/optionNextValue.347
-rw-r--r--autoopts/optionOnlyUsage.331
-rw-r--r--autoopts/optionProcess.355
-rw-r--r--autoopts/optionRestore.335
-rw-r--r--autoopts/optionSaveFile.344
-rw-r--r--autoopts/optionSaveState.341
-rw-r--r--autoopts/optionUnloadNested.328
-rw-r--r--autoopts/optionVersion.327
-rw-r--r--autoopts/parse-duration.c601
-rw-r--r--autoopts/parse-duration.h90
-rw-r--r--autoopts/pgusage.c132
-rw-r--r--autoopts/po/usage-txt.pot474
-rw-r--r--autoopts/project.h50
-rw-r--r--autoopts/proto.h130
-rw-r--r--autoopts/putshell.c361
-rw-r--r--autoopts/reset.c138
-rw-r--r--autoopts/restore.c228
-rw-r--r--autoopts/save.c768
-rw-r--r--autoopts/sort.c336
-rw-r--r--autoopts/stack.c269
-rw-r--r--autoopts/strequate.332
-rw-r--r--autoopts/streqvcmp.339
-rw-r--r--autoopts/streqvcmp.c267
-rw-r--r--autoopts/streqvmap.348
-rw-r--r--autoopts/strneqvcmp.343
-rw-r--r--autoopts/strtransform.337
-rw-r--r--autoopts/test/Makefile.am53
-rw-r--r--autoopts/test/Makefile.in560
-rwxr-xr-xautoopts/test/alias.test120
-rwxr-xr-xautoopts/test/argument.test209
-rwxr-xr-xautoopts/test/cfg-edit.test330
-rwxr-xr-xautoopts/test/cond.test194
-rwxr-xr-xautoopts/test/config.test201
-rw-r--r--autoopts/test/defs.in351
-rwxr-xr-xautoopts/test/doc.test848
-rwxr-xr-xautoopts/test/enums.test309
-rwxr-xr-xautoopts/test/equiv.test274
-rwxr-xr-xautoopts/test/errors.test232
-rwxr-xr-xautoopts/test/getopt.test668
-rwxr-xr-xautoopts/test/handler.test254
-rwxr-xr-xautoopts/test/immediate.test121
-rwxr-xr-xautoopts/test/keyword.test449
-rwxr-xr-xautoopts/test/library.test170
-rwxr-xr-xautoopts/test/main.test127
-rwxr-xr-xautoopts/test/nested.test266
-rwxr-xr-xautoopts/test/nls.test156
-rwxr-xr-xautoopts/test/rc.test240
-rwxr-xr-xautoopts/test/shell.test457
-rw-r--r--autoopts/test/stdopts.def109
-rwxr-xr-xautoopts/test/stdopts.test161
-rwxr-xr-xautoopts/test/time.test101
-rwxr-xr-xautoopts/test/usage.test656
-rwxr-xr-xautoopts/test/vendor.test174
-rwxr-xr-xautoopts/test/vers.test107
-rw-r--r--autoopts/text_mmap.c370
-rw-r--r--autoopts/time.c143
-rw-r--r--autoopts/tokenize.c333
-rw-r--r--autoopts/tpl/aginfo.tpl10
-rw-r--r--autoopts/tpl/aginfo3.tpl128
-rw-r--r--autoopts/tpl/agman-cmd.tpl123
-rw-r--r--autoopts/tpl/agman.tlib81
-rw-r--r--autoopts/tpl/agman1.tpl10
-rw-r--r--autoopts/tpl/agman3.tpl142
-rw-r--r--autoopts/tpl/agmdoc-cmd.tpl115
-rw-r--r--autoopts/tpl/agpl.lic19
-rw-r--r--autoopts/tpl/agtexi-cmd.tpl894
-rw-r--r--autoopts/tpl/bits.tpl721
-rw-r--r--autoopts/tpl/cmd-doc.tlib1001
-rw-r--r--autoopts/tpl/def2pot.tpl131
-rw-r--r--autoopts/tpl/getopt.tpl517
-rw-r--r--autoopts/tpl/gpl.lic20
-rw-r--r--autoopts/tpl/gplv2.lic19
-rw-r--r--autoopts/tpl/lgpl.lic20
-rwxr-xr-xautoopts/tpl/man2mdoc.pl279
-rwxr-xr-xautoopts/tpl/man2texi.sh29
-rw-r--r--autoopts/tpl/mbsd.lic31
-rwxr-xr-xautoopts/tpl/mdoc2man.sh298
-rwxr-xr-xautoopts/tpl/mdoc2texi.pl345
-rw-r--r--autoopts/tpl/optcode.tlib819
-rw-r--r--autoopts/tpl/opthead.tlib601
-rw-r--r--autoopts/tpl/options.tpl57
-rw-r--r--autoopts/tpl/optlib.tlib1260
-rw-r--r--autoopts/tpl/optmain.tlib1255
-rw-r--r--autoopts/tpl/rc-sample.tpl126
-rw-r--r--autoopts/tpl/stdoptions.def345
-rw-r--r--autoopts/tpl/strings.tpl174
-rwxr-xr-xautoopts/tpl/texi2man.sh76
-rwxr-xr-xautoopts/tpl/texi2mdoc.sh196
-rw-r--r--autoopts/tpl/tpl-config-tlib.in84
-rw-r--r--autoopts/tpl/usage-txt.tpl199
-rw-r--r--autoopts/tpl/usage.tlib207
-rw-r--r--autoopts/usage.c1053
-rw-r--r--autoopts/value-type.c123
-rw-r--r--autoopts/value-type.h25
-rw-r--r--autoopts/version.c214
-rw-r--r--autoopts/xat-attribute.c114
-rw-r--r--autoopts/xat-attribute.h22
141 files changed, 40801 insertions, 0 deletions
diff --git a/autoopts/Makefile.am b/autoopts/Makefile.am
new file mode 100644
index 0000000..9a57022
--- /dev/null
+++ b/autoopts/Makefile.am
@@ -0,0 +1,207 @@
+## -*- Mode: Makefile -*-
+## ---------------------------------------------------------------------
+## autoopts/Makefile.am
+##
+## Time-stamp: "2012-04-14 14:22:31 bkorb"
+## Author: Bruce Korb <bkorb@gnu.org>
+##
+## This file is part of AutoOpts, a companion to AutoGen.
+## AutoOpts is free software.
+## AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
+
+SUBDIRS = @OPTS_TESTDIR@
+INCLUDES = @INCLIST@
+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 optionNextValue.3 \
+ optionOnlyUsage.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/man2man tpl/man2mdoc tpl/man2texi \
+ tpl/mdoc2man tpl/mdoc2mdoc tpl/mdoc2texi \
+ tpl/texi2man tpl/texi2mdoc tpl/texi2texi \
+ tpl/tpl-config.tlib
+
+pkgdata_DATA = \
+ autoopts.m4 tpl/aginfo.tpl tpl/aginfo3.tpl \
+ tpl/agman-cmd.tpl tpl/agman.tlib tpl/agman1.tpl \
+ tpl/agman3.tpl tpl/agmdoc-cmd.tpl tpl/agpl.lic \
+ tpl/agtexi-cmd.tpl tpl/bits.tpl tpl/cmd-doc.tlib \
+ tpl/def2pot.tpl tpl/getopt.tpl tpl/gpl.lic \
+ tpl/gplv2.lic tpl/lgpl.lic tpl/mbsd.lic \
+ tpl/optcode.tlib tpl/opthead.tlib tpl/options.tpl \
+ tpl/optlib.tlib tpl/optmain.tlib tpl/rc-sample.tpl \
+ tpl/stdoptions.def 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.sh tpl/mdoc2texi.pl tpl/texi2man.sh \
+ tpl/texi2mdoc.sh tpl/tpl-config-tlib.in tpl/usage-txt.tpl
+
+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 += parse-duration.c
+EXTRA_DIST += parse-duration.h
+
+GENHDRS = autoopts/options.h autoopts/usage-txt.h genshell.h \
+ xat-attribute.h value-type.h ao-strs.h ag-char-map.h
+HDRS = $(GENHDRS) autoopts.h project.h proto.h
+GEN_SRC = ao-strs.c value-type.c xat-attribute.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
+
+
+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)"'
+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_PKGDATA = autoopts.m4 $(TPL_FILES)
+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
+nobase_data_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)" \
+ 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
+ $(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)' \
+ 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..2d35b42
--- /dev/null
+++ b/autoopts/Makefile.in
@@ -0,0 +1,1193 @@
+# Makefile.in generated by automake 1.12.2 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2012 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__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
+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
+DIST_COMMON = $(nobase_include_HEADERS) $(srcdir)/Makefile.am \
+ $(srcdir)/Makefile.in $(srcdir)/autoopts-config.in \
+ $(srcdir)/mk-autoopts-pc.in $(top_srcdir)/config/depcomp
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/config/ag_macros.m4 \
+ $(top_srcdir)/config/extensions.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/snprintfv.m4 \
+ $(top_srcdir)/config/unlocked-io.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+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)$(datadir)" \
+ "$(DESTDIR)$(pkgdatadir)" "$(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)
+libopts_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libopts_la_CFLAGS) \
+ $(CFLAGS) $(libopts_la_LDFLAGS) $(LDFLAGS) -o $@
+SCRIPTS = $(bin_SCRIPTS)
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/config/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libopts_la_SOURCES) $(nodist_libopts_la_SOURCES)
+DIST_SOURCES = $(libopts_la_SOURCES)
+RECURSIVE_TARGETS = all-recursive check-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 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) $(nobase_data_DATA) $(nodist_pkgdata_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=) \
+ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
+ distdir
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+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_GUILE = @AG_GUILE@
+AG_LDFLAGS = @AG_LDFLAGS@
+AG_MAJOR_VERSION = @AG_MAJOR_VERSION@
+AG_MINOR_VERSION = @AG_MINOR_VERSION@
+AG_TIMEOUT = @AG_TIMEOUT@
+AG_VERSION = @AG_VERSION@
+AG_XML2 = @AG_XML2@
+AGexe = @AGexe@
+AGnam = @AGnam@
+AMTAR = @AMTAR@
+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_VERSION = @GUILE_VERSION@
+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@
+LIBGUILE_CFLAGS = @LIBGUILE_CFLAGS@
+LIBGUILE_LIBS = @LIBGUILE_LIBS@
+LIBGUILE_PATH = @LIBGUILE_PATH@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBSNPRINTFV = @LIBSNPRINTFV@
+LIBTOOL = @LIBTOOL@
+LIBXML2_CFLAGS = @LIBXML2_CFLAGS@
+LIBXML2_LIBS = @LIBXML2_LIBS@
+LIBXML2_PATH = @LIBXML2_PATH@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+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@
+POSIX_SHELL = @POSIX_SHELL@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+TEXI2HTML = @TEXI2HTML@
+VERSION = @VERSION@
+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@
+SUBDIRS = @OPTS_TESTDIR@
+INCLUDES = @INCLIST@
+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 \
+ parse-duration.c parse-duration.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 optionNextValue.3 \
+ optionOnlyUsage.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/man2man tpl/man2mdoc tpl/man2texi \
+ tpl/mdoc2man tpl/mdoc2mdoc tpl/mdoc2texi \
+ tpl/texi2man tpl/texi2mdoc tpl/texi2texi \
+ tpl/tpl-config.tlib
+
+pkgdata_DATA = \
+ autoopts.m4 tpl/aginfo.tpl tpl/aginfo3.tpl \
+ tpl/agman-cmd.tpl tpl/agman.tlib tpl/agman1.tpl \
+ tpl/agman3.tpl tpl/agmdoc-cmd.tpl tpl/agpl.lic \
+ tpl/agtexi-cmd.tpl tpl/bits.tpl tpl/cmd-doc.tlib \
+ tpl/def2pot.tpl tpl/getopt.tpl tpl/gpl.lic \
+ tpl/gplv2.lic tpl/lgpl.lic tpl/mbsd.lic \
+ tpl/optcode.tlib tpl/opthead.tlib tpl/options.tpl \
+ tpl/optlib.tlib tpl/optmain.tlib tpl/rc-sample.tpl \
+ tpl/stdoptions.def 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.sh tpl/mdoc2texi.pl tpl/texi2man.sh \
+ tpl/texi2mdoc.sh tpl/tpl-config-tlib.in tpl/usage-txt.tpl
+
+GENSCRIPTS = $(srcdir)/funcs.def \
+ tpl/man2man tpl/man2mdoc tpl/man2texi tpl/mdoc2man tpl/mdoc2mdoc \
+ tpl/mdoc2texi tpl/texi2man tpl/texi2mdoc tpl/texi2texi
+
+GENHDRS = autoopts/options.h autoopts/usage-txt.h genshell.h \
+ xat-attribute.h value-type.h ao-strs.h ag-char-map.h
+
+HDRS = $(GENHDRS) autoopts.h project.h proto.h
+GEN_SRC = ao-strs.c value-type.c xat-attribute.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
+
+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)"'
+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_PKGDATA = autoopts.m4 $(TPL_FILES)
+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
+nobase_data_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)" \
+ POSIX_SHELL="$(POSIX_SHELL)"
+
+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 autoopts/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu autoopts/Makefile
+.PRECIOUS: 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__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ 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)
+ $(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@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+libopts_la-libopts.lo: libopts.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --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__mv) $(DEPDIR)/libopts_la-libopts.Tpo $(DEPDIR)/libopts_la-libopts.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libopts.c' object='libopts_la-libopts.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --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-nobase_dataDATA: $(nobase_data_DATA)
+ @$(NORMAL_INSTALL)
+ @list='$(nobase_data_DATA)'; test -n "$(datadir)" || list=; \
+ if test -n "$$list"; then \
+ echo " $(MKDIR_P) '$(DESTDIR)$(datadir)'"; \
+ $(MKDIR_P) "$(DESTDIR)$(datadir)" || 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)$(datadir)/$$dir'"; \
+ $(MKDIR_P) "$(DESTDIR)$(datadir)/$$dir"; }; \
+ echo " $(INSTALL_DATA) $$xfiles '$(DESTDIR)$(datadir)/$$dir'"; \
+ $(INSTALL_DATA) $$xfiles "$(DESTDIR)$(datadir)/$$dir" || exit $$?; }; \
+ done
+
+uninstall-nobase_dataDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(nobase_data_DATA)'; test -n "$(datadir)" || list=; \
+ $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \
+ dir='$(DESTDIR)$(datadir)'; $(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-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.
+$(RECURSIVE_TARGETS) $(RECURSIVE_CLEAN_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ 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"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+cscopelist-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) cscopelist); \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ 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; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ 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 $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP)'; \
+ 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: $(DISTFILES)
+ @list='$(MANS)'; if test -n "$$list"; then \
+ list=`for p in $$list; do \
+ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+ if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \
+ if test -n "$$list" && \
+ grep 'ab help2man is required to generate this page' $$list >/dev/null; then \
+ echo "error: found man pages containing the 'missing help2man' replacement text:" >&2; \
+ grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \
+ echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \
+ echo " typically 'make maintainer-clean' will remove them" >&2; \
+ exit 1; \
+ else :; fi; \
+ else :; fi
+ @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 $(LTLIBRARIES) $(SCRIPTS) $(MANS) $(DATA) $(HEADERS)
+installdirs: installdirs-recursive
+installdirs-am:
+ for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man3dir)" "$(DESTDIR)$(m4datadir)" "$(DESTDIR)$(datadir)" "$(DESTDIR)$(pkgdatadir)" "$(DESTDIR)$(pkgdatadir)" "$(DESTDIR)$(includedir)"; 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:
+ -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 "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-recursive
+
+clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
+ mostlyclean-am
+
+distclean: distclean-recursive
+ -rm -rf ./$(DEPDIR)
+ -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_dataDATA install-nobase_includeHEADERS \
+ install-nodist_pkgdataDATA 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 -rf ./$(DEPDIR)
+ -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_dataDATA \
+ uninstall-nobase_includeHEADERS uninstall-nodist_pkgdataDATA \
+ uninstall-pkgdataDATA
+
+uninstall-man: uninstall-man1 uninstall-man3
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) \
+ cscopelist-recursive ctags-recursive install-am \
+ install-data-am install-strip tags-recursive
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+ all all-am check check-am clean clean-generic \
+ clean-libLTLIBRARIES clean-libtool cscopelist \
+ cscopelist-recursive ctags ctags-recursive 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_dataDATA \
+ install-nobase_includeHEADERS install-nodist_pkgdataDATA \
+ 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-recursive uninstall uninstall-am \
+ uninstall-binSCRIPTS uninstall-libLTLIBRARIES \
+ uninstall-m4dataDATA uninstall-man uninstall-man1 \
+ uninstall-man3 uninstall-nobase_dataDATA \
+ uninstall-nobase_includeHEADERS uninstall-nodist_pkgdataDATA \
+ uninstall-pkgdataDATA
+
+
+libopts.c : tpl-config-stamp
+$(GENSCRIPTS) : tpl-config-stamp
+
+tpl-config-stamp: $(HDRS) $(CSRC) \
+ $(top_builddir)/config.h $(srcdir)/mk-tpl-config.sh
+ $(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)' \
+ 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/ag-char-map.h b/autoopts/ag-char-map.h
new file mode 100644
index 0000000..0f81225
--- /dev/null
+++ b/autoopts/ag-char-map.h
@@ -0,0 +1,510 @@
+/*
+ * 29 bits for 46 character classifications
+ * generated by char-mapper on 08/11/12 at 09:41:13
+ *
+ * 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-2012 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 md5sums:
+ *
+ * 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+ * 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+ * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/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 <inttypes.h>
+
+# elif defined(HAVE_STDINT_H)
+# include <stdint.h>
+
+# 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 <inttypes.h>
+#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 <stdlib.h>
+#include <string.h>
+
+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 */
+};
+
+#define lock_ag_char_map_spanners()
+#define unlock_ag_char_map_spanners()
+
+static unsigned char const *
+calc_ag_char_map_spanners(unsigned int mask_ix)
+{
+ lock_ag_char_map_spanners();
+ if (ag_char_map_spanners[mask_ix] == NULL) {
+ int ix = 1;
+ ag_char_map_mask_t mask = ag_char_map_masks[mask_ix];
+ unsigned char * res = malloc(256 /* 1 << NBBY */);
+ 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;
+ }
+ unlock_ag_char_map_spanners();
+ 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)*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)*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)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)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..f42b619
--- /dev/null
+++ b/autoopts/alias.c
@@ -0,0 +1,108 @@
+
+/**
+ * \file alias.c
+ *
+ * Time-stamp: "2012-08-11 08:15:43 bkorb"
+ *
+ * Automated Options Paged Usage module.
+ *
+ * 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-2012 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 md5sums:
+ *
+ * 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+ * 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+ * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
+ */
+
+/*=export_func optionAlias
+ * private:
+ *
+ * what: relay an option to its alias
+ * arg: + tOptions* + pOpts + program options descriptor +
+ * arg: + tOptDesc* + pOptDesc + 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 * pOpts, tOptDesc * pOldOD, unsigned int alias)
+{
+ tOptDesc * pOD;
+
+ if (pOpts <= OPTPROC_EMIT_LIMIT)
+ return 0;
+
+ pOD = pOpts->pOptDesc + alias;
+ if ((unsigned)pOpts->optCt <= alias) {
+ fwrite(zAliasRange, strlen (zAliasRange), 1, stderr);
+ exit(EXIT_FAILURE);
+ }
+
+ /*
+ * Copy over the option instance flags
+ */
+ pOD->fOptState &= OPTST_PERSISTENT_MASK;
+ pOD->fOptState |= (pOldOD->fOptState & ~OPTST_PERSISTENT_MASK);
+ pOD->optArg.argString = pOldOD->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 ( (pOD->fOptState & OPTST_DEFINED)
+ && (++pOD->optOccCt > pOD->optMaxCt) ) {
+
+ if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0) {
+ char const * pzEqv =
+ (pOD->optEquivIndex != NO_EQUIVALENT) ? zEquiv : zNil;
+
+ fputs(zErrOnly, stderr);
+
+ if (pOD->optMaxCt > 1)
+ fprintf(stderr, zAtMost, pOD->optMaxCt, pOD->pz_Name, pzEqv);
+ else
+ fprintf(stderr, zOnlyOne, pOD->pz_Name, pzEqv);
+ }
+
+ return -1;
+ }
+
+ /*
+ * Clear the state bits and counters
+ */
+ pOldOD->fOptState &= OPTST_PERSISTENT_MASK;
+ pOldOD->optOccCt = 0;
+
+ /*
+ * If there is a procedure to call, call it
+ */
+ if (pOD->pOptProc != NULL)
+ (*pOD->pOptProc)(pOpts, pOD);
+ 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..5f16caa
--- /dev/null
+++ b/autoopts/ao-strs.c
@@ -0,0 +1,323 @@
+/* -*- buffer-read-only: t -*- vi: set ro:
+ *
+ * DO NOT EDIT THIS FILE (ao-strs.c)
+ *
+ * It has been AutoGen-ed August 11, 2012 at 09:41:13 AM by AutoGen 5.16.2pre7
+ * From the definitions ao-strs.def
+ * and the template file strings
+ *
+ * Copyright (C) 2011-2012 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
+ * <http://www.xfree86.org/3.3.6/COPYRIGHT2.html>
+ *
+ * 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[6265] =
+/* 0 */ " \t\n"
+ ":=\0"
+/* 6 */ "INVALID-%d\0"
+/* 17 */ "*INVALID*\0"
+/* 27 */ "none\0"
+/* 32 */ " + \0"
+/* 36 */ " | \0"
+/* 40 */ "%s\n\0"
+/* 44 */ "PAGER\0"
+/* 50 */ "/tmp/use.%lu\0"
+/* 63 */ "more\0"
+/* 68 */ " --* )\n\0"
+/* 79 */ "%s\n"
+ " \0"
+/* 85 */ " \0"
+/* 88 */ " -* )\n\0"
+/* 98 */ " ;;\n\n\0"
+/* 111 */ "stdout\0"
+/* 118 */ "%A %B %e, %Y at %r %Z\0"
+/* 140 */ "#! %s\n\0"
+/* 147 */ "%s_%s=\0"
+/* 154 */ "\n"
+ "export %s_%s\n\0"
+/* 169 */ "''\0"
+/* 172 */ "\\'\0"
+/* 175 */ "'%s'\0"
+/* 180 */ "%s_%s_%d=\0"
+/* 190 */ "\n"
+ "export %s_%s_%d\n\0"
+/* 208 */ "set --\0"
+/* 215 */ " '%s'\0"
+/* 221 */ "'\\''\0"
+/* 226 */ "\n"
+ "OPTION_CT=0\n\0"
+/* 240 */ "=%1$lu # 0x%1$lX\n\0"
+/* 258 */ "true\0"
+/* 263 */ "false\0"
+/* 269 */ "VERSION\0"
+/* 277 */ "OPT_ARG_NEEDED=OK\0"
+/* 295 */ "OPT_ARG_NEEDED=NO\0"
+/* 313 */ "OPT_ARG_NEEDED=YES\0"
+/* 332 */ "LONGUSAGE\0"
+/* 342 */ "flag\0"
+/* 347 */ "%s_%s_TEXT='\0"
+/* 360 */ "'\n\n\0"
+/* 364 */ "option\0"
+/* 371 */ "\n"
+ "env | grep '^%s_'\n\0"
+/* 391 */ " -- %s\0"
+/* 398 */ "--\0"
+/* 401 */ "\t\t\t\t- \0"
+/* 408 */ "\t\t\t\t \0"
+/* 415 */ "\t\0"
+/* 417 */ " * )\n"
+ " OPT_PROCESS=false\n"
+ " ;;\n"
+ " esac\n\0"
+/* 474 */ " %s\n\0"
+/* 480 */ "%%-%ds\0"
+/* 487 */ "%1$s /tmp/use.%2$lu ; rm -f /tmp/use.%2$lu\0"
+/* 530 */ "# # # # # # # # # # -- do not modify this marker --\n"
+ "#\n"
+ "# DO NOT EDIT THIS SECTION\0"
+/* 612 */ "%s OF %s\n"
+ "#\n"
+ "# From here to the next `-- do not modify this marker --',\n"
+ "# the text has been generated %s\n\0"
+/* 718 */ "# From the %s option definitions\n"
+ "#\n\0"
+/* 755 */ "\n"
+ "if test -z \"${%1$s_%2$s}\"\n"
+ "then\n"
+ " %1$s_%2$s_CT=0\n"
+ "else\n"
+ " %1$s_%2$s_CT=1\n"
+ " %1$s_%2$s_1=${%1$s_%2$s}\n"
+ "fi\n"
+ "export %1$s_%2$s_CT\0"
+/* 876 */ "\n"
+ "%1$s_%2$s=${%1$s_%2$s-'%3$s'}\n"
+ "%1$s_%2$s_set=false\n"
+ "export %1$s_%2$s\0"
+/* 944 */ "\n"
+ "%1$s_%2$s=${%1$s_%2$s}\n"
+ "%1$s_%2$s_set=false\n"
+ "export %1$s_%2$s\n\0"
+/* 1006 */ "\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"
+/* 1200 */ "\n"
+ "OPT_ARG=$1\n"
+ "while [ $# -gt 0 ]\n"
+ "do\n"
+ " OPT_ELEMENT=''\n"
+ " OPT_ARG_VAL=''\n"
+ " OPT_ARG=${1}\n\0"
+/* 1290 */ " 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"
+ "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"
+ "%2$s\0"
+/* 1620 */ "\n"
+ "# # # # # # # # # #\n"
+ "#\n"
+ "# END OF AUTOMATED OPTION PROCESSING\n"
+ "#\n"
+ "# # # # # # # # # # -- do not modify this marker --\n\0"
+/* 1736 */ " case \"${OPT_CODE}\" in\n\0"
+/* 1767 */ " '%s' | \\\n\0"
+/* 1785 */ " '%s' )\n\0"
+/* 1801 */ " '%c' )\n\0"
+/* 1817 */ " ;;\n\n\0"
+/* 1834 */ " * )\n"
+ " echo Unknown %s: \"${OPT_CODE}\" >&2\n"
+ " echo \"$%s_USAGE_TEXT\"\n"
+ " exit 1\n"
+ " ;;\n"
+ " esac\n\n\0"
+/* 1976 */ " echo \"$%s_%s_TEXT\"\n"
+ " exit 0\n\0"
+/* 2027 */ " echo \"$%s_LONGUSAGE_TEXT\" | ${PAGER-more}\n"
+ " exit 0\n\0"
+/* 2101 */ " %s\n\0"
+/* 2117 */ " if [ $%1$s_%2$s_CT -ge %3$d ] ; then\n"
+ " echo Error: more than %3$d %2$s options >&2\n"
+ " echo \"$%1$s_USAGE_TEXT\"\n"
+ " exit 1 ; fi\n\0"
+/* 2296 */ " %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"
+/* 2420 */ " if [ -n \"${%1$s_%2$s}\" ] && ${%1$s_%2$s_set} ; then\n"
+ " echo Error: duplicate %2$s option >&2\n"
+ " echo \"$%1$s_USAGE_TEXT\"\n"
+ " exit 1 ; fi\n"
+ " %1$s_%2$s_set=true\n"
+ " OPT_NAME='%2$s'\n\0"
+/* 2667 */ " %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"
+/* 2808 */ " if [ -n \"${%1$s_%2$s}\" ] && ${%1$s_%2$s_set} ; then\n"
+ " echo 'Error: duplicate %2$s option' >&2\n"
+ " echo \"$%1$s_USAGE_TEXT\"\n"
+ " exit 1 ; fi\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"
+/* 3115 */ " eval %1$s_%2$s${OPT_ELEMENT}=true\n"
+ " export %1$s_%2$s${OPT_ELEMENT}\n"
+ " OPT_ARG_NEEDED=OK\n\0"
+/* 3235 */ " OPT_ARG_NEEDED=YES\n\0"
+/* 3267 */ " eval %1$s_%2$s${OPT_ELEMENT}=true\n"
+ " export %1$s_%2$s${OPT_ELEMENT}\n"
+ " OPT_ARG_NEEDED=NO\n\0"
+/* 3387 */ " 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"
+/* 3638 */ " 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 >&2\n"
+ " echo \"$%s_USAGE_TEXT\"\n"
+ " exit 1\n"
+ " fi\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"
+/* 4417 */ " OPT_CODE=`echo \"X${OPT_ARG}\" | sed 's/X-\\(.\\).*/\\1/'`\n"
+ " OPT_ARG=` echo \"X${OPT_ARG}\" | sed 's/X-.//'`\n\0"
+/* 4534 */ " 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 >&2\n"
+ " echo \"$%s_USAGE_TEXT\"\n"
+ " exit 1\n"
+ " fi\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"
+/* 5688 */ "%1$s_%2$s=%3$d # 0x%3$X\n"
+ "export %1$s_%2$s\n\0"
+/* 5730 */ "%1$s_%2$s_CT=%3$d\n"
+ "export %1$s_%2$s_CT\n\0"
+/* 5769 */ "OPTION_CT=%d\n"
+ "export OPTION_CT\n\0"
+/* 5800 */ "%1$s_%2$s=%3$s\n"
+ "export %1$s_%2$s\n\0"
+/* 5833 */ "%1$s_%2$s='%3$s'\n"
+ "export %1$s_%2$s\n\0"
+/* 5868 */ "%1$s_%2$s_MODE='%3$s'\n"
+ "export %1$s_%2$s_MODE\n\0"
+/* 5913 */ "echo 'Warning: Cannot load options files' >&2\0"
+/* 5960 */ "echo 'Warning: Cannot save options files' >&2\0"
+/* 6007 */ "echo 'Warning: Cannot suppress the loading of options files' >&2\0"
+/* 6073 */ "%1$s_%2$s_TEXT='no %2$s text'\n\0"
+/* 6104 */ "%s WARNING: cannot save options - \0"
+/* 6140 */ "<%s/>\n\0"
+/* 6147 */ "<%s>\0"
+/* 6152 */ "</%s>\n\0"
+/* 6159 */ "<%s type=%s>\0"
+/* 6172 */ "<%s type=nested>\n\0"
+/* 6190 */ "#x%02X;\0"
+/* 6198 */ "<%1$s type=boolean>%2$s</%1$s>\n\0"
+/* 6230 */ "<%1$s type=integer>0x%2$lX</%1$s>\n";
+
+/* end of ao-strs.c */
diff --git a/autoopts/ao-strs.def b/autoopts/ao-strs.def
new file mode 100644
index 0000000..624f872
--- /dev/null
+++ b/autoopts/ao-strs.def
@@ -0,0 +1,429 @@
+AutoGen Definitions strings;
+
+string = { nm = ARG_BREAK_STR; str = " \t\n:="; };
+string = { nm = INVALID_FMT; str = "INVALID-%d"; };
+string = { nm = INVALID_STR; str = "*INVALID*"; };
+string = { nm = NONE_STR; str = "none"; };
+string = { nm = PLUS_STR; str = " + "; };
+string = { nm = OR_STR; str = " | "; };
+string = { nm = NLSTR_FMT; str = "%s\n"; };
+string = { nm = PAGER_NAME; str = "PAGER"; };
+string = { nm = TMP_USAGE_FMT; str = "/tmp/use.%lu"; };
+string = { nm = MORE_STR; str = "more"; };
+string = { nm = LONG_OPT_MARK; str = " --* )\n"; };
+string = { nm = NLSTR_SPACE_FMT; str = "%s\n "; };
+string = { nm = TWO_SPACES_STR; str = " "; };
+string = { nm = FLAG_OPT_MARK; str = " -* )\n"; };
+string = { nm = END_OPT_SEL_STR; str = " ;;\n\n"; };
+string = { nm = STDOUT; str = "stdout"; };
+string = { nm = TIME_FMT; str = "%A %B %e, %Y at %r %Z"; };
+string = { nm = SHELL_MAGIC; str = "#! %s\n"; };
+string = { nm = OPT_VAL_FMT; str = "%s_%s="; };
+string = { nm = OPT_END_FMT; str = "\nexport %s_%s\n"; };
+string = { nm = EMPTY_ARG; str = "''"; };
+string = { nm = QUOT_APOS; str = "\\'"; };
+string = { nm = QUOT_ARG_FMT; str = "'%s'"; };
+string = { nm = ARG_BY_NUM_FMT; str = "%s_%s_%d="; };
+string = { nm = EXPORT_ARG_FMT; str = "\nexport %s_%s_%d\n"; };
+string = { nm = set_dash; str = "set --"; };
+string = { nm = arg_fmt; str = " '%s'"; };
+string = { nm = apostrophy; str = "'\\''"; };
+string = { nm = init_optct; str = "\nOPTION_CT=0\n"; };
+string = { nm = SHOW_VAL_FMT; str = "=%1$lu # 0x%1$lX\n"; };
+string = { nm = TRUE_STR; str = "true"; };
+string = { nm = FALSE_STR; str = "false"; };
+string = { nm = VER_STR; str = "VERSION"; };
+string = { nm = OK_NEED_OPT_ARG; str = "OPT_ARG_NEEDED=OK"; };
+string = { nm = NO_ARG_NEEDED; str = "OPT_ARG_NEEDED=NO"; };
+string = { nm = YES_NEED_OPT_ARG; str = "OPT_ARG_NEEDED=YES"; };
+string = { nm = LONG_USE_STR; str = "LONGUSAGE"; };
+string = { nm = FLAG_STR; str = "flag"; };
+string = { nm = SET_TEXT_FMT; str = "%s_%s_TEXT='"; };
+string = { nm = END_SET_TEXT; str = "'\n\n"; };
+string = { nm = OPTION_STR; str = "option"; };
+string = { nm = SHOW_PROG_ENV; str = "\nenv | grep '^%s_'\n"; };
+string = { nm = SET_OFF_FMT; str = " -- %s"; };
+string = { nm = LONG_OPT_MARKER; str = "--"; };
+string = { nm = BULLET_STR; str = "\t\t\t\t- "; };
+string = { nm = DEEP_INDENT_STR; str = "\t\t\t\t "; };
+string = { nm = ONE_TAB_STR; str = "\t"; };
+
+string = { nm = NOT_FOUND_STR;
+ str = <<- _EOStr_
+ * )
+ OPT_PROCESS=false
+ ;;
+ esac
+
+ _EOStr_;
+};
+
+string = { nm = ENUM_ERR_SEP_LINE_FMT;
+ str = " %s\n"; };
+
+string = { nm = ENUM_ERR_STR_WIDTH_FMT;
+ str = "%%-%ds"; };
+
+string = { nm = PAGE_USAGE_FMT;
+ str = "%1$s /tmp/use.%2$lu ; rm -f /tmp/use.%2$lu"; };
+
+string = { nm = START_MARK;
+ str = <<- _EOStr_
+ # # # # # # # # # # -- do not modify this marker --
+ #
+ # DO NOT EDIT THIS SECTION
+ _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 = END_PRE_FMT;
+ str = "# From the %s option definitions\n#\n"; };
+
+string = { nm = MULTI_DEF_FMT;
+ str = <<- _EOStr_
+
+ if test -z "${%1$s_%2$s}"
+ then
+ %1$s_%2$s_CT=0
+ else
+ %1$s_%2$s_CT=1
+ %1$s_%2$s_1=${%1$s_%2$s}
+ fi
+ export %1$s_%2$s_CT
+ _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 = LOOP_STR;
+ str = <<- _EOStr_
+
+ 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 = ONLY_OPTS_LOOP;
+ str = <<- _EOStr_
+
+ OPT_ARG=$1
+ while [ $# -gt 0 ]
+ do
+ OPT_ELEMENT=''
+ OPT_ARG_VAL=''
+ OPT_ARG=${1}
+
+ _EOStr_;
+};
+
+string = { nm = zLoopEnd;
+ 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
+ unset OPT_PROCESS || :
+ unset OPT_ELEMENT || :
+ unset OPT_ARG || :
+ unset OPT_ARG_NEEDED || :
+ unset OPT_NAME || :
+ unset OPT_CODE || :
+ unset OPT_ARG_VAL || :
+ %2$s
+ _EOStr_;
+};
+
+string = { nm = END_MARK;
+ str = <<- _EOStr_
+
+ # # # # # # # # # #
+ #
+ # END OF AUTOMATED OPTION PROCESSING
+ #
+ # # # # # # # # # # -- do not modify this marker --
+
+ _EOStr_;
+};
+
+string = { nm = zOptionCase;
+ str = " case \"${OPT_CODE}\" in\n"; };
+
+string = { nm = zOptionPartName; str = " '%s' | \\\n"; };
+string = { nm = zOptionFullName; str = " '%s' )\n"; };
+string = { nm = zOptionFlag; str = " '%c' )\n"; };
+string = { nm = zOptionEndSelect; str = " ;;\n\n"; };
+
+string = { nm = UNK_OPT_FMT;
+ str =
+" * )\n"
+" echo Unknown %s: \"${OPT_CODE}\" >&2\n"
+" echo \"$%s_USAGE_TEXT\"\n"
+" exit 1\n"
+" ;;\n"
+" esac\n\n"; };
+
+string = { nm = zTextExit;
+ str =
+" echo \"$%s_%s_TEXT\"\n"
+" exit 0\n"; };
+
+string = { nm = zPagedUsageExit;
+ str =
+" echo \"$%s_LONGUSAGE_TEXT\" | ${PAGER-more}\n"
+" exit 0\n"; };
+
+string = { nm = zCmdFmt;
+ str = " %s\n"; };
+
+string = { nm = zCountTest;
+ str =
+" if [ $%1$s_%2$s_CT -ge %3$d ] ; then\n"
+" echo Error: more than %3$d %2$s options >&2\n"
+" echo \"$%1$s_USAGE_TEXT\"\n"
+" exit 1 ; fi\n"; };
+
+string = { nm = MULTI_ARG_FMT;
+ str =
+" %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"; };
+
+string = { nm = SGL_ARG_FMT;
+ str =
+" if [ -n \"${%1$s_%2$s}\" ] && ${%1$s_%2$s_set} ; then\n"
+" echo Error: duplicate %2$s option >&2\n"
+" echo \"$%1$s_USAGE_TEXT\"\n"
+" exit 1 ; fi\n"
+" %1$s_%2$s_set=true\n"
+" OPT_NAME='%2$s'\n"; };
+
+string = { nm = NO_MULTI_ARG_FMT;
+ str =
+" %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"; };
+
+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' >&2
+ echo "$%1$s_USAGE_TEXT"
+ exit 1 ; fi
+ %1$s_%2$s_set=true
+ %1$s_%2$s='%3$s'
+ export %1$s_%2$s
+ OPT_NAME='%2$s'
+
+ _EOStr_;
+};
+
+string = { nm = zMayArg;
+ str =
+" eval %1$s_%2$s${OPT_ELEMENT}=true\n"
+" export %1$s_%2$s${OPT_ELEMENT}\n"
+" OPT_ARG_NEEDED=OK\n"; };
+
+string = { nm = zMustArg;
+ str = " OPT_ARG_NEEDED=YES\n"; };
+
+string = { nm = zCantArg;
+ str =
+" eval %1$s_%2$s${OPT_ELEMENT}=true\n"
+" export %1$s_%2$s${OPT_ELEMENT}\n"
+" OPT_ARG_NEEDED=NO\n"; };
+
+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 = 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 >&2
+ echo "$%s_USAGE_TEXT"
+ exit 1
+ fi
+ 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 = 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 = 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 >&2
+ echo "$%s_USAGE_TEXT"
+ exit 1
+ fi
+ 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 = zOptNumFmt;
+ str = "%1$s_%2$s=%3$d # 0x%3$X\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 = zFullOptFmt;
+ str = "%1$s_%2$s='%3$s'\nexport %1$s_%2$s\n"; };
+
+string = { nm = zEquivMode;
+ str = "%1$s_%2$s_MODE='%3$s'\nexport %1$s_%2$s_MODE\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 = SET_NO_TEXT_FMT;
+ str = "%1$s_%2$s_TEXT='no %2$s text'\n"; };
+
+string = { nm = SAVE_WARN;
+ str = "%s WARNING: cannot save options - "; };
+
+string = { nm = OPEN_CLOSE_FMT; str = "<%s/>\n"; };
+string = { nm = OPEN_XML_FMT; str = "<%s>"; };
+string = { nm = END_XML_FMT; str = "</%s>\n"; };
+string = { nm = TYPE_ATR_FMT; str = "<%s type=%s>"; };
+string = { nm = NULL_ATR_FMT; str = "<%s/>\n"; };
+string = { nm = NESTED_OPT_FMT; str = "<%s type=nested>\n"; };
+string = { nm = XML_HEX_BYTE_FMT; str = "#x%02X;"; };
+
+string = { nm = BOOL_ATR_FMT;
+ str = "<%1$s type=boolean>%2$s</%1$s>\n"; };
+
+string = { nm = NUMB_ATR_FMT;
+ str = "<%1$s type=integer>0x%2$lX</%1$s>\n"; };
+
+#if 0
+string = { nm = ;
+ str = ; };
+#endif
diff --git a/autoopts/ao-strs.h b/autoopts/ao-strs.h
new file mode 100644
index 0000000..62d92ff
--- /dev/null
+++ b/autoopts/ao-strs.h
@@ -0,0 +1,250 @@
+/* -*- buffer-read-only: t -*- vi: set ro:
+ *
+ * DO NOT EDIT THIS FILE (ao-strs.h)
+ *
+ * It has been AutoGen-ed August 11, 2012 at 09:41:13 AM by AutoGen 5.16.2pre7
+ * From the definitions ao-strs.def
+ * and the template file strings
+ *
+ * Copyright (C) 2011-2012 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
+ * <http://www.xfree86.org/3.3.6/COPYRIGHT2.html>
+ *
+ * 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
+/*
+ * 102 strings in ao_strs_strtable string table
+ */
+#define ARG_BREAK_STR (ao_strs_strtable+0)
+#define ARG_BREAK_STR_LEN 5
+#define ARG_BY_NUM_FMT (ao_strs_strtable+180)
+#define ARG_BY_NUM_FMT_LEN 9
+#define BOOL_ATR_FMT (ao_strs_strtable+6198)
+#define BOOL_ATR_FMT_LEN 31
+#define BULLET_STR (ao_strs_strtable+401)
+#define BULLET_STR_LEN 6
+#define DEEP_INDENT_STR (ao_strs_strtable+408)
+#define DEEP_INDENT_STR_LEN 6
+#define EMPTY_ARG (ao_strs_strtable+169)
+#define EMPTY_ARG_LEN 2
+#define END_MARK (ao_strs_strtable+1620)
+#define END_MARK_LEN 115
+#define END_OPT_SEL_STR (ao_strs_strtable+98)
+#define END_OPT_SEL_STR_LEN 12
+#define END_PRE_FMT (ao_strs_strtable+718)
+#define END_PRE_FMT_LEN 36
+#define END_SET_TEXT (ao_strs_strtable+360)
+#define END_SET_TEXT_LEN 3
+#define END_XML_FMT (ao_strs_strtable+6152)
+#define END_XML_FMT_LEN 6
+#define ENUM_ERR_SEP_LINE_FMT (ao_strs_strtable+474)
+#define ENUM_ERR_SEP_LINE_FMT_LEN 5
+#define ENUM_ERR_STR_WIDTH_FMT (ao_strs_strtable+480)
+#define ENUM_ERR_STR_WIDTH_FMT_LEN 6
+#define EXPORT_ARG_FMT (ao_strs_strtable+190)
+#define EXPORT_ARG_FMT_LEN 17
+#define FALSE_STR (ao_strs_strtable+263)
+#define FALSE_STR_LEN 5
+#define FLAG_OPT_MARK (ao_strs_strtable+88)
+#define FLAG_OPT_MARK_LEN 9
+#define FLAG_STR (ao_strs_strtable+342)
+#define FLAG_STR_LEN 4
+#define INIT_LOPT_STR (ao_strs_strtable+3387)
+#define INIT_LOPT_STR_LEN 250
+#define INIT_OPT_STR (ao_strs_strtable+4417)
+#define INIT_OPT_STR_LEN 116
+#define INVALID_FMT (ao_strs_strtable+6)
+#define INVALID_FMT_LEN 10
+#define INVALID_STR (ao_strs_strtable+17)
+#define INVALID_STR_LEN 9
+#define LONG_OPT_MARK (ao_strs_strtable+68)
+#define LONG_OPT_MARKER (ao_strs_strtable+398)
+#define LONG_OPT_MARKER_LEN 2
+#define LONG_OPT_MARK_LEN 10
+#define LONG_USE_STR (ao_strs_strtable+332)
+#define LONG_USE_STR_LEN 9
+#define LOOP_STR (ao_strs_strtable+1006)
+#define LOOP_STR_LEN 193
+#define LOPT_ARG_FMT (ao_strs_strtable+3638)
+#define LOPT_ARG_FMT_LEN 778
+#define MORE_STR (ao_strs_strtable+63)
+#define MORE_STR_LEN 4
+#define MULTI_ARG_FMT (ao_strs_strtable+2296)
+#define MULTI_ARG_FMT_LEN 123
+#define MULTI_DEF_FMT (ao_strs_strtable+755)
+#define MULTI_DEF_FMT_LEN 120
+#define NESTED_OPT_FMT (ao_strs_strtable+6172)
+#define NESTED_OPT_FMT_LEN 17
+#define NLSTR_FMT (ao_strs_strtable+40)
+#define NLSTR_FMT_LEN 3
+#define NLSTR_SPACE_FMT (ao_strs_strtable+79)
+#define NLSTR_SPACE_FMT_LEN 5
+#define NONE_STR (ao_strs_strtable+27)
+#define NONE_STR_LEN 4
+#define NOT_FOUND_STR (ao_strs_strtable+417)
+#define NOT_FOUND_STR_LEN 56
+#define NO_ARG_NEEDED (ao_strs_strtable+295)
+#define NO_ARG_NEEDED_LEN 17
+#define NO_LOAD_WARN (ao_strs_strtable+5913)
+#define NO_LOAD_WARN_LEN 46
+#define NO_MULTI_ARG_FMT (ao_strs_strtable+2667)
+#define NO_MULTI_ARG_FMT_LEN 140
+#define NO_SAVE_OPTS (ao_strs_strtable+5960)
+#define NO_SAVE_OPTS_LEN 46
+#define NO_SGL_ARG_FMT (ao_strs_strtable+2808)
+#define NO_SGL_ARG_FMT_LEN 306
+#define NO_SUPPRESS_LOAD (ao_strs_strtable+6007)
+#define NO_SUPPRESS_LOAD_LEN 65
+#define NULL_ATR_FMT (ao_strs_strtable+6140)
+#define NULL_ATR_FMT_LEN 6
+#define NUMB_ATR_FMT (ao_strs_strtable+6230)
+#define NUMB_ATR_FMT_LEN 34
+#define OK_NEED_OPT_ARG (ao_strs_strtable+277)
+#define OK_NEED_OPT_ARG_LEN 17
+#define ONE_TAB_STR (ao_strs_strtable+415)
+#define ONE_TAB_STR_LEN 1
+#define ONLY_OPTS_LOOP (ao_strs_strtable+1200)
+#define ONLY_OPTS_LOOP_LEN 89
+#define OPEN_CLOSE_FMT (ao_strs_strtable+6140)
+#define OPEN_CLOSE_FMT_LEN 6
+#define OPEN_XML_FMT (ao_strs_strtable+6147)
+#define OPEN_XML_FMT_LEN 4
+#define OPTION_STR (ao_strs_strtable+364)
+#define OPTION_STR_LEN 6
+#define OPT_ARG_FMT (ao_strs_strtable+4534)
+#define OPT_ARG_FMT_LEN 1153
+#define OPT_END_FMT (ao_strs_strtable+154)
+#define OPT_END_FMT_LEN 14
+#define OPT_VAL_FMT (ao_strs_strtable+147)
+#define OPT_VAL_FMT_LEN 6
+#define OR_STR (ao_strs_strtable+36)
+#define OR_STR_LEN 3
+#define PAGER_NAME (ao_strs_strtable+44)
+#define PAGER_NAME_LEN 5
+#define PAGE_USAGE_FMT (ao_strs_strtable+487)
+#define PAGE_USAGE_FMT_LEN 42
+#define PLUS_STR (ao_strs_strtable+32)
+#define PLUS_STR_LEN 3
+#define PREAMBLE_FMT (ao_strs_strtable+612)
+#define PREAMBLE_FMT_LEN 105
+#define QUOT_APOS (ao_strs_strtable+172)
+#define QUOT_APOS_LEN 2
+#define QUOT_ARG_FMT (ao_strs_strtable+175)
+#define QUOT_ARG_FMT_LEN 4
+#define SAVE_WARN (ao_strs_strtable+6104)
+#define SAVE_WARN_LEN 35
+#define SET_NO_TEXT_FMT (ao_strs_strtable+6073)
+#define SET_NO_TEXT_FMT_LEN 30
+#define SET_OFF_FMT (ao_strs_strtable+391)
+#define SET_OFF_FMT_LEN 6
+#define SET_TEXT_FMT (ao_strs_strtable+347)
+#define SET_TEXT_FMT_LEN 12
+#define SGL_ARG_FMT (ao_strs_strtable+2420)
+#define SGL_ARG_FMT_LEN 246
+#define SGL_DEF_FMT (ao_strs_strtable+876)
+#define SGL_DEF_FMT_LEN 67
+#define SGL_NO_DEF_FMT (ao_strs_strtable+944)
+#define SGL_NO_DEF_FMT_LEN 61
+#define SHELL_MAGIC (ao_strs_strtable+140)
+#define SHELL_MAGIC_LEN 6
+#define SHOW_PROG_ENV (ao_strs_strtable+371)
+#define SHOW_PROG_ENV_LEN 19
+#define SHOW_VAL_FMT (ao_strs_strtable+240)
+#define SHOW_VAL_FMT_LEN 17
+#define START_MARK (ao_strs_strtable+530)
+#define START_MARK_LEN 81
+#define STDOUT (ao_strs_strtable+111)
+#define STDOUT_LEN 6
+#define TIME_FMT (ao_strs_strtable+118)
+#define TIME_FMT_LEN 21
+#define TMP_USAGE_FMT (ao_strs_strtable+50)
+#define TMP_USAGE_FMT_LEN 12
+#define TRUE_STR (ao_strs_strtable+258)
+#define TRUE_STR_LEN 4
+#define TWO_SPACES_STR (ao_strs_strtable+85)
+#define TWO_SPACES_STR_LEN 2
+#define TYPE_ATR_FMT (ao_strs_strtable+6159)
+#define TYPE_ATR_FMT_LEN 12
+#define UNK_OPT_FMT (ao_strs_strtable+1834)
+#define UNK_OPT_FMT_LEN 141
+#define VER_STR (ao_strs_strtable+269)
+#define VER_STR_LEN 7
+#define XML_HEX_BYTE_FMT (ao_strs_strtable+6190)
+#define XML_HEX_BYTE_FMT_LEN 7
+#define YES_NEED_OPT_ARG (ao_strs_strtable+313)
+#define YES_NEED_OPT_ARG_LEN 18
+#define apostrophy (ao_strs_strtable+221)
+#define apostrophy_LEN 4
+#define arg_fmt (ao_strs_strtable+215)
+#define arg_fmt_LEN 5
+#define init_optct (ao_strs_strtable+226)
+#define init_optct_LEN 13
+#define set_dash (ao_strs_strtable+208)
+#define set_dash_LEN 6
+#define zCantArg (ao_strs_strtable+3267)
+#define zCantArg_LEN 119
+#define zCmdFmt (ao_strs_strtable+2101)
+#define zCmdFmt_LEN 15
+#define zCountTest (ao_strs_strtable+2117)
+#define zCountTest_LEN 178
+#define zEquivMode (ao_strs_strtable+5868)
+#define zEquivMode_LEN 44
+#define zFullOptFmt (ao_strs_strtable+5833)
+#define zFullOptFmt_LEN 34
+#define zLoopEnd (ao_strs_strtable+1290)
+#define zLoopEnd_LEN 329
+#define zMayArg (ao_strs_strtable+3115)
+#define zMayArg_LEN 119
+#define zMustArg (ao_strs_strtable+3235)
+#define zMustArg_LEN 31
+#define zOptCookieCt (ao_strs_strtable+5730)
+#define zOptCookieCt_LEN 38
+#define zOptCtFmt (ao_strs_strtable+5769)
+#define zOptCtFmt_LEN 30
+#define zOptDisabl (ao_strs_strtable+5800)
+#define zOptDisabl_LEN 32
+#define zOptNumFmt (ao_strs_strtable+5688)
+#define zOptNumFmt_LEN 41
+#define zOptionCase (ao_strs_strtable+1736)
+#define zOptionCase_LEN 30
+#define zOptionEndSelect (ao_strs_strtable+1817)
+#define zOptionEndSelect_LEN 16
+#define zOptionFlag (ao_strs_strtable+1801)
+#define zOptionFlag_LEN 15
+#define zOptionFullName (ao_strs_strtable+1785)
+#define zOptionFullName_LEN 15
+#define zOptionPartName (ao_strs_strtable+1767)
+#define zOptionPartName_LEN 17
+#define zPagedUsageExit (ao_strs_strtable+2027)
+#define zPagedUsageExit_LEN 73
+#define zTextExit (ao_strs_strtable+1976)
+#define zTextExit_LEN 50
+extern char const ao_strs_strtable[6265];
+
+#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..5c3e6a2
--- /dev/null
+++ b/autoopts/ao_string_tokenize.3
@@ -0,0 +1,86 @@
+.TH ao_string_tokenize 3 2012-08-11 "" "Programmer's Manual"
+.\" DO NOT EDIT THIS FILE (ao_string_tokenize.3)
+.\"
+.\" It has been AutoGen-ed August 11, 2012 at 09:44:56 AM by AutoGen 5.16.2
+.\" 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 <stdlib.h>
+ 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), optionNextValue(3), optionOnlyUsage(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), pathfind(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..f02c868
--- /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-2012 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 md5sums:
+
+ 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+ 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+ 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/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..f600e3f
--- /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 August 11, 2012 at 09:41:23 AM by AutoGen 5.16.2pre7
+\" From the definitions aoconf.def
+\" and the template file aoconf.tpl
+\"
+.TH autoopts-config 1 2012-08-11 "" "Programmer's Manual"
+.SH NAME
+autoopts-config \- script to get information about installed version of
+autoopts
+.SH SYNOPSIS
+.B autoopts-config
+.B { <value-name> [...] | 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 preceeded 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 <bkorb@gnu.org>.
+.br
+Bruce Korb <bkorb@gnu.org> and
+.br
+Luca Filipozzi <lfilipoz@debian.org>
+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..177cdd4
--- /dev/null
+++ b/autoopts/autoopts-config.in
@@ -0,0 +1,114 @@
+#! @CONFIG_SHELL@
+## ---------------------------------------------------------------------
+## autoopts-config.in -- Describe AutoOpts configuration
+##
+## Autoopts Copyright (c) 1992-2012 by Bruce Korb
+##
+## DO NOT EDIT THIS FILE (autoopts-config.in)
+##
+## It has been AutoGen-ed August 11, 2012 at 09:41:23 AM by AutoGen 5.16.2pre7
+## 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 )
+ ldopts=''
+ ldflags=-lopts
+ ;;
+
+* )
+ test -n "${ldopts}" && \
+ ldflags="${ldopts}${libdir} ${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 \<\<OPTION\>\> [ ... ]
+ 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..1eff700
--- /dev/null
+++ b/autoopts/autoopts.c
@@ -0,0 +1,729 @@
+
+/**
+ * \file autoopts.c
+ *
+ * Time-stamp: "2012-03-04 19:44:56 bkorb"
+ *
+ * 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-2012 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 md5sums:
+ *
+ * 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+ * 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+ * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
+ */
+
+#ifndef PKGDATADIR
+# define PKGDATADIR ""
+#endif
+
+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;
+
+ FILE * option_usage_fp = NULL;
+
+/* = = = START-STATIC-FORWARD = = = */
+static tSuccess
+next_opt_arg_must(tOptions * pOpts, tOptState* pOptState);
+
+static tSuccess
+next_opt_arg_may(tOptions * pOpts, tOptState * pOptState);
+
+static tSuccess
+next_opt_arg_none(tOptions * pOpts, tOptState* pOptState);
+
+static tSuccess
+next_opt(tOptions * pOpts, tOptState * pOptState);
+
+static tSuccess
+doPresets(tOptions * pOpts);
+/* = = = END-STATIC-FORWARD = = = */
+
+LOCAL void *
+ao_malloc(size_t sz)
+{
+ void * res = malloc(sz);
+ if (res == NULL) {
+ fprintf(stderr, zAO_Alloc, (int)sz);
+ exit(EXIT_FAILURE);
+ }
+ return res;
+}
+#undef malloc
+#define malloc(_s) ao_malloc(_s)
+
+LOCAL void *
+ao_realloc(void *p, size_t sz)
+{
+ void * res = (p == NULL) ? malloc(sz) : realloc(p, sz);
+ if (res == NULL) {
+ fprintf(stderr, zAO_Realloc, (int)sz, p);
+ exit(EXIT_FAILURE);
+ }
+ return res;
+}
+#undef realloc
+#define realloc(_p,_s) ao_realloc(_p,_s)
+
+LOCAL char *
+ao_strdup(char const *str)
+{
+ char * res = strdup(str);
+ if (res == NULL) {
+ fprintf(stderr, zAO_Strdup, (int)strlen(str));
+ exit(EXIT_FAILURE);
+ }
+ return res;
+}
+#undef strdup
+#define strdup(_p) ao_strdup(_p)
+
+#ifndef HAVE_PATHFIND
+# include "compat/pathfind.c"
+#endif
+
+#ifndef HAVE_SNPRINTF
+# include "compat/snprintf.c"
+#endif
+
+#ifndef HAVE_STRDUP
+# include "compat/strdup.c"
+#endif
+
+#ifndef HAVE_STRCHR
+# include "compat/strchr.c"
+#endif
+
+/*
+ * handle_opt
+ *
+ * This routine handles equivalencing, sets the option state flags and
+ * invokes the handler procedure, if any.
+ */
+LOCAL tSuccess
+handle_opt(tOptions * pOpts, tOptState* pOptState)
+{
+ /*
+ * Save a copy of the option procedure pointer.
+ * If this is an equivalence class option, we still want this proc.
+ */
+ tOptDesc* pOD = pOptState->pOD;
+ tOptProc* pOP = pOD->pOptProc;
+ if (pOD->fOptState & OPTST_ALLOC_ARG)
+ AGFREE(pOD->optArg.argString);
+
+ pOD->optArg.argString = pOptState->pzOptArg;
+
+ /*
+ * IF we are presetting options, then we will ignore any un-presettable
+ * options. They are the ones either marked as such.
+ */
+ if ( ((pOpts->fOptSet & OPTPROC_PRESETTING) != 0)
+ && ((pOD->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 pOD->optChar[0], if this is an
+ * equivalence entry.)
+ * set the pointer to the equivalence class base
+ */
+ if (pOD->optEquivIndex != NO_EQUIVALENT) {
+ tOptDesc* p = pOpts->pOptDesc + pOD->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 ((pOD->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 (p->optActualIndex != pOD->optIndex) {
+ fprintf(stderr, (char*)zMultiEquiv, p->pz_Name, pOD->pz_Name,
+ (pOpts->pOptDesc + p->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.
+ */
+ p->optActualIndex = NO_EQUIVALENT;
+ }
+
+ if (p->optActualIndex != pOD->optIndex) {
+ /*
+ * First time through, copy over the state
+ * and add in the equivalence flag
+ */
+ p->optActualValue = pOD->optValue;
+ p->optActualIndex = pOD->optIndex;
+ pOptState->flags |= OPTST_EQUIVALENCE;
+ }
+
+ /*
+ * Copy the most recent option argument. set membership state
+ * is kept in ``p->optCookie''. Do not overwrite.
+ */
+ p->optArg.argString = pOD->optArg.argString;
+ pOD = p;
+
+ } else {
+ pOD->optActualValue = pOD->optValue;
+ pOD->optActualIndex = pOD->optIndex;
+ }
+
+ pOD->fOptState &= OPTST_PERSISTENT_MASK;
+ pOD->fOptState |= (pOptState->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 ( (pOD->fOptState & OPTST_DEFINED)
+ && (++pOD->optOccCt > pOD->optMaxCt) ) {
+
+ if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0) {
+ char const * pzEqv =
+ (pOD->optEquivIndex != NO_EQUIVALENT) ? zEquiv : zNil;
+
+ fputs(zErrOnly, stderr);
+
+ if (pOD->optMaxCt > 1)
+ fprintf(stderr, zAtMost, pOD->optMaxCt, pOD->pz_Name, pzEqv);
+ else
+ fprintf(stderr, zOnlyOne, pOD->pz_Name, pzEqv);
+ }
+
+ return FAILURE;
+ }
+
+ /*
+ * If provided a procedure to call, call it
+ */
+ if (pOP != NULL)
+ (*pOP)(pOpts, pOD);
+
+ return SUCCESS;
+}
+
+static tSuccess
+next_opt_arg_must(tOptions * pOpts, tOptState* pOptState)
+{
+ /*
+ * 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 (pOptState->optType) {
+ case TOPT_SHORT:
+ /*
+ * See if an arg string follows the flag character
+ */
+ if (*++(pOpts->pzCurOpt) == NUL)
+ pOpts->pzCurOpt = pOpts->origArgVect[ pOpts->curOptIdx++ ];
+ pOptState->pzOptArg = pOpts->pzCurOpt;
+ break;
+
+ case TOPT_LONG:
+ /*
+ * See if an arg string has already been assigned (glued on
+ * with an `=' character)
+ */
+ if (pOptState->pzOptArg == NULL)
+ pOptState->pzOptArg = pOpts->origArgVect[ pOpts->curOptIdx++ ];
+ break;
+
+ default:
+#ifdef DEBUG
+ fputs("AutoOpts lib error: option type not selected\n", stderr);
+ exit(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 (pOpts->curOptIdx > pOpts->origArgCt) {
+ fprintf(stderr, zMisArg, pOpts->pzProgPath, pOptState->pOD->pz_Name);
+ return FAILURE;
+ }
+
+ pOpts->pzCurOpt = NULL; /* next time advance to next arg */
+ return SUCCESS;
+}
+
+/**
+ * Process an optional option 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 pOptState a structure for managing the current processing state
+ * @returns SUCCESS or does not return
+ */
+static tSuccess
+next_opt_arg_may(tOptions * pOpts, tOptState * pOptState)
+{
+ /*
+ * An option argument is optional.
+ */
+ switch (pOptState->optType) {
+ case TOPT_SHORT:
+ if (*++pOpts->pzCurOpt != NUL)
+ pOptState->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 == '-'))
+ pOptState->pzOptArg = NULL;
+ else {
+ pOpts->curOptIdx++; /* argument found */
+ pOptState->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 ( (pOptState->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 == '-'))
+ pOptState->pzOptArg = NULL;
+ else {
+ pOpts->curOptIdx++; /* argument found */
+ pOptState->pzOptArg = pzLA;
+ }
+ }
+ break;
+
+ default:
+ case TOPT_DEFAULT:
+ fputs(zAO_Woops, stderr );
+ exit(EX_SOFTWARE);
+ }
+
+ /*
+ * 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;
+}
+
+
+static tSuccess
+next_opt_arg_none(tOptions * pOpts, tOptState* pOptState)
+{
+ /*
+ * No option argument. Make sure next time around we find
+ * the correct option flag character for short options
+ */
+ if (pOptState->optType == TOPT_SHORT)
+ (pOpts->pzCurOpt)++;
+
+ /*
+ * It is a long option. Make sure there was no ``=xxx'' argument
+ */
+ else if (pOptState->pzOptArg != NULL) {
+ fprintf(stderr, zNoArg, pOpts->pzProgPath, pOptState->pOD->pz_Name);
+ return FAILURE;
+ }
+
+ /*
+ * It is a long option. Advance to next command line argument.
+ */
+ else
+ pOpts->pzCurOpt = NULL;
+ 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 pOpts the program option descriptor
+ * @param pOptState the state of the next found option
+ */
+static tSuccess
+next_opt(tOptions * pOpts, tOptState * pOptState)
+{
+ {
+ tSuccess res = find_opt(pOpts, pOptState);
+ if (! SUCCESSFUL(res))
+ return res;
+ }
+
+ if ( ((pOptState->flags & OPTST_DEFINED) != 0)
+ && ((pOptState->pOD->fOptState & OPTST_NO_COMMAND) != 0)) {
+ fprintf(stderr, zNotCmdOpt, pOptState->pOD->pz_Name);
+ return FAILURE;
+ }
+
+ return get_opt_arg(pOpts, pOptState);
+}
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * 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. doPresets()
+ * 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
+ */
+LOCAL tSuccess
+immediate_opts(tOptions * pOpts)
+{
+ tSuccess res;
+
+ pOpts->fOptSet |= OPTPROC_IMMEDIATE;
+ pOpts->curOptIdx = 1; /* start by skipping program name */
+ pOpts->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(pOpts, &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(pOpts, &opt_st)))
+ break;
+ } failed_option:;
+
+ if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0)
+ (*pOpts->pUsageProc)(pOpts, EXIT_FAILURE);
+
+leave:
+
+ pOpts->fOptSet &= ~OPTPROC_IMMEDIATE;
+ return res;
+}
+
+/**
+ * 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 pOpts program options descriptor
+ * @returns SUCCESS or FAILURE
+ */
+LOCAL tSuccess
+regular_opts(tOptions * pOpts)
+{
+ /* assert: pOpts->fOptSet & OPTPROC_IMMEDIATE == 0 */
+ for (;;) {
+ tOptState opt_st = OPTSTATE_INITIALIZER(DEFINED);
+
+ switch (next_opt(pOpts, &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(pOpts, &opt_st)))
+ break;
+ } failed_option:;
+
+ if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0)
+ (*pOpts->pUsageProc)(pOpts, EXIT_FAILURE);
+
+ return FAILURE;
+}
+
+
+/**
+ * check for preset values from a config files or envrionment variables
+ */
+static tSuccess
+doPresets(tOptions * pOpts)
+{
+ tOptDesc * pOD = NULL;
+
+ if (! SUCCESSFUL(immediate_opts(pOpts)))
+ 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 ( (pOpts->specOptIdx.save_opts != NO_EQUIVALENT)
+ && (pOpts->specOptIdx.save_opts != 0)) {
+ pOD = pOpts->pOptDesc + pOpts->specOptIdx.save_opts + 1;
+ if (DISABLED_OPT(pOD))
+ return SUCCESS;
+ }
+
+ /*
+ * Until we return from this procedure, disable non-presettable opts
+ */
+ pOpts->fOptSet |= OPTPROC_PRESETTING;
+ /*
+ * IF there are no config files,
+ * THEN do any environment presets and leave.
+ */
+ if (pOpts->papzHomeList == NULL) {
+ env_presets(pOpts, ENV_ALL);
+ }
+ else {
+ env_presets(pOpts, ENV_IMM);
+
+ /*
+ * Check to see if environment variables have disabled presetting.
+ */
+ if ((pOD != NULL) && ! DISABLED_OPT(pOD))
+ intern_file_load(pOpts);
+
+ /*
+ * ${PROGRAM_LOAD_OPTS} value of "no" cannot disable other environment
+ * variable options. Only the loading of .rc files.
+ */
+ env_presets(pOpts, ENV_NON_IMM);
+ }
+ pOpts->fOptSet &= ~OPTPROC_PRESETTING;
+
+ return SUCCESS;
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * 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* + 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 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 * pOpts, int argCt, char ** argVect)
+{
+ if (! SUCCESSFUL(validate_struct(pOpts, argVect[0])))
+ exit(EX_SOFTWARE);
+
+ /*
+ * Establish the real program name, the program full path,
+ * and do all the presetting the first time thru only.
+ */
+ if ((pOpts->fOptSet & OPTPROC_INITDONE) == 0) {
+ pOpts->origArgCt = (unsigned int)argCt;
+ pOpts->origArgVect = argVect;
+ pOpts->fOptSet |= OPTPROC_INITDONE;
+ if (HAS_pzPkgDataDir(pOpts))
+ program_pkgdatadir = pOpts->pzPkgDataDir;
+
+ if (! SUCCESSFUL(doPresets(pOpts)))
+ return 0;
+
+ /*
+ * 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 ( ((pOpts->fOptSet & OPTPROC_TRANSLATE) != 0)
+ && (pOpts->pTransProc != NULL)
+ && ((pOpts->fOptSet & OPTPROC_NO_XLAT_MASK)
+ == OPTPROC_NXLAT_OPT_CFG) ) {
+
+ pOpts->fOptSet &= ~OPTPROC_NXLAT_OPT_CFG;
+ (*pOpts->pTransProc)();
+ }
+
+ if ((pOpts->fOptSet & OPTPROC_REORDER) != 0)
+ optionSort(pOpts);
+
+ pOpts->curOptIdx = 1;
+ pOpts->pzCurOpt = NULL;
+ }
+
+ /*
+ * IF we are (re)starting,
+ * THEN reset option location
+ */
+ else if (pOpts->curOptIdx <= 0) {
+ pOpts->curOptIdx = 1;
+ pOpts->pzCurOpt = NULL;
+ }
+
+ if (! SUCCESSFUL(regular_opts(pOpts)))
+ return pOpts->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)
+ */
+ if ( (pOpts->specOptIdx.save_opts != NO_EQUIVALENT)
+ && (pOpts->specOptIdx.save_opts != 0)) {
+ tOptDesc* pOD = pOpts->pOptDesc + pOpts->specOptIdx.save_opts;
+
+ if (SELECTED_OPT(pOD)) {
+ optionSaveFile(pOpts);
+ exit(EXIT_SUCCESS);
+ }
+ }
+
+ /*
+ * IF we are checking for errors,
+ * THEN look for too few occurrences of required options
+ */
+ if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0) {
+ if (! is_consistent(pOpts))
+ (*pOpts->pUsageProc)(pOpts, EXIT_FAILURE);
+ }
+
+ return pOpts->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..194ea5a
--- /dev/null
+++ b/autoopts/autoopts.h
@@ -0,0 +1,335 @@
+
+/*
+ * \file autoopts.h
+ *
+ * Time-stamp: "2012-03-04 19:05:01 bkorb"
+ *
+ * This file defines all the global structures and special values
+ * used in the automated option processing library.
+ *
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+ *
+ * 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+ * 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+ * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
+ */
+
+#ifndef AUTOGEN_AUTOOPTS_H
+#define AUTOGEN_AUTOOPTS_H
+
+#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
+# 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
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+# define DIRCH '\\'
+#else
+# define DIRCH '/'
+#endif
+
+#define AO_EXIT_REQ_USAGE 64
+#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
+
+#define NL '\n'
+
+/*
+ * 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;
+#define DIRECTION_PRESET -1
+#define DIRECTION_PROCESS 1
+#define DIRECTION_CALLED 0
+
+#define PROCESSING(d) ((d)>0)
+#define PRESETTING(d) ((d)<0)
+
+/*
+ * When loading a line (or block) of text as an option, the value can
+ * be processed in any of several modes:
+ *
+ * @table @samp
+ * @item keep
+ * Every part of the value between the delimiters is saved.
+ *
+ * @item uncooked
+ * Even if the value begins with quote characters, do not do quote processing.
+ *
+ * @item cooked
+ * 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.
+ * @end table
+ */
+typedef enum {
+ OPTION_LOAD_COOKED,
+ OPTION_LOAD_UNCOOKED,
+ 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,
+ PAGER_STATE_READY,
+ 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;
+ tCC* pzOptArg;
+ tAoUL 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_
+
+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((void*)p, (size_t)c)
+#define AGFREE(_p) free((void *)_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((void *)_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 <sys/mman.h>
+#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 ((void*)-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
+
+/*
+ * 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;
+static char const * program_pkgdatadir;
+
+extern tOptProc optionPrintVersion, optionPagedUsage, optionLoadOpt;
+
+#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..718f497
--- /dev/null
+++ b/autoopts/autoopts.m4
@@ -0,0 +1,225 @@
+dnl -*- Mode: M4 -*-
+dnl --------------------------------------------------------------------
+dnl autoopts.m4 --- Configure paths for autoopts
+dnl
+dnl Author: Gary V. Vaughan <gvaughan@localhost>
+dnl Time-stamp: "2011-12-13 09:45:03 bkorb"
+dnl
+dnl This file is part of AutoOpts, a companion to AutoGen.
+dnl AutoOpts is free software.
+dnl AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+dnl
+dnl 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+dnl 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+dnl 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <autoopts/options.h>
+#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", &current, &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 <autoopts/options.h>
+#include <stdio.h>
+], [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..c16d91b
--- /dev/null
+++ b/autoopts/autoopts/options.h
@@ -0,0 +1,1110 @@
+/* -*- buffer-read-only: t -*- vi: set ro:
+ *
+ * DO NOT EDIT THIS FILE (options.h)
+ *
+ * It has been AutoGen-ed August 11, 2012 at 09:41:18 AM by AutoGen 5.16.2pre7
+ * 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-2012 by Bruce Korb
+ *
+ * * AutoOpts 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.
+ *
+ * AutoOpts is distributed in the hope that 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 <http://www.gnu.org/licenses/>.";
+ */
+#ifndef AUTOOPTS_OPTIONS_H_GUARD
+#define AUTOOPTS_OPTIONS_H_GUARD 1
+#include <sys/types.h>
+#include <stdio.h>
+
+#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 <stdint.h>
+# elif defined(HAVE_INTTYPES_H)
+# include <inttypes.h>
+# endif /* HAVE_STDINT/INTTYPES_H */
+
+# if defined(HAVE_LIMITS_H)
+# include <limits.h>
+# elif defined(HAVE_SYS_LIMITS_H)
+# include <sys/limits.h>
+# endif /* HAVE_LIMITS/SYS_LIMITS_H */
+
+# if defined(HAVE_SYSEXITS_H)
+# include <sysexits.h>
+# endif /* HAVE_SYSEXITS_H */
+
+# if defined(HAVE_STDBOOL_H)
+# include <stdbool.h>
+# else
+ 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 normal 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 64
+
+/*
+ * 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.
+ */
+#define OPTIONS_STRUCT_VERSION 147461
+#define OPTIONS_VERSION_STRING "36:5:11"
+#define OPTIONS_MINIMUM_VERSION 102400
+#define OPTIONS_MIN_VER_STRING "25:0:0"
+#define OPTIONS_VER_TO_NUM(_v, _r) (((_v) * 4096) + (_r))
+
+typedef enum {
+ OPARG_TYPE_NONE = 0,
+ 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 */
+} teOptArgType;
+
+typedef struct optionValue {
+ teOptArgType valType;
+ char* pzName;
+ 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;
+
+typedef enum {
+ FTYPE_MODE_MAY_EXIST = 0x00,
+ FTYPE_MODE_MUST_EXIST = 0x01,
+ FTYPE_MODE_MUST_NOT_EXIST = 0x02,
+ FTYPE_MODE_EXIST_MASK = 0x03,
+ FTYPE_MODE_NO_OPEN = 0x00,
+ FTYPE_MODE_OPEN_FD = 0x10,
+ FTYPE_MODE_FOPEN_FP = 0x20,
+ FTYPE_MODE_OPEN_MASK = 0x30
+} teOptFileType;
+
+typedef union {
+ int file_flags;
+ char const * file_mode;
+} tuFileMode;
+
+typedef struct argList tArgList;
+#define MIN_ARG_ALLOC_CT 6
+#define INCR_ARG_ALLOC_CT 8
+struct argList {
+ int useCt;
+ int allocCt;
+ char const * apzArgs[MIN_ARG_ALLOC_CT];
+};
+
+/*
+ * Bits in the fOptState option descriptor field.
+ */
+typedef enum {
+ OPTST_SET_ID = 0, /* Set via the "SET_OPT()" macro */
+ OPTST_PRESET_ID = 1, /* Set via an RC/INI file */
+ OPTST_DEFINED_ID = 2, /* Set via a command line option */
+ OPTST_RESET_ID = 3, /* Reset via command line option */
+ OPTST_EQUIVALENCE_ID = 4, /* selected by equiv'ed option */
+ OPTST_DISABLED_ID = 5, /* option is in disabled state */
+ OPTST_ALLOC_ARG_ID = 6, /* pzOptArg was allocated */
+ OPTST_NO_INIT_ID = 8, /* option cannot be preset */
+ OPTST_NUMBER_OPT_ID = 9, /* opt value (flag) is any digit */
+ OPTST_STACKED_ID = 10, /* opt uses optionStackArg proc */
+ OPTST_INITENABLED_ID = 11, /* option defaults to enabled */
+ OPTST_ARG_TYPE_1_ID = 12, /* bit 1 of arg type enum */
+ OPTST_ARG_TYPE_2_ID = 13, /* bit 2 of arg type enum */
+ OPTST_ARG_TYPE_3_ID = 14, /* bit 3 of arg type enum */
+ OPTST_ARG_TYPE_4_ID = 15, /* bit 4 of arg type enum */
+ OPTST_ARG_OPTIONAL_ID = 16, /* the option arg not required */
+ OPTST_IMM_ID = 17, /* process opt on first pass */
+ OPTST_DISABLE_IMM_ID = 18, /* process disablement immed. */
+ OPTST_OMITTED_ID = 19, /* compiled out of program */
+ OPTST_MUST_SET_ID = 20, /* must be set or pre-set */
+ OPTST_DOCUMENT_ID = 21, /* opt is for doc only */
+ OPTST_TWICE_ID = 22, /* process opt twice - imm + reg */
+ OPTST_DISABLE_TWICE_ID = 23, /* process disabled option twice */
+ OPTST_SCALED_NUM_ID = 24, /* scaled integer value */
+ OPTST_NO_COMMAND_ID = 25, /* disable from cmd line */
+ OPTST_DEPRECATED_ID = 26, /* support is being removed */
+ OPTST_ALIAS_ID = 27 /* alias for other option */
+} opt_state_enum_t;
+
+#define OPTST_INIT 0U
+#define OPTST_SET (1U << OPTST_SET_ID)
+#define OPTST_PRESET (1U << OPTST_PRESET_ID)
+#define OPTST_DEFINED (1U << OPTST_DEFINED_ID)
+#define OPTST_RESET (1U << OPTST_RESET_ID)
+#define OPTST_EQUIVALENCE (1U << OPTST_EQUIVALENCE_ID)
+#define OPTST_DISABLED (1U << OPTST_DISABLED_ID)
+#define OPTST_ALLOC_ARG (1U << OPTST_ALLOC_ARG_ID)
+#define OPTST_NO_INIT (1U << OPTST_NO_INIT_ID)
+#define OPTST_NUMBER_OPT (1U << OPTST_NUMBER_OPT_ID)
+#define OPTST_STACKED (1U << OPTST_STACKED_ID)
+#define OPTST_INITENABLED (1U << OPTST_INITENABLED_ID)
+#define OPTST_ARG_TYPE_1 (1U << OPTST_ARG_TYPE_1_ID)
+#define OPTST_ARG_TYPE_2 (1U << OPTST_ARG_TYPE_2_ID)
+#define OPTST_ARG_TYPE_3 (1U << OPTST_ARG_TYPE_3_ID)
+#define OPTST_ARG_TYPE_4 (1U << OPTST_ARG_TYPE_4_ID)
+#define OPTST_ARG_OPTIONAL (1U << OPTST_ARG_OPTIONAL_ID)
+#define OPTST_IMM (1U << OPTST_IMM_ID)
+#define OPTST_DISABLE_IMM (1U << OPTST_DISABLE_IMM_ID)
+#define OPTST_OMITTED (1U << OPTST_OMITTED_ID)
+#define OPTST_MUST_SET (1U << OPTST_MUST_SET_ID)
+#define OPTST_DOCUMENT (1U << OPTST_DOCUMENT_ID)
+#define OPTST_TWICE (1U << OPTST_TWICE_ID)
+#define OPTST_DISABLE_TWICE (1U << OPTST_DISABLE_TWICE_ID)
+#define OPTST_SCALED_NUM (1U << OPTST_SCALED_NUM_ID)
+#define OPTST_NO_COMMAND (1U << OPTST_NO_COMMAND_ID)
+#define OPTST_DEPRECATED (1U << OPTST_DEPRECATED_ID)
+#define OPTST_ALIAS (1U << OPTST_ALIAS_ID)
+#define OPT_STATE_MASK 0x0FFFFF7FU
+
+#define OPTST_SET_MASK ( \
+ OPTST_DEFINED | OPTST_PRESET | OPTST_RESET | \
+ OPTST_SET \
+ /* 0x0000000FU */ )
+
+#define OPTST_MUTABLE_MASK ( \
+ OPTST_ALLOC_ARG | OPTST_DEFINED | \
+ OPTST_DISABLED | OPTST_EQUIVALENCE | \
+ OPTST_PRESET | OPTST_RESET | \
+ OPTST_SET \
+ /* 0x0000007FU */ )
+
+#define OPTST_SELECTED_MASK ( \
+ OPTST_DEFINED | OPTST_SET \
+ /* 0x00000005U */ )
+
+#define OPTST_ARG_TYPE_MASK ( \
+ OPTST_ARG_TYPE_1 | OPTST_ARG_TYPE_2 | OPTST_ARG_TYPE_3 | \
+ OPTST_ARG_TYPE_4 \
+ /* 0x0000F000U */ )
+
+#define OPTST_NO_USAGE_MASK ( \
+ OPTST_DEPRECATED | OPTST_NO_COMMAND | OPTST_OMITTED \
+ /* 0x06080000U */ )
+
+#define OPTST_IMMUTABLE_MASK ( \
+ OPTST_DOCUMENT | OPTST_OMITTED \
+ /* 0x00280000U */ )
+
+#define OPTST_DO_NOT_SAVE_MASK ( \
+ OPTST_DOCUMENT | OPTST_NO_INIT | OPTST_OMITTED \
+ /* 0x00280100U */ )
+
+#define OPTST_NO_OUTPUT_MASK ( \
+ OPTST_ALIAS | OPTST_DOCUMENT | OPTST_OMITTED \
+ /* 0x08280000U */ )
+
+#ifdef NO_OPTIONAL_OPT_ARGS
+# undef OPTST_ARG_OPTIONAL
+# define OPTST_ARG_OPTIONAL 0
+#endif
+
+#define VENDOR_OPTION_VALUE 'W'
+
+#define OPTST_PERSISTENT_MASK (~OPTST_MUTABLE_MASK)
+
+#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_1_ID)
+#define OPTST_GET_ARGTYPE(_f) (((_f)&OPTST_ARG_TYPE_MASK)>>OPTST_ARG_TYPE_1_ID)
+
+/*
+ * 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
+ */
+typedef enum {
+ OPTPROC_LONGOPT_ID = 0, /* Process long style options */
+ OPTPROC_SHORTOPT_ID = 1, /* Process short style "flags" */
+ OPTPROC_ERRSTOP_ID = 2, /* Stop on argument errors */
+ OPTPROC_DISABLEDOPT_ID = 3, /* Current option is disabled */
+ OPTPROC_NO_REQ_OPT_ID = 4, /* no options are required */
+ OPTPROC_NUM_OPT_ID = 5, /* there is a number option */
+ OPTPROC_INITDONE_ID = 6, /* have inits been done? */
+ OPTPROC_NEGATIONS_ID = 7, /* any negation options? */
+ OPTPROC_ENVIRON_ID = 8, /* check environment? */
+ OPTPROC_NO_ARGS_ID = 9, /* Disallow remaining arguments */
+ OPTPROC_ARGS_REQ_ID = 10, /* Require args after options */
+ OPTPROC_REORDER_ID = 11, /* reorder operands after opts */
+ OPTPROC_GNUUSAGE_ID = 12, /* emit usage in GNU style */
+ OPTPROC_TRANSLATE_ID = 13, /* Translate strings in tOptions */
+ OPTPROC_MISUSE_ID = 14, /* no usage on usage error */
+ OPTPROC_IMMEDIATE_ID = 15, /* immediate options active */
+ OPTPROC_NXLAT_OPT_CFG_ID = 16, /* suppress for config only */
+ OPTPROC_NXLAT_OPT_ID = 17, /* suppress xlation always */
+ OPTPROC_VENDOR_OPT_ID = 18, /* vendor options active */
+ OPTPROC_PRESETTING_ID = 19 /* opt processing in preset state */
+} optproc_state_enum_t;
+
+#define OPTPROC_NONE 0U
+#define OPTPROC_LONGOPT (1U << OPTPROC_LONGOPT_ID)
+#define OPTPROC_SHORTOPT (1U << OPTPROC_SHORTOPT_ID)
+#define OPTPROC_ERRSTOP (1U << OPTPROC_ERRSTOP_ID)
+#define OPTPROC_DISABLEDOPT (1U << OPTPROC_DISABLEDOPT_ID)
+#define OPTPROC_NO_REQ_OPT (1U << OPTPROC_NO_REQ_OPT_ID)
+#define OPTPROC_NUM_OPT (1U << OPTPROC_NUM_OPT_ID)
+#define OPTPROC_INITDONE (1U << OPTPROC_INITDONE_ID)
+#define OPTPROC_NEGATIONS (1U << OPTPROC_NEGATIONS_ID)
+#define OPTPROC_ENVIRON (1U << OPTPROC_ENVIRON_ID)
+#define OPTPROC_NO_ARGS (1U << OPTPROC_NO_ARGS_ID)
+#define OPTPROC_ARGS_REQ (1U << OPTPROC_ARGS_REQ_ID)
+#define OPTPROC_REORDER (1U << OPTPROC_REORDER_ID)
+#define OPTPROC_GNUUSAGE (1U << OPTPROC_GNUUSAGE_ID)
+#define OPTPROC_TRANSLATE (1U << OPTPROC_TRANSLATE_ID)
+#define OPTPROC_MISUSE (1U << OPTPROC_MISUSE_ID)
+#define OPTPROC_IMMEDIATE (1U << OPTPROC_IMMEDIATE_ID)
+#define OPTPROC_NXLAT_OPT_CFG (1U << OPTPROC_NXLAT_OPT_CFG_ID)
+#define OPTPROC_NXLAT_OPT (1U << OPTPROC_NXLAT_OPT_ID)
+#define OPTPROC_VENDOR_OPT (1U << OPTPROC_VENDOR_OPT_ID)
+#define OPTPROC_PRESETTING (1U << OPTPROC_PRESETTING_ID)
+#define OPTPROC_STATE_MASK 0x000FFFFFU
+
+#define OPTPROC_NO_XLAT_MASK ( \
+ OPTPROC_NXLAT_OPT | OPTPROC_NXLAT_OPT_CFG \
+ /* 0x00030000U */ )
+
+#define STMTS(s) do { s; } while (false)
+
+/*
+ * The following must be #defined instead of typedef-ed
+ * because "static const" cannot both be applied to a type,
+ * tho each individually can...so they all are
+ */
+#define tSCC static char const
+#define tCC char const
+#define tAoSC static char
+#define tAoUC unsigned char
+#define tAoUI unsigned int
+#define tAoUL unsigned long
+#define tAoUS unsigned short
+
+/*
+ * It is so disgusting that there must be so many ways
+ * of specifying TRUE and FALSE.
+ */
+typedef enum { AG_FALSE = 0, AG_TRUE } ag_bool;
+
+/*
+ * Define a structure that describes each option and
+ * a pointer to the procedure that handles it.
+ * The argument is the count of this flag previously seen.
+ */
+typedef struct options tOptions;
+typedef struct optDesc tOptDesc;
+typedef struct optNames tOptNames;
+#define OPTPROC_EMIT_USAGE ((tOptions *)0x01UL)
+#define OPTPROC_EMIT_SHELL ((tOptions *)0x02UL)
+#define OPTPROC_RETURN_VALNAME ((tOptions *)0x03UL)
+#define OPTPROC_EMIT_LIMIT ((tOptions *)0x0FUL)
+
+/*
+ * The option procedures do the special processing for each
+ * option flag that needs it.
+ */
+typedef void (tOptProc)(tOptions* pOpts, tOptDesc* pOptDesc);
+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);
+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
+#define OPTION_LIMIT SHRT_MAX
+#define NO_EQUIVALENT (OPTION_LIMIT+1)
+
+typedef union {
+ char const * argString;
+ uintptr_t argEnum;
+ uintptr_t argIntptr;
+ long argInt;
+ unsigned long argUint;
+ unsigned int argBool;
+ FILE * argFp;
+ int argFd;
+} optArgBucket_t;
+
+#define pzLastArg optArg.argString
+
+/*
+ * Descriptor structure for each option.
+ * Only the fields marked "PUBLIC" are for public use.
+ */
+struct optDesc {
+ tAoUS const optIndex; /* PUBLIC */
+ tAoUS const optValue; /* PUBLIC */
+ tAoUS optActualIndex; /* PUBLIC */
+ tAoUS optActualValue; /* PUBLIC */
+
+ tAoUS const optEquivIndex; /* PUBLIC */
+ tAoUS const optMinCt;
+ tAoUS const optMaxCt;
+ tAoUS optOccCt; /* PUBLIC */
+
+ tAoUI fOptState; /* PUBLIC */
+ tAoUI reserved;
+ optArgBucket_t optArg; /* PUBLIC */
+ void* optCookie; /* PUBLIC */
+
+ int const * const pOptMust;
+ int const * const pOptCant;
+ tpOptProc const pOptProc;
+ char const* const pzText;
+
+ char const* const pz_NAME;
+ char const* const pz_Name;
+ char const* const pz_DisableName;
+ char const* const pz_DisablePfx;
+};
+
+/*
+ * Some options need special processing, so we store their
+ * indexes in a known place:
+ */
+typedef struct optSpecIndex tOptSpecIndex;
+struct optSpecIndex {
+ const tAoUS more_help;
+ const tAoUS save_opts;
+ const tAoUS number_option;
+ const tAoUS default_opt;
+};
+
+/*
+ * 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;
+ unsigned int origArgCt;
+ char** origArgVect;
+ unsigned int fOptSet;
+ unsigned int curOptIdx;
+ char* pzCurOpt;
+
+ char const* const pzProgPath; /* PUBLIC */
+ char const* const pzProgName; /* PUBLIC */
+ char const* const pzPROGNAME; /* PUBLIC */
+ char const* const pzRcName; /* PUBLIC */
+ char const* const pzCopyright; /* PUBLIC */
+ char const* const pzCopyNotice; /* PUBLIC */
+ char const* const pzFullVersion; /* PUBLIC */
+ char const* const* const papzHomeList;
+ char const* const pzUsageTitle;
+ char const* const pzExplain;
+ char const* const pzDetail;
+ tOptDesc* const pOptDesc; /* PUBLIC */
+ char const* const pzBugAddr; /* PUBLIC */
+
+ void* pExtensions;
+ void* pSavedState;
+
+ // coverity[+kill]
+ tpUsageProc pUsageProc;
+ tOptionXlateProc* pTransProc;
+
+ tOptSpecIndex specOptIdx;
+ int const optCt;
+ int const presetOptCt;
+ char const * pzFullUsage;
+ char const * pzShortUsage;
+ /* PUBLIC: */
+ optArgBucket_t const * const originalOptArgArray;
+ void * const * const originalOptArgCookie;
+ char const * const pzPkgDataDir;
+ char const * const pzPackager;
+};
+
+/*
+ * Versions where in various fields first appear:
+ * ($AO_CURRENT * 4096 + $AO_REVISION, but $AO_REVISION must be zero)
+ */
+#define originalOptArgArray_STRUCT_VERSION 131072 /* AO_CURRENT = 32 */
+#define HAS_originalOptArgArray(_opt) \
+ ((_opt)->structVersion >= originalOptArgArray_STRUCT_VERSION)
+
+#define pzPkgDataDir_STRUCT_VERSION 139264 /* AO_CURRENT = 34 */
+#define HAS_pzPkgDataDir(_opt) \
+ ((_opt)->structVersion >= pzPkgDataDir_STRUCT_VERSION)
+
+/*
+ * "token list" structure returned by "string_tokenize()"
+ */
+typedef struct {
+ unsigned long tkn_ct;
+ unsigned char* tkn_list[1];
+} 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;
+
+#define TEXT_MMAP_FAILED_ADDR(a) ((void*)(a) == (void*)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:
+ */
+
+/* From: tokenize.c line 164
+ *
+ * ao_string_tokenize - tokenize an input string
+ *
+ * Arguments:
+ * string 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 @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.
+ */
+extern token_list_t* ao_string_tokenize(char const*);
+
+
+/* From: configfile.c line 77
+ *
+ * configFileLoad - parse a configuration file
+ *
+ * Arguments:
+ * pzFile the file to load
+ *
+ * Returns: const tOptionValue* - An allocated, compound value structure
+ *
+ * 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()}.
+ */
+extern const tOptionValue* configFileLoad(char const*);
+
+
+/* From: configfile.c line 1066
+ *
+ * optionFileLoad - Load the locatable config files, in order
+ *
+ * Arguments:
+ * pOpts program options descriptor
+ * pzProg 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 @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.
+ */
+extern int optionFileLoad(tOptions*, char const*);
+
+
+/* From: configfile.c line 211
+ *
+ * optionFindNextValue - find a hierarcicaly valued option instance
+ *
+ * Arguments:
+ * pOptDesc an option with a nested arg type
+ * pPrevVal the last entry
+ * name name of value to find
+ * value the matching value
+ *
+ * Returns: const tOptionValue* - a compound value structure
+ *
+ * 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.
+ */
+extern const tOptionValue* optionFindNextValue(const tOptDesc*, const tOptionValue*, char const*, char const*);
+
+
+/* From: configfile.c line 137
+ *
+ * optionFindValue - find a hierarcicaly valued option instance
+ *
+ * Arguments:
+ * pOptDesc an option with a nested arg type
+ * name name of value to find
+ * value the matching value
+ *
+ * Returns: const tOptionValue* - a compound value structure
+ *
+ * This routine will find an entry in a nested value option or configurable.
+ * It will search through the list and return a matching entry.
+ */
+extern const tOptionValue* optionFindValue(const tOptDesc*, char const*, char const*);
+
+
+/* From: restore.c line 166
+ *
+ * optionFree - free allocated option processing memory
+ *
+ * Arguments:
+ * pOpts program options descriptor
+ *
+ * AutoOpts sometimes allocates memory and puts pointers to it in the
+ * option state structures. This routine deallocates all such memory.
+ */
+extern void optionFree(tOptions*);
+
+
+/* From: configfile.c line 280
+ *
+ * optionGetValue - get a specific value from a hierarcical list
+ *
+ * Arguments:
+ * pOptValue a hierarchcal value
+ * valueName name of value to get
+ *
+ * Returns: const tOptionValue* - a compound value structure
+ *
+ * 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.
+ */
+extern const tOptionValue* optionGetValue(const tOptionValue*, char const*);
+
+
+/* From: load.c line 478
+ *
+ * optionLoadLine - process a string for an option name and value
+ *
+ * Arguments:
+ * opts program options descriptor
+ * line 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 (@pxref{basic expression}),
+ * except that you may not use backquotes.
+ */
+extern void optionLoadLine(tOptions*, char const*);
+
+
+/* From: configfile.c line 340
+ *
+ * optionNextValue - get the next value from a hierarchical list
+ *
+ * Arguments:
+ * pOptValue a hierarchcal list value
+ * pOldValue a value from this list
+ *
+ * Returns: const tOptionValue* - a compound value structure
+ *
+ * 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()}".
+ */
+extern const tOptionValue* optionNextValue(const tOptionValue*, const tOptionValue*);
+
+
+/* From: usage.c line 201
+ *
+ * optionOnlyUsage - Print usage text for just the options
+ *
+ * Arguments:
+ * pOpts program options descriptor
+ * ex_code 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.
+ */
+extern void optionOnlyUsage(tOptions*, int);
+
+
+/* From: autoopts.c line 607
+ *
+ * optionProcess - this is the main option processing routine
+ *
+ * Arguments:
+ * pOpts program options descriptor
+ * argc program arg count
+ * argv 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
+ * @emph{not} be counted among the processed arguments. A hyphen by itself
+ * is treated as an operand. Encountering an operand stops option
+ * processing.
+ */
+extern int optionProcess(tOptions*, int, char**);
+
+
+/* From: restore.c line 123
+ *
+ * optionRestore - restore option state from memory copy
+ *
+ * Arguments:
+ * pOpts 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.
+ */
+extern void optionRestore(tOptions*);
+
+
+/* From: save.c line 648
+ *
+ * optionSaveFile - saves the option state to a file
+ *
+ * Arguments:
+ * pOpts 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 @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
+ */
+extern void optionSaveFile(tOptions*);
+
+
+/* From: restore.c line 71
+ *
+ * optionSaveState - saves the option state to memory
+ *
+ * Arguments:
+ * pOpts 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.
+ */
+extern void optionSaveState(tOptions*);
+
+
+/* From: nested.c line 563
+ *
+ * optionUnloadNested - Deallocate the memory for a nested value
+ *
+ * Arguments:
+ * pOptVal the hierarchical 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}).
+ */
+extern void optionUnloadNested(tOptionValue const *);
+
+
+/* From: version.c line 31
+ *
+ * optionVersion - return the compiled AutoOpts version number
+ *
+ * Returns: char const* - the version string in constant memory
+ *
+ * Returns the full version string compiled into the library.
+ * The returned string cannot be modified.
+ */
+extern char const* optionVersion(void);
+
+
+/* From: ../compat/pathfind.c line 29
+ *
+ * pathfind - fild a file in a list of directories
+ *
+ * Arguments:
+ * path colon separated list of search directories
+ * file the name of the file to look for
+ * mode the mode bits that must be set to match
+ *
+ * Returns: char* - the path to the located file
+ *
+ * the pathfind function is available only if HAVE_PATHFIND is not defined
+ *
+ * pathfind looks for a a file with name "FILE" and "MODE" access
+ * along colon delimited "PATH", and returns the full pathname as a
+ * string, or NULL if not found. If "FILE" contains a slash, then
+ * it is treated as a relative or absolute path and "PATH" is ignored.
+ *
+ * @strong{NOTE}: this function is compiled into @file{libopts} only if
+ * it is not natively supplied.
+ *
+ * The "MODE" argument is a string of option letters chosen from the
+ * list below:
+ * @example
+ * Letter Meaning
+ * r readable
+ * w writable
+ * x executable
+ * f normal file (NOT IMPLEMENTED)
+ * b block special (NOT IMPLEMENTED)
+ * c character special (NOT IMPLEMENTED)
+ * d directory (NOT IMPLEMENTED)
+ * p FIFO (pipe) (NOT IMPLEMENTED)
+ * u set user ID bit (NOT IMPLEMENTED)
+ * g set group ID bit (NOT IMPLEMENTED)
+ * k sticky bit (NOT IMPLEMENTED)
+ * s size nonzero (NOT IMPLEMENTED)
+ * @end example
+ */
+#ifndef HAVE_PATHFIND
+extern char* pathfind(char const*, char const*, char const*);
+#endif /* HAVE_PATHFIND */
+
+
+/* From: streqvcmp.c line 209
+ *
+ * strequate - map a list of characters to the same value
+ *
+ * Arguments:
+ * ch_list 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.
+ */
+extern void strequate(char const*);
+
+
+/* From: streqvcmp.c line 119
+ *
+ * streqvcmp - compare two strings with an equivalence mapping
+ *
+ * Arguments:
+ * str1 first string
+ * str2 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.
+ */
+extern int streqvcmp(char const*, char const*);
+
+
+/* From: streqvcmp.c line 156
+ *
+ * streqvmap - Set the character mappings for the streqv functions
+ *
+ * Arguments:
+ * From Input character
+ * To Mapped-to character
+ * ct compare length
+ *
+ * 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.
+ */
+extern void streqvmap(char, char, int);
+
+
+/* From: streqvcmp.c line 78
+ *
+ * strneqvcmp - compare two strings with an equivalence mapping
+ *
+ * Arguments:
+ * str1 first string
+ * str2 second string
+ * ct 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 @code{ct} bytes.
+ * This function name is mapped to option_strneqvcmp so as to not conflict
+ * with the POSIX name space.
+ */
+extern int strneqvcmp(char const*, char const*, int);
+
+
+/* From: streqvcmp.c line 235
+ *
+ * strtransform - convert a string into its mapped-to value
+ *
+ * Arguments:
+ * dest output string
+ * src 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.
+ */
+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 optionPrintVersion(tOptions*, tOptDesc*);
+
+extern void optionPutShell(tOptions*);
+
+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..0200b84
--- /dev/null
+++ b/autoopts/autoopts/usage-txt.h
@@ -0,0 +1,435 @@
+/* -*- buffer-read-only: t -*- vi: set ro:
+ *
+ * DO NOT EDIT THIS FILE (usage-txt.h)
+ *
+ * It has been AutoGen-ed August 11, 2012 at 09:41:15 AM by AutoGen 5.16.2pre7
+ * From the definitions usage-txt.def
+ * and the template file usage-txt.tpl
+ *
+ * This file handles all the bookkeeping required for tracking all the little
+ * tiny strings used by the AutoOpts library. There are 146
+ * 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.
+ *
+ * Copyright (C) 1992-2012 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 3 or later
+ * <http://gnu.org/licenses/lgpl.html>
+ *
+ * AutoOpts 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.
+ *
+ * AutoOpts is distributed in the hope that 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 <http://www.gnu.org/licenses/>.";
+ */
+#ifndef AUTOOPTS_USAGE_TXT_H_GUARD
+#define AUTOOPTS_USAGE_TXT_H_GUARD 1
+
+#undef cch_t
+#define cch_t char const
+
+/*
+ * One structure to hold all the pointers to all the stringlets.
+ */
+typedef struct {
+ int field_ct;
+ char* utpz_GnuBoolArg;
+ char* utpz_GnuKeyArg;
+ char* utpz_GnuFileArg;
+ char* utpz_GnuKeyLArg;
+ char* utpz_GnuTimeArg;
+ char* utpz_GnuNumArg;
+ char* utpz_GnuStrArg;
+ cch_t* apz_str[ 139 ];
+} usage_text_t;
+
+/*
+ * Declare the global structure with all the pointers to translated
+ * strings. This is then used by the usage generation procedure.
+ */
+extern usage_text_t option_usage_text;
+
+#if defined(AUTOOPTS_INTERNAL) /* DEFINE ALL THE STRINGS = = = = = */
+/*
+ * Provide a mapping from a short name to fields in this structure.
+ */
+#define zAO_Alloc (option_usage_text.apz_str[ 0])
+#define zAO_Bad (option_usage_text.apz_str[ 1])
+#define zAO_Big (option_usage_text.apz_str[ 2])
+#define zAO_Err (option_usage_text.apz_str[ 3])
+#define zAO_Realloc (option_usage_text.apz_str[ 4])
+#define zAO_Sml (option_usage_text.apz_str[ 5])
+#define zAO_Strdup (option_usage_text.apz_str[ 6])
+#define zAO_Ver (option_usage_text.apz_str[ 7])
+#define zAO_Woops (option_usage_text.apz_str[ 8])
+#define zAliasRange (option_usage_text.apz_str[ 9])
+#define zAll (option_usage_text.apz_str[ 10])
+#define zAlt (option_usage_text.apz_str[ 11])
+#define zAmbigKey (option_usage_text.apz_str[ 12])
+#define zAmbigList (option_usage_text.apz_str[ 13])
+#define zAmbigOptStr (option_usage_text.apz_str[ 14])
+#define zAmbiguous (option_usage_text.apz_str[ 15])
+#define zArgsMust (option_usage_text.apz_str[ 16])
+#define zAtMost (option_usage_text.apz_str[ 17])
+#define zAuto (option_usage_text.apz_str[ 18])
+#define zBadPipe (option_usage_text.apz_str[ 19])
+#define zBadVerArg (option_usage_text.apz_str[ 20])
+#define zCantFmt (option_usage_text.apz_str[ 21])
+#define zCantSave (option_usage_text.apz_str[ 22])
+#define zCfgAO_Flags (option_usage_text.apz_str[ 23])
+#define zCfgProg (option_usage_text.apz_str[ 24])
+#define zDefaultOpt (option_usage_text.apz_str[ 25])
+#define zDis (option_usage_text.apz_str[ 26])
+#define zDisabledErr (option_usage_text.apz_str[ 27])
+#define zDisabledOpt (option_usage_text.apz_str[ 28])
+#define zDisabledWhy (option_usage_text.apz_str[ 29])
+#define zEnab (option_usage_text.apz_str[ 30])
+#define zEquiv (option_usage_text.apz_str[ 31])
+#define zErrOnly (option_usage_text.apz_str[ 32])
+#define zExamineFmt (option_usage_text.apz_str[ 33])
+#define zFiveSpaces (option_usage_text.apz_str[ 34])
+#define zFlagOkay (option_usage_text.apz_str[ 35])
+#define zFmtFmt (option_usage_text.apz_str[ 36])
+#define zForkFail (option_usage_text.apz_str[ 37])
+#define zFreopenFail (option_usage_text.apz_str[ 38])
+#define zFSErrOptLoad (option_usage_text.apz_str[ 39])
+#define zFSErrReadFile (option_usage_text.apz_str[ 40])
+#define zFSOptError (option_usage_text.apz_str[ 41])
+#define zFSOptErrMayExist (option_usage_text.apz_str[ 42])
+#define zFSOptErrMustExist (option_usage_text.apz_str[ 43])
+#define zFSOptErrNoExist (option_usage_text.apz_str[ 44])
+#define zFSOptErrOpen (option_usage_text.apz_str[ 45])
+#define zFSOptErrFopen (option_usage_text.apz_str[ 46])
+#define zFileCannotExist (option_usage_text.apz_str[ 47])
+#define zFileMustExist (option_usage_text.apz_str[ 48])
+#define zGenshell (option_usage_text.apz_str[ 49])
+#define zGnuBoolArg (option_usage_text.utpz_GnuBoolArg)
+#define zGnuBreak (option_usage_text.apz_str[ 50])
+#define zGnuKeyArg (option_usage_text.utpz_GnuKeyArg)
+#define zGnuFileArg (option_usage_text.utpz_GnuFileArg)
+#define zGnuKeyLArg (option_usage_text.utpz_GnuKeyLArg)
+#define zGnuTimeArg (option_usage_text.utpz_GnuTimeArg)
+#define zGnuNestArg (option_usage_text.apz_str[ 51])
+#define zGnuNumArg (option_usage_text.utpz_GnuNumArg)
+#define zGnuOptArg (option_usage_text.apz_str[ 52])
+#define zGnuOptFmt (option_usage_text.apz_str[ 53])
+#define zGnuStrArg (option_usage_text.utpz_GnuStrArg)
+#define zIllOptChr (option_usage_text.apz_str[ 54])
+#define zIllOptStr (option_usage_text.apz_str[ 55])
+#define zIllVendOptStr (option_usage_text.apz_str[ 56])
+#define zIntRange (option_usage_text.apz_str[ 57])
+#define zInvalOptDesc (option_usage_text.apz_str[ 58])
+#define zInvalOptName (option_usage_text.apz_str[ 59])
+#define zLowerBits (option_usage_text.apz_str[ 60])
+#define zMembers (option_usage_text.apz_str[ 61])
+#define zMisArg (option_usage_text.apz_str[ 62])
+#define zMultiEquiv (option_usage_text.apz_str[ 63])
+#define zMust (option_usage_text.apz_str[ 64])
+#define zNeedOne (option_usage_text.apz_str[ 65])
+#define zNoArg (option_usage_text.apz_str[ 66])
+#define zNoArgs (option_usage_text.apz_str[ 67])
+#define zNoCreat (option_usage_text.apz_str[ 68])
+#define zNoFlags (option_usage_text.apz_str[ 69])
+#define zNoKey (option_usage_text.apz_str[ 70])
+#define zNoLim (option_usage_text.apz_str[ 71])
+#define zNoPreset (option_usage_text.apz_str[ 72])
+#define zNoResetArg (option_usage_text.apz_str[ 73])
+#define zNoRq_NoShrtTtl (option_usage_text.apz_str[ 74])
+#define zNoRq_ShrtTtl (option_usage_text.apz_str[ 75])
+#define zNoStat (option_usage_text.apz_str[ 76])
+#define zNoState (option_usage_text.apz_str[ 77])
+#define zNone (option_usage_text.apz_str[ 78])
+#define zNotDef (option_usage_text.apz_str[ 79])
+#define zNotCmdOpt (option_usage_text.apz_str[ 80])
+#define zNotEnough (option_usage_text.apz_str[ 81])
+#define zNotFile (option_usage_text.apz_str[ 82])
+#define zNotNumber (option_usage_text.apz_str[ 83])
+#define zNotDate (option_usage_text.apz_str[ 84])
+#define zNotDuration (option_usage_text.apz_str[ 85])
+#define zNrmOptFmt (option_usage_text.apz_str[ 86])
+#define zNumberOpt (option_usage_text.apz_str[ 87])
+#define zOnlyOne (option_usage_text.apz_str[ 88])
+#define zOptsOnly (option_usage_text.apz_str[ 89])
+#define zOutputFail (option_usage_text.apz_str[ 90])
+#define zPathFmt (option_usage_text.apz_str[ 91])
+#define zPlsSendBugs (option_usage_text.apz_str[ 92])
+#define zPreset (option_usage_text.apz_str[ 93])
+#define zPresetFile (option_usage_text.apz_str[ 94])
+#define zPresetIntro (option_usage_text.apz_str[ 95])
+#define zProhib (option_usage_text.apz_str[ 96])
+#define zReorder (option_usage_text.apz_str[ 97])
+#define zRange (option_usage_text.apz_str[ 98])
+#define zRangeAbove (option_usage_text.apz_str[ 99])
+#define zRangeLie (option_usage_text.apz_str[100])
+#define zRangeOnly (option_usage_text.apz_str[101])
+#define zRangeOr (option_usage_text.apz_str[102])
+#define zRangeErr (option_usage_text.apz_str[103])
+#define zRangeExact (option_usage_text.apz_str[104])
+#define zRangeScaled (option_usage_text.apz_str[105])
+#define zRangeUpto (option_usage_text.apz_str[106])
+#define zResetNotConfig (option_usage_text.apz_str[107])
+#define zReqFmt (option_usage_text.apz_str[108])
+#define zReqOptFmt (option_usage_text.apz_str[109])
+#define zReqThese (option_usage_text.apz_str[110])
+#define zReq_NoShrtTtl (option_usage_text.apz_str[111])
+#define zReq_ShrtTtl (option_usage_text.apz_str[112])
+#define zSepChars (option_usage_text.apz_str[113])
+#define zSetMemberSettings (option_usage_text.apz_str[114])
+#define zShrtGnuOptFmt (option_usage_text.apz_str[115])
+#define zSixSpaces (option_usage_text.apz_str[116])
+#define zStdBoolArg (option_usage_text.apz_str[117])
+#define zStdBreak (option_usage_text.apz_str[118])
+#define zStdFileArg (option_usage_text.apz_str[119])
+#define zStdKeyArg (option_usage_text.apz_str[120])
+#define zStdKeyLArg (option_usage_text.apz_str[121])
+#define zStdTimeArg (option_usage_text.apz_str[122])
+#define zStdNestArg (option_usage_text.apz_str[123])
+#define zStdNoArg (option_usage_text.apz_str[124])
+#define zStdNumArg (option_usage_text.apz_str[125])
+#define zStdOptArg (option_usage_text.apz_str[126])
+#define zStdReqArg (option_usage_text.apz_str[127])
+#define zStdStrArg (option_usage_text.apz_str[128])
+#define zTabHyp (option_usage_text.apz_str[129])
+#define zTabHypAnd (option_usage_text.apz_str[130])
+#define zTabout (option_usage_text.apz_str[131])
+#define zThreeSpaces (option_usage_text.apz_str[132])
+#define zTooLarge (option_usage_text.apz_str[133])
+#define zTwoSpaces (option_usage_text.apz_str[134])
+#define zUpTo (option_usage_text.apz_str[135])
+#define zValidKeys (option_usage_text.apz_str[136])
+#define zVendOptsAre (option_usage_text.apz_str[137])
+#define zVendIntro (option_usage_text.apz_str[138])
+
+ /*
+ * 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_zGnuFileArg[] = "=file";
+ static char eng_zGnuKeyLArg[] = "=Mbr";
+ static char eng_zGnuTimeArg[] = "=Tim";
+ static char eng_zGnuNumArg[] = "=num";
+ static char eng_zGnuStrArg[] = "=str";
+static char const usage_txt[4660] =
+/* 0 */ "malloc of %d bytes failed\n\0"
+/* 27 */ "AutoOpts function called without option descriptor\n\0"
+/* 79 */ "\tThis exceeds the compiled library version: \0"
+/* 125 */ "Automated Options Processing Error!\n"
+ "\t%s called AutoOpts function with structure version %d:%d:%d.\n\0"
+/* 224 */ "realloc of %d bytes at 0x%p failed\n\0"
+/* 260 */ "\tThis is less than the minimum library version: \0"
+/* 310 */ "strdup of %d byte string failed\n\0"
+/* 343 */ "Automated Options version %s\n"
+ "\tcopyright (c) 1999-2012 by Bruce Korb - all rights reserved\n\0"
+/* 434 */ "AutoOpts lib error: defaulted to option with optional arg\n\0"
+/* 493 */ "(AutoOpts bug): Aliasing option is out of range.\0"
+/* 543 */ "all\0"
+/* 547 */ "\t\t\t\t- an alternate for %s\n\0"
+/* 574 */ "%s error: the keyword `%s' is ambiguous for %s\n\0"
+/* 623 */ " The following options match:\n\0"
+/* 655 */ "%s: ambiguous option name: %s (matches %d options)\n\0"
+/* 707 */ " %s%s\n\0"
+/* 715 */ "%s: Command line arguments required\n\0"
+/* 752 */ "%d %s%s options allowed\n\0"
+/* 777 */ "version, usage and configuration options:\0"
+/* 819 */ "Error %d (%s) from the pipe(2) syscall\n\0"
+/* 859 */ "ERROR: version option argument '%c' invalid. Use:\n"
+ "\t'v' - version only\n"
+ "\t'c' - version and copyright\n"
+ "\t'n' - version and copyright notice\n\0"
+/* 996 */ "ERROR: %s option conflicts with the %s option\n\0"
+/* 1044 */ "%s(optionSaveState): error: cannot allocate %d bytes\n\0"
+/* 1098 */ "auto-options\0"
+/* 1111 */ "program\0"
+/* 1119 */ "\t\t\t\t- default option for unnamed options\n\0"
+/* 1161 */ "\t\t\t\t- disabled as --%s\n\0"
+/* 1185 */ "%s: The ``%s'' option has been disabled\0"
+/* 1225 */ " --- %-14s %s\n\0"
+/* 1240 */ "This option has been disabled\0"
+/* 1270 */ "\t\t\t\t- enabled by default\n\0"
+/* 1296 */ "-equivalence\0"
+/* 1309 */ "ERROR: only \0"
+/* 1323 */ " - examining environment variables named %s_*\n\0"
+/* 1370 */ " \0"
+/* 1376 */ "Options are specified by doubled hyphens and their name or by a single\n"
+ "hyphen and the flag character.\n\0"
+/* 1479 */ "%%-%ds %%s\n\0"
+/* 1491 */ "fs error %d (%s) on fork - cannot obtain %s usage\n\0"
+/* 1542 */ "fs error %d (%s) on freopen\n\0"
+/* 1571 */ "File error %d (%s) opening %s for loading options\n\0"
+/* 1622 */ "fs error %d (%s) reading file %s\n\0"
+/* 1656 */ "fs error %d (%s) on %s %s for option %s\n\0"
+/* 1697 */ "stat-ing for directory\0"
+/* 1720 */ "stat-ing for regular file\0"
+/* 1746 */ "stat-ing for non-existant file\0"
+/* 1777 */ "open-ing file\0"
+/* 1791 */ "fopen-ing file\0"
+/* 1806 */ "\t\t\t\t- file must not pre-exist\n\0"
+/* 1837 */ "\t\t\t\t- file must pre-exist\n\0"
+/* 1864 */ "\n"
+ "= = = = = = = =\n\n"
+ "This incarnation of genshell will produce\n"
+ "a shell script to parse the options for %s:\n\n\0"
+/* 1970 */ "\n"
+ "%s\n\n\0"
+/* 1976 */ "=Cplx\0"
+/* 1982 */ "[=arg]\0"
+/* 1989 */ "--%2$s%1$s\0"
+/* 2000 */ "%s: illegal option -- %c\n\0"
+/* 2026 */ "%s: illegal option -- %s\n\0"
+/* 2052 */ "%s: unknown vendor extension option -- %s\n\0"
+/* 2095 */ " or an integer from %d through %d\n\0"
+/* 2131 */ "AutoOpts ERROR: invalid option descriptor for %s\n\0"
+/* 2182 */ "%s: invalid option name: %s\n\0"
+/* 2211 */ " or an integer mask with any of the lower %d bits set\n\0"
+/* 2267 */ "\t\t\t\t- is a set membership option\n\0"
+/* 2301 */ "%s: option `%s' requires an argument\n\0"
+/* 2339 */ "Equivalenced option '%s' was equivalenced to both\n"
+ "\t'%s' and '%s'\0"
+/* 2404 */ "\t\t\t\t- must appear between %d and %d times\n\0"
+/* 2447 */ "ERROR: The %s option is required\n\0"
+/* 2482 */ "%s: option `%s' cannot have an argument\n\0"
+/* 2523 */ "%s: Command line arguments not allowed\n\0"
+/* 2563 */ "error %d (%s) creating %s\n\0"
+/* 2590 */ "Options are specified by single or double hyphens and their name.\n\0"
+/* 2657 */ "%s error: `%s' does not match any %s keywords\n\0"
+/* 2705 */ "\t\t\t\t- may appear multiple times\n\0"
+/* 2738 */ "\t\t\t\t- may not be preset\n\0"
+/* 2763 */ "The 'reset-option' option requires an argument\n\0"
+/* 2811 */ " Arg Option-Name Description\n\0"
+/* 2846 */ " Flg Arg Option-Name Description\n\0"
+/* 2884 */ "error %d (%s) stat-ing %s\n\0"
+/* 2911 */ "%s(optionRestore): error: no saved option state\n\0"
+/* 2960 */ "none\0"
+/* 2965 */ "'%s' not defined\n\0"
+/* 2983 */ "'%s' is not a command line option\n\0"
+/* 3018 */ "ERROR: The %s option must appear %d times\n\0"
+/* 3062 */ "error: cannot load options from non-regular file %s\n\0"
+/* 3116 */ "%s error: `%s' is not a recognizable number\n\0"
+/* 3162 */ "%s error: `%s' is not a recognizable date/time\n\0"
+/* 3211 */ "%s error: `%s' is not a recognizable time duration\n\0"
+/* 3264 */ " %3s %s\0"
+/* 3272 */ "The '-#<number>' option may omit the hash char\n\0"
+/* 3320 */ "one %s%s option allowed\n\0"
+/* 3345 */ "All arguments are named options.\n\0"
+/* 3379 */ "Write failure to output file\0"
+/* 3408 */ " - reading file %s\0"
+/* 3427 */ "\n"
+ "please send bug reports to: %s\n\0"
+/* 3461 */ "\t\t\t\t- may NOT appear - preset only\n\0"
+/* 3497 */ "# preset/initialization file\n"
+ "# %s#\n\0"
+/* 3535 */ "\n"
+ "The following option preset mechanisms are supported:\n\0"
+/* 3591 */ "prohibits these options:\n\0"
+/* 3617 */ "Operands and options may be intermixed. They will be reordered.\n\0"
+/* 3683 */ "%s%ld to %ld\0"
+/* 3696 */ "%sgreater than or equal to %ld\0"
+/* 3727 */ "%sIt must lie in one of the ranges:\n\0"
+/* 3764 */ "%sIt must be in the range:\n\0"
+/* 3792 */ ", or\n\0"
+/* 3798 */ "%s error: %s option value %ld is out of range.\n\0"
+/* 3847 */ "%s%ld exactly\0"
+/* 3861 */ "%sis scalable with a suffix: k/K/m/M/g/G/t/T\n\0"
+/* 3907 */ "%sless than or equal to %ld\0"
+/* 3935 */ "The --reset-option has not been configured.\n\0"
+/* 3980 */ "ERROR: %s option requires the %s option\n\0"
+/* 4022 */ " %3s %-14s %s\0"
+/* 4036 */ "requires these options:\n\0"
+/* 4061 */ " Arg Option-Name Req? Description\n\0"
+/* 4101 */ " Flg Arg Option-Name Req? Description\n\0"
+/* 4144 */ "-_^\0"
+/* 4148 */ "or you may use a numeric representation. Preceding these with a '!' will\n"
+ "clear the bits, specifying 'none' will clear all bits, and 'all' will set them\n"
+ "all. Multiple entries may be passed as an option argument list.\n\0"
+/* 4367 */ "%s\0"
+/* 4370 */ " \0"
+/* 4377 */ "T/F\0"
+/* 4381 */ "\n"
+ "%s\n\n"
+ "%s\0"
+/* 4389 */ "Fil\0"
+/* 4393 */ "KWd\0"
+/* 4397 */ "Mbr\0"
+/* 4401 */ "Tim\0"
+/* 4405 */ "Cpx\0"
+/* 4409 */ "no \0"
+/* 4413 */ "Num\0"
+/* 4417 */ "opt\0"
+/* 4421 */ "YES\0"
+/* 4425 */ "Str\0"
+/* 4429 */ "\t\t\t\t- \0"
+/* 4436 */ "\t\t\t\t-- and \0"
+/* 4448 */ "\t\t\t\t%s\n\0"
+/* 4456 */ " \0"
+/* 4460 */ "%s error: %s exceeds %s keyword count\n\0"
+/* 4500 */ " \0"
+/* 4503 */ "\t\t\t\t- may appear up to %d times\n\0"
+/* 4536 */ "The valid \"%s\" option keywords are:\n\0"
+/* 4573 */ "These additional options are:\0"
+/* 4603 */ "The next option supports vendor supported extra options:";
+
+
+ /*
+ * 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_usage_text = {
+ 146,
+ eng_zGnuBoolArg, eng_zGnuKeyArg, eng_zGnuFileArg, eng_zGnuKeyLArg,
+ eng_zGnuTimeArg, eng_zGnuNumArg, eng_zGnuStrArg,
+ {
+ usage_txt + 0, usage_txt + 27, usage_txt + 79, usage_txt + 125,
+ usage_txt + 224, usage_txt + 260, usage_txt + 310, usage_txt + 343,
+ usage_txt + 434, usage_txt + 493, usage_txt + 543, usage_txt + 547,
+ usage_txt + 574, usage_txt + 623, usage_txt + 655, usage_txt + 707,
+ usage_txt + 715, usage_txt + 752, usage_txt + 777, usage_txt + 819,
+ usage_txt + 859, usage_txt + 996, usage_txt +1044, usage_txt +1098,
+ usage_txt +1111, usage_txt +1119, usage_txt +1161, usage_txt +1185,
+ usage_txt +1225, usage_txt +1240, usage_txt +1270, usage_txt +1296,
+ usage_txt +1309, usage_txt +1323, usage_txt +1370, usage_txt +1376,
+ usage_txt +1479, usage_txt +1491, usage_txt +1542, usage_txt +1571,
+ usage_txt +1622, usage_txt +1656, usage_txt +1697, usage_txt +1720,
+ usage_txt +1746, usage_txt +1777, usage_txt +1791, usage_txt +1806,
+ usage_txt +1837, usage_txt +1864, usage_txt +1970, usage_txt +1976,
+ usage_txt +1982, usage_txt +1989, usage_txt +2000, usage_txt +2026,
+ usage_txt +2052, usage_txt +2095, usage_txt +2131, usage_txt +2182,
+ usage_txt +2211, usage_txt +2267, usage_txt +2301, usage_txt +2339,
+ usage_txt +2404, usage_txt +2447, usage_txt +2482, usage_txt +2523,
+ usage_txt +2563, usage_txt +2590, usage_txt +2657, usage_txt +2705,
+ usage_txt +2738, usage_txt +2763, usage_txt +2811, usage_txt +2846,
+ usage_txt +2884, usage_txt +2911, usage_txt +2960, usage_txt +2965,
+ usage_txt +2983, usage_txt +3018, usage_txt +3062, usage_txt +3116,
+ usage_txt +3162, usage_txt +3211, usage_txt +3264, usage_txt +3272,
+ usage_txt +3320, usage_txt +3345, usage_txt +3379, usage_txt +3408,
+ usage_txt +3427, usage_txt +3461, usage_txt +3497, usage_txt +3535,
+ usage_txt +3591, usage_txt +3617, usage_txt +3683, usage_txt +3696,
+ usage_txt +3727, usage_txt +3764, usage_txt +3792, usage_txt +3798,
+ usage_txt +3847, usage_txt +3861, usage_txt +3907, usage_txt +3935,
+ usage_txt +3980, usage_txt +4022, usage_txt +4036, usage_txt +4061,
+ usage_txt +4101, usage_txt +4144, usage_txt +4148, usage_txt +4367,
+ usage_txt +4370, usage_txt +4377, usage_txt +4381, usage_txt +4389,
+ usage_txt +4393, usage_txt +4397, usage_txt +4401, usage_txt +4405,
+ usage_txt +4409, usage_txt +4413, usage_txt +4417, usage_txt +4421,
+ usage_txt +4425, usage_txt +4429, usage_txt +4436, usage_txt +4448,
+ usage_txt +4456, usage_txt +4460, usage_txt +4500, usage_txt +4503,
+ usage_txt +4536, usage_txt +4573, usage_txt +4603
+ }
+ };
+
+#endif /* DO_TRANSLATIONS */
+#endif /* AUTOOPTS_USAGE_TXT_H_GUARD */
diff --git a/autoopts/boolean.c b/autoopts/boolean.c
new file mode 100644
index 0000000..c463778
--- /dev/null
+++ b/autoopts/boolean.c
@@ -0,0 +1,97 @@
+
+/**
+ * \file boolean.c
+ *
+ * Time-stamp: "2012-08-11 08:34:39 bkorb"
+ *
+ * Automated Options Paged Usage module.
+ *
+ * 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-2012 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 md5sums:
+ *
+ * 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+ * 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+ * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
+ */
+
+/*=export_func optionBooleanVal
+ * private:
+ *
+ * what: Decipher a boolean value
+ * arg: + tOptions* + pOpts + program options descriptor +
+ * arg: + tOptDesc* + pOptDesc + 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 * pOpts, tOptDesc * pOD )
+{
+ char* pz;
+ bool res = true;
+
+ (void)pOpts;
+
+ if (pOpts <= OPTPROC_EMIT_LIMIT)
+ return;
+
+ if ((pOD->fOptState & OPTST_RESET) != 0)
+ return;
+
+ if (pOD->optArg.argString == NULL) {
+ pOD->optArg.argBool = false;
+ return;
+ }
+
+ switch (*(pOD->optArg.argString)) {
+ case '0':
+ {
+ long val = strtol( pOD->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 (pOD->optArg.argString[1] != 'f')
+ break;
+ res = false;
+ }
+
+ if (pOD->fOptState & OPTST_ALLOC_ARG) {
+ AGFREE(pOD->optArg.argString);
+ pOD->fOptState &= ~OPTST_ALLOC_ARG;
+ }
+ pOD->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..d86a9aa
--- /dev/null
+++ b/autoopts/bootstrap.dir
@@ -0,0 +1,232 @@
+#! /bin/echo This_file_must_be_sourced,_not_executed
+# Time-stamp: "2012-04-14 14:12:20 bkorb"
+#
+## This file is part of AutoOpts, a companion to AutoGen.
+## AutoOpts is free software.
+## AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/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
+ do g=${f%.sh} ; g=${g%.pl}
+ 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.
+ #
+ ${AGexe} -Tagman3.tpl funcs.def || \
+ die "FAILED: ${AGexe} -Tagman3.tpl funcs.def"
+
+ local tmpl=$(
+ ndst=""
+ sfil=''
+
+ for f in man mdoc texi
+ do
+ for g in man mdoc texi
+ do
+ sfil=${sfil}tpl/${f}2${g}${nl}
+ test -f tpl/${f}2${g}.sh || \
+ ndst=${ndst}tpl/${f}2${g}${nl}
+ done
+ done
+
+ 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}tpl/usage-txt.tpl${nl}"
+
+ for f in tpl/*.*
+ do
+ case $f in
+ ( *.in | *.pl | *.sh )
+ g=$(echo $f | sed 's/\...$//;s/-tlib$/.tlib/')
+ ndst=${ndst}${g}${nl} # installed file
+ edta=${edta}${f}${nl} # distributed file
+ ;;
+
+ ( *tpl-config.tlib | *tpl/usage* ) : ;;
+
+ ( *.tlib | *.tpl | *.def | *.lic )
+ 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 '\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 > Makefile.tmp
+ mv -f Makefile.tmp Makefile.am
+
+ rm -f Makefile.lists gnulib.mk *.3
+}
+
+make_funcs_def()
+{
+ $noag && exit 1
+ s2enum=`which mk-str2enum` 2>/dev/null || :
+ test -x "${s2enum}" || \
+ s2enum="bash ${top_srcdir}/add-on/char-mapper/mk-str2enum.sh"
+
+ ${char_mapper:-char-mapper} autogen.map || die "FAILED: char-mapper"
+ ${AGexe} ao-strs.def || die "cannot make strings - exited $?"
+
+ ${s2enum} --base-name=xat-attribute -n \
+ type words members cooked uncooked keep || \
+ die "FAILED: ${s2enum} --base-name=xat-attribute"
+
+ ${s2enum} --base-name=value-type --prefix=vtp -n string integer \
+ boolean bool keyword set set-membership nested hierarchy || \
+ die "FAILED: ${s2enum} --base-name=value-type"
+ burn_aover
+
+ test -d autoopts || mkdir autoopts
+ test -d po || mkdir po
+ ${AGexe} genshell.def || \
+ die "FAILED: ${AGexe} genshell.def"
+ ${AGexe} usage-txt.def || \
+ die "FAILED: ${AGexe} usage-txt.def"
+ mv usage-txt.h autoopts/.
+ mv usage-txt.pot po/.
+
+ files=$(sed -n '/^CSRC/,/\.c$/p' Makefile.am | \
+ sed '/^CSRC/d;s/[=\\]//'
+ echo ../compat/pathfind.c)
+ 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}";
+ 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_
+ ${AGexe} funcs.def || die "FAILED: ${AGexe} funcs.def"
+ test -f options.h || die "options.h not created"
+ mv options.h autoopts/.
+ cp project.h autoopts/.
+ add_files_to_mf
+ make_proto
+
+ ${AGexe} aoconf.def || die "FAILED: ${AGexe} aoconf.def"
+}
+
+test "X${mainpid}" = X && {
+ \cd ${top_srcdir-..}
+ top_srcdir=`pwd`
+ . config/bootstrap.shlib
+ cd autoopts
+ free_trap=true
+} || {
+ free_trap=false
+}
+
+export AGexe=${AGexe-autogen}\ -L${top_srcdir}/autoopts/tpl
+noag=`${AGexe} -v > /dev/null 2>&1 && echo false || echo true`
+nl=$'\n'
+
+case "$1" in
+*genshell.c )
+ if ${noag}
+ then
+ test -f ${top_srcdir}/autoopts/genshell.c || \
+ die "No autogen for building genshell.c"
+ else
+ ${AGexe} genshell.def || \
+ die "FAILED: ${AGexe} genshell.def"
+ fi
+ ;;
+
+*libopts.texi )
+ if ${noag}
+ then
+ test -f ${top_srcdir}/autoopts/libopts.texi || \
+ die "No autogen for building libopts.texi"
+ else
+ agopts='-Taginfo3.tpl -DLEVEL=subsection -blibopts funcs.def'
+ ${AGexe} ${agopts} || \
+ die "FAILED: ${AGexe} ${agopts}"
+ fi
+ ;;
+
+aoconf )
+ make_funcs_def
+ ;;
+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..019a235
--- /dev/null
+++ b/autoopts/check.c
@@ -0,0 +1,166 @@
+/**
+ * @file check.c
+ *
+ * @brief consistency checks.
+ *
+ * Time-stamp: "2012-03-31 13:46:35 bkorb"
+ *
+ * This file contains the routines that deal with processing quoted strings
+ * into an internal format.
+ *
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+ *
+ * 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+ * 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+ * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
+ */
+
+/**
+ * Check for conflicts based on "must" and "cannot" attributes.
+ */
+static bool
+has_conflict(tOptions * pOpts, tOptDesc * pOD)
+{
+ if (pOD->pOptMust != NULL) {
+ int const * pMust = pOD->pOptMust;
+
+ while (*pMust != NO_EQUIVALENT) {
+ tOptDesc * p = pOpts->pOptDesc + *(pMust++);
+ if (UNUSED_OPT(p)) {
+ const tOptDesc * pN = pOpts->pOptDesc + pMust[-1];
+ fprintf(stderr, zReqFmt, pOD->pz_Name, pN->pz_Name);
+ return true;
+ }
+ }
+ }
+
+ if (pOD->pOptCant != NULL) {
+ int const * pCant = pOD->pOptCant;
+
+ while (*pCant != NO_EQUIVALENT) {
+ tOptDesc * p = pOpts->pOptDesc + *(pCant++);
+ if (SELECTED_OPT(p)) {
+ const tOptDesc* pN = pOpts->pOptDesc + pCant[-1];
+ fprintf(stderr, zCantFmt, pOD->pz_Name, pN->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, zNotEnough, pOD->pz_Name, pOD->optMinCt);
+ else fprintf(stderr, zNeedOne, pOD->pz_Name);
+ return false;
+}
+
+/**
+ * Verify option consistency.
+ *
+ * Make sure that the argument list passes our consistency tests.
+ */
+LOCAL 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, zArgsMust, pOpts->pzProgName);
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
diff --git a/autoopts/configFileLoad.3 b/autoopts/configFileLoad.3
new file mode 100644
index 0000000..83c3d7e
--- /dev/null
+++ b/autoopts/configFileLoad.3
@@ -0,0 +1,50 @@
+.TH configFileLoad 3 2012-08-11 "" "Programmer's Manual"
+.\" DO NOT EDIT THIS FILE (configFileLoad.3)
+.\"
+.\" It has been AutoGen-ed August 11, 2012 at 09:44:56 AM by AutoGen 5.16.2
+.\" 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* \fIpzFile\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 pzFile
+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), optionNextValue(3), optionOnlyUsage(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), pathfind(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..3f98e31
--- /dev/null
+++ b/autoopts/configfile.c
@@ -0,0 +1,1433 @@
+/**
+ * \file configfile.c
+ *
+ * Time-stamp: "2012-08-11 08:34:55 bkorb"
+ *
+ * configuration/rc/ini file handling.
+ *
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+ *
+ * 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+ * 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+ * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
+ */
+
+/* = = = START-STATIC-FORWARD = = = */
+static void
+file_preset(tOptions * opts, char const * fname, int dir);
+
+static char*
+handle_comment(char* pzText);
+
+static char *
+handle_cfg(tOptions * pOpts, tOptState * pOS, char * pzText, int dir);
+
+static char *
+handle_directive(tOptions * pOpts, char * pzText);
+
+static char *
+aoflags_directive(tOptions * pOpts, char * pzText);
+
+static char *
+program_directive(tOptions * pOpts, char * pzText);
+
+static char *
+handle_section(tOptions * pOpts, char * pzText);
+
+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 * pOpts, tOptState * pOS, char * pzText, int dir);
+
+static char*
+parse_keyword(tOptions * pOpts, char * pzText, tOptionValue * pType);
+
+static char*
+parse_set_mem(tOptions * pOpts, char * pzText, tOptionValue * pType);
+
+static char *
+parse_value(char * pzText, tOptionValue * pType);
+
+static char *
+skip_unkn(char* pzText);
+/* = = = END-STATIC-FORWARD = = = */
+
+
+/*=export_func configFileLoad
+ *
+ * what: parse a configuration file
+ * arg: + char const* + pzFile + 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* pzFile)
+{
+ tmap_info_t cfgfile;
+ tOptionValue* pRes = NULL;
+ tOptionLoadMode save_mode = option_load_mode;
+
+ char* pzText =
+ text_mmap(pzFile, PROT_READ, MAP_PRIVATE, &cfgfile);
+
+ if (TEXT_MMAP_FAILED_ADDR(pzText))
+ return NULL; /* errno is set */
+
+ option_load_mode = OPTION_LOAD_COOKED;
+ pRes = optionLoadNested(pzText, pzFile, strlen(pzFile));
+
+ if (pRes == NULL) {
+ int err = errno;
+ text_munmap(&cfgfile);
+ errno = err;
+ } else
+ text_munmap(&cfgfile);
+
+ option_load_mode = save_mode;
+ return pRes;
+}
+
+
+/*=export_func optionFindValue
+ *
+ * what: find a hierarcicaly valued option instance
+ * arg: + const tOptDesc* + pOptDesc + an option with a nested arg type +
+ * 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 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* pOptDesc, char const* pzName,
+ char const* pzVal)
+{
+ const tOptionValue* pRes = NULL;
+
+ if ( (pOptDesc == NULL)
+ || (OPTST_GET_ARGTYPE(pOptDesc->fOptState) != OPARG_TYPE_HIERARCHY)) {
+ errno = EINVAL;
+ }
+
+ else if (pOptDesc->optCookie == NULL) {
+ errno = ENOENT;
+ }
+
+ else do {
+ tArgList* pAL = pOptDesc->optCookie;
+ int ct = pAL->useCt;
+ void** ppOV = (void**)(pAL->apzArgs);
+
+ if (ct == 0) {
+ errno = ENOENT;
+ break;
+ }
+
+ if (pzName == NULL) {
+ pRes = (tOptionValue*)*ppOV;
+ break;
+ }
+
+ while (--ct >= 0) {
+ const tOptionValue* pOV = *(ppOV++);
+ const tOptionValue* pRV = optionGetValue(pOV, pzName);
+
+ if (pRV == NULL)
+ continue;
+
+ if (pzVal == NULL) {
+ pRes = pOV;
+ break;
+ }
+ }
+ if (pRes == NULL)
+ errno = ENOENT;
+ } while (false);
+
+ return pRes;
+}
+
+
+/*=export_func optionFindNextValue
+ *
+ * FIXME: the handling of 'pzName' and 'pzVal' is just wrong.
+ *
+ * what: find a hierarcicaly valued option instance
+ * arg: + const tOptDesc* + pOptDesc + 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 * pOptDesc, const tOptionValue * pPrevVal,
+ char const * pzName, char const * pzVal)
+{
+ bool old_found = false;
+ tOptionValue* pRes = NULL;
+
+ (void)pzName;
+ (void)pzVal;
+
+ if ( (pOptDesc == NULL)
+ || (OPTST_GET_ARGTYPE(pOptDesc->fOptState) != OPARG_TYPE_HIERARCHY)) {
+ errno = EINVAL;
+ }
+
+ else if (pOptDesc->optCookie == NULL) {
+ errno = ENOENT;
+ }
+
+ else do {
+ tArgList* pAL = pOptDesc->optCookie;
+ int ct = pAL->useCt;
+ void** ppOV = (void**)pAL->apzArgs;
+
+ while (--ct >= 0) {
+ tOptionValue* pOV = *(ppOV++);
+ if (old_found) {
+ pRes = pOV;
+ break;
+ }
+ if (pOV == pPrevVal)
+ old_found = true;
+ }
+ if (pRes == NULL)
+ errno = ENOENT;
+ } while (false);
+
+ return pRes;
+}
+
+
+/*=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
+=*/
+const tOptionValue*
+optionGetValue(tOptionValue const * pOld, char const * pzValName)
+{
+ tArgList * pAL;
+ tOptionValue * pRes = NULL;
+
+ if ((pOld == NULL) || (pOld->valType != OPARG_TYPE_HIERARCHY)) {
+ errno = EINVAL;
+ return pRes;
+ }
+ pAL = pOld->v.nestVal;
+
+ if (pAL->useCt > 0) {
+ int ct = pAL->useCt;
+ void ** papOV = (void**)(pAL->apzArgs);
+
+ if (pzValName == NULL) {
+ pRes = (tOptionValue*)*papOV;
+
+ } else do {
+ tOptionValue * pOV = *(papOV++);
+ if (strcmp(pOV->pzName, pzValName) == 0) {
+ pRes = pOV;
+ break;
+ }
+ } while (--ct > 0);
+ }
+ if (pRes == NULL)
+ errno = ENOENT;
+ return pRes;
+}
+
+
+/*=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 * pOVList,tOptionValue const * pOldOV )
+{
+ tArgList* pAL;
+ tOptionValue* pRes = NULL;
+ int err = EINVAL;
+
+ if ((pOVList == NULL) || (pOVList->valType != OPARG_TYPE_HIERARCHY)) {
+ errno = EINVAL;
+ return NULL;
+ }
+ pAL = pOVList->v.nestVal;
+ {
+ int ct = pAL->useCt;
+ void** papNV = (void**)(pAL->apzArgs);
+
+ while (ct-- > 0) {
+ tOptionValue* pNV = *(papNV++);
+ if (pNV == pOldOV) {
+ if (ct == 0) {
+ err = ENOENT;
+
+ } else {
+ err = 0;
+ pRes = (tOptionValue*)*papNV;
+ }
+ break;
+ }
+ }
+ }
+ if (err != 0)
+ errno = err;
+ return pRes;
+}
+
+
+/**
+ * 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);
+ unsigned long st_flags = optst.flags;
+ char * ftext =
+ text_mmap(fname, PROT_READ|PROT_WRITE, MAP_PRIVATE, &cfgfile);
+
+ if (TEXT_MMAP_FAILED_ADDR(ftext))
+ return;
+
+ 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;
+
+ default:
+ 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);
+}
+
+
+/**
+ * "pzText" points to a "<!" sequence.
+ * Theoretically, we should ensure that it begins with "<!--",
+ * but actually I don't care that much. It ends with "-->".
+ */
+static char*
+handle_comment(char* pzText)
+{
+ char* pz = strstr(pzText, "-->");
+ if (pz != NULL)
+ pz += 3;
+ return pz;
+}
+
+
+/**
+ * "pzText" 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 * pOpts, tOptState * pOS, char * pzText, int dir)
+{
+ char* pzName = pzText++;
+ char* pzEnd = strchr(pzText, NL);
+
+ if (pzEnd == NULL)
+ return pzText + strlen(pzText);
+
+ pzText = SPN_VALUE_NAME_CHARS(pzText);
+ pzText = SPN_WHITESPACE_CHARS(pzText);
+ if (pzText > pzEnd) {
+ name_only:
+ *pzEnd++ = NUL;
+ loadOptionLine(pOpts, pOS, 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 ((*pzText == '=') || (*pzText == ':')) {
+ pzText = SPN_WHITESPACE_CHARS(pzText+1);
+ if (pzText > pzEnd)
+ goto name_only;
+ } else if (! IS_WHITESPACE_CHAR(pzText[-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.
+ */
+ loadOptionLine(pOpts, pOS, pzName, dir, OPTION_LOAD_UNCOOKED);
+
+ return pzEnd;
+}
+
+
+/**
+ * "pzText" points to a "<?" sequence.
+ * We handle "<?program" and "<?auto-options" directives.
+ * All others are treated as comments.
+ */
+static char *
+handle_directive(tOptions * pOpts, char * pzText)
+{
+# define DIRECTIVE_TABLE \
+ _dt_(zCfgProg, program_directive) \
+ _dt_(zCfgAO_Flags, aoflags_directive)
+
+ typedef char * (directive_func_t)(tOptions *, char *);
+# define _dt_(_s, _fn) _fn,
+ static directive_func_t * dir_disp[] = {
+ DIRECTIVE_TABLE
+ };
+# undef _dt_
+
+# define _dt_(_s, _fn) 1 +
+ static int const dir_ct = DIRECTIVE_TABLE 0;
+ static char const * dir_names[DIRECTIVE_TABLE 0];
+# undef _dt_
+
+ int ix;
+
+ if (dir_names[0] == NULL) {
+ ix = 0;
+# define _dt_(_s, _fn) dir_names[ix++] = _s;
+ DIRECTIVE_TABLE;
+# undef _dt_
+ }
+
+ for (ix = 0; ix < dir_ct; ix++) {
+ size_t len = strlen(dir_names[ix]);
+ if ( (strncmp(pzText + 2, dir_names[ix], len) == 0)
+ && (! IS_VALUE_NAME_CHAR(pzText[len+2])) )
+ return dir_disp[ix](pOpts, pzText + len + 2);
+ }
+
+ /*
+ * We don't know what this is. Skip it.
+ */
+ pzText = strchr(pzText+2, '>');
+ if (pzText != NULL)
+ pzText++;
+ return pzText;
+}
+
+/**
+ * handle AutoOpts mode flags
+ */
+static char *
+aoflags_directive(tOptions * pOpts, char * pzText)
+{
+ char * pz;
+
+ pz = SPN_WHITESPACE_CHARS(pzText+1);
+ pzText = strchr(pz, '>');
+ if (pzText != NULL) {
+
+ size_t len = pzText - pz;
+ char * ftxt = AGALOC(len + 1, "aoflags");
+
+ memcpy(ftxt, pz, len);
+ ftxt[len] = NUL;
+ set_usage_flags(pOpts, ftxt);
+ AGFREE(ftxt);
+
+ pzText++;
+ }
+
+ return pzText;
+}
+
+/**
+ * handle program segmentation of config file.
+ */
+static char *
+program_directive(tOptions * pOpts, char * pzText)
+{
+ static char const ttlfmt[] = "<?";
+ size_t ttl_len = sizeof(ttlfmt) + strlen(zCfgProg);
+ char * ttl = AGALOC(ttl_len, "prog title");
+ size_t name_len = strlen(pOpts->pzProgName);
+
+ memcpy(ttl, ttlfmt, sizeof(ttlfmt) - 1);
+ memcpy(ttl + sizeof(ttlfmt) - 1, zCfgProg, ttl_len - (sizeof(ttlfmt) - 1));
+
+ do {
+ pzText = SPN_WHITESPACE_CHARS(pzText+1);
+
+ if ( (strneqvcmp(pzText, pOpts->pzProgName, (int)name_len) == 0)
+ && (IS_END_XML_TOKEN_CHAR(pzText[name_len])) ) {
+ pzText += name_len;
+ break;
+ }
+
+ pzText = strstr(pzText, ttl);
+ } while (pzText != NULL);
+
+ AGFREE(ttl);
+ if (pzText != NULL)
+ for (;;) {
+ if (*pzText == NUL) {
+ pzText = NULL;
+ break;
+ }
+ if (*(pzText++) == '>')
+ break;
+ }
+
+ return pzText;
+}
+
+
+/**
+ * "pzText" points to a '[' character.
+ * The "traditional" [PROG_NAME] segmentation of the config file.
+ * Do not ever mix with the "<?program prog-name>" variation.
+ */
+static char *
+handle_section(tOptions * pOpts, char * pzText)
+{
+ size_t len = strlen(pOpts->pzPROGNAME);
+ if ( (strncmp(pzText+1, pOpts->pzPROGNAME, len) == 0)
+ && (pzText[len+1] == ']'))
+ return strchr(pzText + len + 2, NL);
+
+ if (len > 16)
+ return NULL;
+
+ {
+ char z[24];
+ sprintf(z, "[%s]", pOpts->pzPROGNAME);
+ pzText = strstr(pzText, z);
+ }
+
+ if (pzText != NULL)
+ pzText = strchr(pzText, NL);
+ return pzText;
+}
+
+/**
+ * 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':
+ /*
+ * &#0022; is hex and &#22; 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)
+{
+ static char const fmt[] = "</%s>";
+ size_t len = strlen(pznm) + sizeof(fmt) - 2 /* for %s */;
+ char * etext;
+
+ {
+ char z[64], *pz = z;
+ if (len >= sizeof(z))
+ pz = AGALOC(len, "scan name");
+
+ len = sprintf(pz, fmt, pznm);
+ *intxt = ' ';
+ etext = strstr(intxt, pz);
+ if (pz != z) AGFREE(pz);
+ }
+
+ if (etext == NULL)
+ return etext;
+
+ {
+ char * result = etext + 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 = strtoul(bf, NULL, 16);
+ /* FALLTHROUGH */
+
+ default:
+ *(pzd++) = (char)ch;
+ }
+ }
+}
+
+/**
+ * "pzText" points to a '<' character, followed by an alpha.
+ * The end of the entry is either the "/>" following the name, or else a
+ * "</name>" string.
+ */
+static char *
+handle_struct(tOptions * pOpts, tOptState * pOS, char * pzText, int dir)
+{
+ tOptionLoadMode mode = option_load_mode;
+ tOptionValue valu;
+
+ char* pzName = ++pzText;
+ char* pzData;
+ char* pcNulPoint;
+
+ pzText = SPN_VALUE_NAME_CHARS(pzText);
+ pcNulPoint = pzText;
+ valu.valType = OPARG_TYPE_STRING;
+
+ switch (*pzText) {
+ case ' ':
+ case '\t':
+ pzText = parse_attrs(pOpts, pzText, &mode, &valu);
+ if (*pzText == '>')
+ break;
+ if (*pzText != '/')
+ return NULL;
+ /* FALLTHROUGH */
+
+ case '/':
+ if (pzText[1] != '>')
+ return NULL;
+ *pzText = NUL;
+ pzText += 2;
+ loadOptionLine(pOpts, pOS, pzName, dir, mode);
+ return pzText;
+
+ case '>':
+ break;
+
+ default:
+ pzText = strchr(pzText, '>');
+ if (pzText != NULL)
+ pzText++;
+ return pzText;
+ }
+
+ /*
+ * If we are here, we have a value. "pzText" points to a closing angle
+ * bracket. Separate the name from the value for a moment.
+ */
+ *pcNulPoint = NUL;
+ pzData = ++pzText;
+ pzText = trim_xml_text(pzText, pzName, mode);
+ if (pzText == NULL)
+ return pzText;
+
+ /*
+ * Rejoin the name and value for parsing by "loadOptionLine()".
+ * Erase any attributes parsed by "parse_attrs()".
+ */
+ memset(pcNulPoint, ' ', 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.
+ */
+ loadOptionLine(pOpts, pOS, pzName, dir, mode);
+
+ return pzText;
+}
+
+
+/**
+ * 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)
+ */
+LOCAL void
+intern_file_load(tOptions* pOpts)
+{
+ uint32_t svfl;
+ int idx;
+ int inc;
+ char zFileName[ AG_PATH_MAX+1 ];
+
+ if (pOpts->papzHomeList == NULL)
+ return;
+
+ svfl = pOpts->fOptSet;
+ inc = DIRECTION_PRESET;
+
+ /*
+ * Never stop on errors in config files.
+ */
+ pOpts->fOptSet &= ~OPTPROC_ERRSTOP;
+
+ /*
+ * Find the last RC entry (highest priority entry)
+ */
+ for (idx = 0; pOpts->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 StatBuf;
+ cch_t* pzPath;
+
+ /*
+ * IF we've reached the bottom end, change direction
+ */
+ if (idx < 0) {
+ inc = DIRECTION_PROCESS;
+ idx = 0;
+ }
+
+ pzPath = pOpts->papzHomeList[ idx ];
+
+ /*
+ * IF we've reached the top end, bail out
+ */
+ if (pzPath == NULL)
+ break;
+
+ idx += inc;
+
+ if (! optionMakePath(zFileName, (int)sizeof(zFileName),
+ pzPath, pOpts->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(zFileName, &StatBuf) != 0)
+ continue; /* bogus name - skip the home list entry */
+
+ if (S_ISDIR(StatBuf.st_mode)) {
+ size_t len = strlen(zFileName);
+ size_t nln = strlen(pOpts->pzRcName) + 1;
+ char * pz = zFileName + len;
+
+ if (len + 1 + nln >= sizeof(zFileName))
+ continue;
+
+ if (pz[-1] != DIRCH)
+ *(pz++) = DIRCH;
+ memcpy(pz, pOpts->pzRcName, nln);
+ }
+
+ file_preset(pOpts, zFileName, inc);
+
+ /*
+ * IF we are now to skip config files AND we are presetting,
+ * THEN change direction. We must go the other way.
+ */
+ {
+ tOptDesc * pOD = pOpts->pOptDesc + pOpts->specOptIdx.save_opts+1;
+ if (DISABLED_OPT(pOD) && PRESETTING(inc)) {
+ idx -= inc; /* go back and reprocess current file */
+ inc = DIRECTION_PROCESS;
+ }
+ }
+ } /* twice for every path in the home list, ... */
+
+ pOpts->fOptSet = svfl;
+}
+
+
+/*=export_func optionFileLoad
+ *
+ * what: Load the locatable config files, in order
+ *
+ * arg: + tOptions* + pOpts + program options descriptor +
+ * arg: + char const* + pzProg + 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 * pOpts, char const * pzProgram)
+{
+ if (! SUCCESSFUL(validate_struct(pOpts, pzProgram)))
+ return -1;
+
+ {
+ char const ** pp =
+ (char const **)(void *)&(pOpts->pzProgName);
+ *pp = pzProgram;
+ }
+
+ intern_file_load(pOpts);
+ return 0;
+}
+
+
+/*=export_func optionLoadOpt
+ * private:
+ *
+ * what: Load an option rc/ini file
+ * arg: + tOptions* + pOpts + program options descriptor +
+ * arg: + tOptDesc* + pOptDesc + the descriptor for this arg +
+ *
+ * doc:
+ * Processes the options found in the file named with
+ * pOptDesc->optArg.argString.
+=*/
+void
+optionLoadOpt(tOptions * pOpts, tOptDesc * pOptDesc)
+{
+ struct stat sb;
+
+ if (pOpts <= 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(pOptDesc)
+ || ((pOptDesc->fOptState & OPTST_RESET) != 0))
+ return;
+
+ if (stat(pOptDesc->optArg.argString, &sb) != 0) {
+ if ((pOpts->fOptSet & OPTPROC_ERRSTOP) == 0)
+ return;
+
+ fprintf(stderr, zFSErrOptLoad, errno, strerror(errno),
+ pOptDesc->optArg.argString);
+ exit(EX_NOINPUT);
+ /* NOT REACHED */
+ }
+
+ if (! S_ISREG(sb.st_mode)) {
+ if ((pOpts->fOptSet & OPTPROC_ERRSTOP) == 0)
+ return;
+
+ fprintf(stderr, zNotFile, pOptDesc->optArg.argString);
+ exit(EX_NOINPUT);
+ /* NOT REACHED */
+ }
+
+ file_preset(pOpts, pOptDesc->optArg.argString, DIRECTION_CALLED);
+}
+
+
+/**
+ * Parse the various attributes of an XML-styled config file entry
+ */
+LOCAL char*
+parse_attrs(tOptions * pOpts, char * pzText, tOptionLoadMode * pMode,
+ tOptionValue * pType)
+{
+ size_t len;
+
+ do {
+ if (! IS_WHITESPACE_CHAR(*pzText))
+ switch (*pzText) {
+ case '/': pType->valType = OPARG_TYPE_NONE;
+ /* FALLTHROUGH */
+ case '>': return pzText;
+
+ default:
+ case NUL: return NULL;
+ }
+
+ pzText = SPN_WHITESPACE_CHARS(pzText+1);
+ len = SPN_LOWER_CASE_CHARS(pzText) - pzText;
+
+ switch (find_xat_attribute_id(pzText, len)) {
+ case XAT_KWD_TYPE:
+ pzText = parse_value(pzText+len, pType);
+ break;
+
+ case XAT_KWD_WORDS:
+ pzText = parse_keyword(pOpts, pzText+len, pType);
+ break;
+
+ case XAT_KWD_MEMBERS:
+ pzText = parse_set_mem(pOpts, pzText+len, pType);
+ break;
+
+ case XAT_KWD_COOKED:
+ pzText += len;
+ if (! IS_END_XML_TOKEN_CHAR(*pzText))
+ goto invalid_kwd;
+
+ *pMode = OPTION_LOAD_COOKED;
+ break;
+
+ case XAT_KWD_UNCOOKED:
+ pzText += len;
+ if (! IS_END_XML_TOKEN_CHAR(*pzText))
+ goto invalid_kwd;
+
+ *pMode = OPTION_LOAD_UNCOOKED;
+ break;
+
+ case XAT_KWD_KEEP:
+ pzText += len;
+ if (! IS_END_XML_TOKEN_CHAR(*pzText))
+ goto invalid_kwd;
+
+ *pMode = OPTION_LOAD_KEEP;
+ break;
+
+ default:
+ case XAT_KWD_INVALID:
+ invalid_kwd:
+ pType->valType = OPARG_TYPE_NONE;
+ return skip_unkn(pzText);
+ }
+ } while (pzText != NULL);
+
+ return pzText;
+}
+
+
+/**
+ * "pzText" points to the character after "words=".
+ * What should follow is a name of a keyword (enumeration) list.
+ */
+static char*
+parse_keyword(tOptions * pOpts, char * pzText, tOptionValue * pType)
+{
+ (void)pOpts;
+ (void)pType;
+
+ return skip_unkn(pzText);
+}
+
+
+/**
+ * "pzText" points to the character after "members="
+ * What should follow is a name of a "set membership".
+ * A collection of bit flags.
+ */
+static char*
+parse_set_mem(tOptions * pOpts, char * pzText, tOptionValue * pType)
+{
+ (void)pOpts;
+ (void)pType;
+
+ return skip_unkn(pzText);
+}
+
+
+/**
+ * "pzText" points to the character after "type="
+ */
+static char *
+parse_value(char * pzText, tOptionValue * pType)
+{
+ size_t len = 0;
+
+ if (*(pzText++) != '=')
+ goto woops;
+
+ len = SPN_OPTION_NAME_CHARS(pzText) - pzText;
+
+ if ((len == 0) || (! IS_END_XML_TOKEN_CHAR(pzText[len]))) {
+ woops:
+ pType->valType = OPARG_TYPE_NONE;
+ return skip_unkn(pzText + len);
+ }
+
+ switch (find_value_type_id(pzText, len)) {
+ default:
+ case VTP_KWD_INVALID: goto woops;
+
+ case VTP_KWD_STRING:
+ pType->valType = OPARG_TYPE_STRING;
+ break;
+
+ case VTP_KWD_INTEGER:
+ pType->valType = OPARG_TYPE_NUMERIC;
+ break;
+
+ case VTP_KWD_BOOL:
+ case VTP_KWD_BOOLEAN:
+ pType->valType = OPARG_TYPE_BOOLEAN;
+ break;
+
+ case VTP_KWD_KEYWORD:
+ pType->valType = OPARG_TYPE_ENUMERATION;
+ break;
+
+ case VTP_KWD_SET:
+ case VTP_KWD_SET_MEMBERSHIP:
+ pType->valType = OPARG_TYPE_MEMBERSHIP;
+ break;
+
+ case VTP_KWD_NESTED:
+ case VTP_KWD_HIERARCHY:
+ pType->valType = OPARG_TYPE_HIERARCHY;
+ }
+
+ return pzText + len;
+}
+
+
+/**
+ * Skip over some unknown attribute
+ */
+static char *
+skip_unkn(char* pzText)
+{
+ for (;; pzText++) {
+ if (IS_END_XML_TOKEN_CHAR(*pzText)) return pzText;
+ if (*pzText == NUL) return NULL;
+ }
+}
+
+
+/**
+ * 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 pOpts program options descriptor
+ * @param pzProgram name of program, from argv[]
+ * @returns SUCCESS or FAILURE
+ */
+LOCAL tSuccess
+validate_struct(tOptions * pOpts, char const * pzProgram)
+{
+ if (pOpts == NULL) {
+ fputs(zAO_Bad, stderr);
+ return FAILURE;
+ }
+
+ /*
+ * IF the client has enabled translation and the translation procedure
+ * is available, then go do it.
+ */
+ if ( ((pOpts->fOptSet & OPTPROC_TRANSLATE) != 0)
+ && (pOpts->pTransProc != NULL) ) {
+ /*
+ * 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 ((pOpts->fOptSet & OPTPROC_NO_XLAT_MASK) == OPTPROC_NXLAT_OPT)
+ pOpts->fOptSet |= OPTPROC_NXLAT_OPT_CFG;
+ (*pOpts->pTransProc)();
+ pOpts->fOptSet &= ~OPTPROC_TRANSLATE;
+ }
+
+ /*
+ * IF the struct version is not the current, and also
+ * either too large (?!) or too small,
+ * THEN emit error message and fail-exit
+ */
+ if ( ( pOpts->structVersion != OPTIONS_STRUCT_VERSION )
+ && ( (pOpts->structVersion > OPTIONS_STRUCT_VERSION )
+ || (pOpts->structVersion < OPTIONS_MINIMUM_VERSION )
+ ) ) {
+ static char const aover[] =
+ STR(AO_CURRENT)":"STR(AO_REVISION)":"STR(AO_AGE)"\n";
+
+ fprintf(stderr, zAO_Err, pzProgram, NUM_TO_VER(pOpts->structVersion));
+ if (pOpts->structVersion > OPTIONS_STRUCT_VERSION )
+ fputs(zAO_Big, stderr);
+ else
+ fputs(zAO_Sml, stderr);
+
+ fwrite(aover, sizeof(aover) - 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 (pOpts->pzProgName == NULL) {
+ char const * pz = strrchr(pzProgram, DIRCH);
+ char const ** pp =
+ (char const **)(void **)&(pOpts->pzProgName);
+
+ if (pz != NULL) {
+ *pp = pz+1;
+ } else {
+ *pp = pzProgram;
+ pz = pathfind(getenv("PATH"), (char *)pzProgram, "rx");
+ if (pz != NULL)
+ pzProgram = (void *)pz;
+ }
+
+ pp = (char const **)(void **)&(pOpts->pzProgPath);
+ *pp = pzProgram;
+
+ /*
+ * when comparing long names, these are equivalent
+ */
+ strequate(zSepChars);
+ }
+
+ return SUCCESS;
+}
+
+
+/**
+ * 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..f34a6ed
--- /dev/null
+++ b/autoopts/cook.c
@@ -0,0 +1,311 @@
+/**
+ * \file cook.c
+ *
+ * Time-stamp: "2012-02-28 19:40:47 bkorb"
+ *
+ * This file contains the routines that deal with processing quoted strings
+ * into an internal format.
+ *
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+ *
+ * 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+ * 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+ * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
+ */
+
+/* = = = START-STATIC-FORWARD = = = */
+static bool
+contiguous_quote(char ** pps, char * pq, int * lnct_p);
+/* = = = END-STATIC-FORWARD = = = */
+
+/*=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], *pz = z;
+
+ do *(pz++) = *(pzIn++);
+ while (IS_HEX_DIGIT_CHAR(*pzIn) && (pz < z + 2));
+ *pz = NUL;
+ *pRes = (unsigned char)strtoul(z, NULL, 16);
+ res += pz - z;
+ }
+ 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
+ */
+ char z[4], *pz = z + 1;
+ unsigned long val;
+ z[0] = *pRes;
+
+ while (IS_OCT_DIGIT_CHAR(*pzIn) && (pz < z + 3))
+ *(pz++) = *(pzIn++);
+ *pz = NUL;
+ val = strtoul(z, NULL, 8);
+ if (val > 0xFF)
+ val = 0xFF;
+ *pRes = (unsigned char)val;
+ res = pz - z;
+ break;
+ }
+
+ default: ;
+ }
+
+ return res;
+}
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * 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:
+ *pps = NULL;
+ return false;
+
+ case '/':
+ /*
+ * Skip to end of line
+ */
+ ps = strchr(ps, NL);
+ if (ps == NULL) {
+ *pps = NULL;
+ return false;
+ }
+ break;
+
+ case '*':
+ {
+ char* p = strstr( ps+2, "*/" );
+ /*
+ * Skip to terminating star slash
+ */
+ if (p == NULL) {
+ *pps = NULL;
+ return false;
+ }
+
+ while (ps < p) {
+ if (*(ps++) == NL)
+ (*lnct_p)++;
+ }
+
+ ps = p + 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;
+ }
+ }
+}
+
+/*=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 != '\'') {
+ int 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..dff5df8
--- /dev/null
+++ b/autoopts/enum.c
@@ -0,0 +1,546 @@
+
+/**
+ * \file enumeration.c
+ *
+ * Time-stamp: "2012-08-11 08:12:58 bkorb"
+ *
+ * Automated Options Paged Usage module.
+ *
+ * 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-2012 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 md5sums:
+ *
+ * 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+ * 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+ * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
+ */
+
+static char const * pz_enum_err_fmt;
+
+/* = = = START-STATIC-FORWARD = = = */
+static void
+enum_err(tOptions * pOpts, tOptDesc * pOD,
+ char const * const * paz_names, int name_ct);
+
+static uintptr_t
+find_name(char const * pzName, tOptions * pOpts, tOptDesc * pOD,
+ char const * const * paz_names, unsigned int name_ct);
+
+static void
+set_memb_usage(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 * pOpts, tOptDesc * pOD, char const * const * paz_names,
+ unsigned int name_ct);
+/* = = = END-STATIC-FORWARD = = = */
+
+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_SEP_LINE_FMT, *(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 zFmt[16]; /* format for all-but-last entries on a line */
+
+ sprintf(zFmt, ENUM_ERR_STR_WIDTH_FMT, (int)max_len);
+ 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, zFmt, *(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 pzName 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 * pzName, 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*)pzName);
+ uintptr_t idx;
+
+ if (IS_DEC_DIGIT_CHAR(*pzName)) {
+ char * pz = (char *)(void *)pzName;
+ unsigned long val = strtoul(pz, &pz, 0);
+ if ((*pz == NUL) && (val < name_ct))
+ return (uintptr_t)val;
+ pz_enum_err_fmt = zTooLarge;
+ option_usage_fp = stderr;
+ enum_err(pOpts, pOD, paz_names, (int)name_ct);
+ return name_ct;
+ }
+
+ if (IS_INVERSION_CHAR(*pzName) && (pzName[2] == NUL)) {
+ if ( ((pzName[0] == '~') && (pzName[1] == '0'))
+ || ((pzName[0] == '-') && (pzName[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*)pzName, len) == 0) {
+ if (paz_names[idx][len] == NUL)
+ return idx; /* full match */
+
+ if (res == name_ct)
+ res = idx; /* save partial match */
+ else
+ res = ~0; /* may yet find full match */
+ }
+ }
+
+ if (res < name_ct)
+ return res; /* partial match */
+
+oops:
+
+ pz_enum_err_fmt = (res == name_ct) ? zNoKey : zAmbigKey;
+ 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 = {
+ .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 = 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 = 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_usage(tOptions * pOpts, tOptDesc * pOD, char const * const * paz_names,
+ unsigned int name_ct)
+{
+ /*
+ * print the list of enumeration names.
+ */
+ (void)pOpts;
+ enum_err(OPTPROC_EMIT_USAGE, pOD, paz_names, (int)name_ct );
+}
+
+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 * pOpts, tOptDesc * pOD, char const * const * paz_names,
+ unsigned int name_ct)
+{
+ char * pz;
+ uintptr_t bits = (uintptr_t)pOD->optCookie;
+ unsigned int ix = 0;
+ size_t len = NONE_STR_LEN + 1;
+
+ (void)pOpts;
+ bits &= ((uintptr_t)1 << (uintptr_t)name_ct) - (uintptr_t)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(paz_names[ix]) + PLUS_STR_LEN + 1;
+ if (++ix >= name_ct) break;
+ bits >>= 1;
+ }
+
+ pOD->optArg.argString = pz = AGALOC(len, "enum");
+
+ /*
+ * Start by clearing all the bits. We want to turn off any defaults
+ * because we will be restoring to current state, not adding to
+ * the default set of bits.
+ */
+ memcpy(pz, NONE_STR, NONE_STR_LEN);
+ pz += NONE_STR_LEN;
+ bits = (uintptr_t)pOD->optCookie;
+ bits &= ((uintptr_t)1 << (uintptr_t)name_ct) - (uintptr_t)1;
+ ix = 0;
+
+ while (bits != 0) {
+ if (bits & 1) {
+ size_t nln = strlen(paz_names[ix]);
+ memcpy(pz, PLUS_STR, PLUS_STR_LEN);
+ memcpy(pz+PLUS_STR_LEN, paz_names[ix], nln);
+ pz += nln + PLUS_STR_LEN;
+ }
+ if (++ix >= name_ct) break;
+ bits >>= 1;
+ }
+ *pz = NUL;
+}
+
+/*=export_func optionSetMembers
+ * what: Convert between bit flag values and strings
+ * 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
+ *
+ * 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 * pOpts, tOptDesc * pOD,
+ char const* const * paz_names, unsigned int name_ct)
+{
+ /*
+ * 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:
+ set_memb_usage(pOpts, pOD, paz_names, name_ct);
+ return;
+
+ case (uintptr_t)OPTPROC_EMIT_SHELL:
+ set_memb_shell(pOpts, pOD, paz_names, name_ct);
+ return;
+
+ case (uintptr_t)OPTPROC_RETURN_VALNAME:
+ set_memb_names(pOpts, pOD, paz_names, name_ct);
+ return;
+
+ default:
+ break;
+ }
+
+ if ((pOD->fOptState & OPTST_RESET) != 0)
+ return;
+
+ {
+ char const * pzArg = pOD->optArg.argString;
+ uintptr_t res;
+ if ((pzArg == NULL) || (*pzArg == NUL)) {
+ pOD->optCookie = (void*)0;
+ return;
+ }
+
+ res = (uintptr_t)pOD->optCookie;
+ for (;;) {
+ int iv, len;
+
+ pzArg = SPN_SET_SEPARATOR_CHARS(pzArg);
+ iv = (*pzArg == '!');
+ if (iv)
+ pzArg = SPN_WHITESPACE_CHARS(pzArg+1);
+
+ len = BRK_SET_SEPARATOR_CHARS(pzArg) - pzArg;
+ if (len == 0)
+ break;
+
+ if ((len == 3) && (strncmp(pzArg, zAll, 3) == 0)) {
+ if (iv)
+ res = 0;
+ else res = ~0UL;
+ }
+ else if ((len == 4) && (strncmp(pzArg, zNone, 4) == 0)) {
+ if (! iv)
+ res = 0;
+ }
+ else do {
+ char* pz;
+ uintptr_t bit = strtoul(pzArg, &pz, 0);
+
+ if (pz != pzArg + len) {
+ char z[ AO_NAME_SIZE ];
+ char const* p;
+ unsigned int shift_ct;
+
+ if (*pz != NUL) {
+ if (len >= AO_NAME_LIMIT)
+ break;
+ memcpy(z, pzArg, (size_t)len);
+ z[len] = NUL;
+ p = z;
+ } else {
+ p = pzArg;
+ }
+
+ shift_ct = find_name(p, pOpts, pOD, paz_names, name_ct);
+ if (shift_ct >= name_ct) {
+ pOD->optCookie = (void*)0;
+ return;
+ }
+ bit = 1UL << shift_ct;
+ }
+ if (iv)
+ res &= ~bit;
+ else res |= bit;
+ } while (false);
+
+ if (pzArg[len] == NUL)
+ break;
+ pzArg += len + 1;
+ }
+ if (name_ct < (8 * sizeof(uintptr_t))) {
+ res &= (1UL << name_ct) - 1UL;
+ }
+
+ pOD->optCookie = (void*)res;
+ }
+}
+
+/*
+ * Local Variables:
+ * mode: C
+ * c-file-style: "stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * end of autoopts/enumeration.c */
diff --git a/autoopts/env.c b/autoopts/env.c
new file mode 100644
index 0000000..2b55137
--- /dev/null
+++ b/autoopts/env.c
@@ -0,0 +1,264 @@
+
+/**
+ * \file environment.c
+ *
+ * Time-stamp: "2012-08-11 08:18:25 bkorb"
+ *
+ * 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-2012 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 md5sums:
+ *
+ * 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+ * 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+ * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
+ */
+
+/* = = = START-STATIC-FORWARD = = = */
+static void
+do_env_opt(tOptState * os, char * env_name,
+ tOptions * pOpts, teEnvPresetType type);
+/* = = = END-STATIC-FORWARD = = = */
+
+/*
+ * 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.
+ */
+LOCAL void
+doPrognameEnv(tOptions * pOpts, teEnvPresetType type)
+{
+ char const * pczOptStr = getenv(pOpts->pzPROGNAME);
+ token_list_t* pTL;
+ int sv_argc;
+ tAoUI sv_flag;
+ char ** sv_argv;
+
+ /*
+ * No such beast? Then bail now.
+ */
+ if (pczOptStr == NULL)
+ return;
+
+ /*
+ * Tokenize the string. If there's nothing of interest, we'll bail
+ * here immediately.
+ */
+ pTL = ao_string_tokenize(pczOptStr);
+ if (pTL == NULL)
+ return;
+
+ /*
+ * Substitute our $PROGNAME argument list for the real one
+ */
+ sv_argc = 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 = (void *)(v - sizeof(char *));
+ }
+ pOpts->origArgCt = 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 = 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....
+ */
+LOCAL 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 - (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..5a5b3eb
--- /dev/null
+++ b/autoopts/file.c
@@ -0,0 +1,208 @@
+
+/**
+ * \file file.c
+ *
+ * Time-stamp: "2011-08-06 08:49:35 bkorb"
+ *
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+ *
+ * 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+ * 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+ * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/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;
+ fprintf(stderr, zFSOptError, errno, strerror(errno),
+ zFSOptErrNoExist, fname, pOD->pz_Name);
+ pOpts->pUsageProc(pOpts, EXIT_FAILURE);
+ /* 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 = 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))) {
+ fprintf(stderr, zFSOptError, errno, strerror(errno),
+ zFSOptErrMayExist, fname, pOD->pz_Name);
+ pOpts->pUsageProc(pOpts, EXIT_FAILURE);
+ /* NOTREACHED */
+ }
+ AGFREE(p);
+ break;
+ }
+
+ case FTYPE_MODE_MUST_EXIST:
+ if ( (stat(fname, &sb) != 0)
+ || (errno = EINVAL, ! S_ISREG(sb.st_mode)) ) {
+ fprintf(stderr, zFSOptError, errno, strerror(errno),
+ zFSOptErrMustExist, fname,
+ pOD->pz_Name);
+ pOpts->pUsageProc(pOpts, EXIT_FAILURE);
+ /* 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) {
+ fprintf(stderr, zFSOptError, errno, strerror(errno),
+ zFSOptErrOpen, pOD->optArg.argString, pOD->pz_Name);
+ pOpts->pUsageProc(pOpts, EXIT_FAILURE);
+ /* NOTREACHED */
+ }
+
+ if ((pOD->fOptState & OPTST_ALLOC_ARG) != 0)
+ pOD->optCookie = (void *)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) {
+ fprintf(stderr, zFSOptError, errno, strerror(errno),
+ zFSOptErrFopen, pOD->optArg.argString, pOD->pz_Name);
+ pOpts->pUsageProc(pOpts, EXIT_FAILURE);
+ /* NOTREACHED */
+ }
+
+ if ((pOD->fOptState & OPTST_ALLOC_ARG) != 0)
+ pOD->optCookie = (void *)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, option_usage_fp);
+ break;
+
+ case FTYPE_MODE_MUST_EXIST:
+ fputs(zFileMustExist, 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..b9e88d5
--- /dev/null
+++ b/autoopts/find.c
@@ -0,0 +1,579 @@
+/**
+ * @file check.c
+ *
+ * @brief Hunt for options in the option descriptor list
+ *
+ * Time-stamp: "2012-08-11 08:36:11 bkorb"
+ *
+ * This file contains the routines that deal with processing quoted strings
+ * into an internal format.
+ *
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+ *
+ * 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+ * 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+ * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/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, 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(zAmbigList, stderr);
+ do {
+ if (strneqvcmp(name, pOD->pz_Name, nm_len) == 0)
+ fprintf(stderr, zAmbiguous, hyph, pOD->pz_Name);
+
+ else if ( (pOD->pz_DisableName != NULL)
+ && (strneqvcmp(name, pOD->pz_DisableName, nm_len) == 0)
+ )
+ fprintf(stderr, zAmbiguous, 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, zAmbigOptStr, opts->pzProgPath, name, match_ct);
+ if (match_ct <= 4)
+ opt_ambiguities(opts, name, 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
+ */
+LOCAL 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 <= 0) {
+ 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
+ */
+LOCAL 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)) {
+ 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;
+}
+
+LOCAL tSuccess
+get_opt_arg(tOptions * pOpts, tOptState * pOptState)
+{
+ pOptState->flags |= (pOptState->pOD->fOptState & OPTST_PERSISTENT_MASK);
+
+ /*
+ * Figure out what to do about option arguments. An argument may be
+ * required, not associated with the option, or be optional. We detect the
+ * latter by examining for an option marker on the next possible argument.
+ * Disabled mode option selection also disables option arguments.
+ */
+ {
+ enum { ARG_NONE, ARG_MAY, ARG_MUST } arg_type = ARG_NONE;
+ tSuccess res;
+
+ if ((pOptState->flags & OPTST_DISABLED) != 0)
+ arg_type = ARG_NONE;
+
+ else if (OPTST_GET_ARGTYPE(pOptState->flags) == OPARG_TYPE_NONE)
+ arg_type = ARG_NONE;
+
+ else if (pOptState->flags & OPTST_ARG_OPTIONAL)
+ arg_type = ARG_MAY;
+
+ else
+ arg_type = ARG_MUST;
+
+ switch (arg_type) {
+ case ARG_MUST: res = next_opt_arg_must(pOpts, pOptState); break;
+ case ARG_MAY: res = next_opt_arg_may( pOpts, pOptState); break;
+ case ARG_NONE: res = next_opt_arg_none(pOpts, pOptState); break;
+ }
+
+ return res;
+ }
+}
+
+/**
+ * Find the option descriptor for the current option
+ */
+LOCAL tSuccess
+find_opt(tOptions * pOpts, tOptState * pOptState)
+{
+ /*
+ * 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 ((pOpts->pzCurOpt != NULL) && (*pOpts->pzCurOpt != NUL))
+ return opt_find_short(pOpts, (tAoUC)*(pOpts->pzCurOpt), pOptState);
+
+ if (pOpts->curOptIdx >= pOpts->origArgCt)
+ return PROBLEM; /* NORMAL COMPLETION */
+
+ pOpts->pzCurOpt = pOpts->origArgVect[ pOpts->curOptIdx ];
+
+ /*
+ * IF all arguments must be named options, ...
+ */
+ if (NAMED_OPTS(pOpts)) {
+ char * pz = pOpts->pzCurOpt;
+ int def;
+ tSuccess res;
+ tAoUS * def_opt;
+
+ pOpts->curOptIdx++;
+
+ if (*pz != '-')
+ return opt_find_long(pOpts, pz, pOptState);
+
+ /*
+ * 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 = (void *)&(pOpts->specOptIdx.default_opt);
+ def = *def_opt;
+ *def_opt = NO_EQUIVALENT;
+ res = opt_find_long(pOpts, pz, pOptState);
+ *def_opt = def;
+ return res;
+ }
+
+ /*
+ * Note the kind of flag/option marker
+ */
+ if (*((pOpts->pzCurOpt)++) != '-')
+ return PROBLEM; /* NORMAL COMPLETION - this + rest are operands */
+
+ /*
+ * Special hack for a hyphen by itself
+ */
+ if (*(pOpts->pzCurOpt) == NUL)
+ return PROBLEM; /* NORMAL COMPLETION - this + rest are operands */
+
+ /*
+ * The current argument is to be processed as an option argument
+ */
+ pOpts->curOptIdx++;
+
+ /*
+ * We have an option marker.
+ * Test the next character for long option indication
+ */
+ if (pOpts->pzCurOpt[0] == '-') {
+ if (*++(pOpts->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 ((pOpts->fOptSet & OPTPROC_LONGOPT) == 0) {
+ fprintf(stderr, zIllOptStr, pOpts->pzProgPath,
+ pOpts->pzCurOpt-2);
+ return FAILURE;
+ }
+
+ return opt_find_long(pOpts, pOpts->pzCurOpt, pOptState);
+ }
+
+ /*
+ * If short options are not allowed, then do long
+ * option processing. Otherwise the character must be a
+ * short (i.e. single character) option.
+ */
+ if ((pOpts->fOptSet & OPTPROC_SHORTOPT) != 0)
+ return opt_find_short(pOpts, (tAoUC)*(pOpts->pzCurOpt), pOptState);
+
+ return opt_find_long(pOpts, pOpts->pzCurOpt, pOptState);
+}
+
+/*
+ * 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..3696339
--- /dev/null
+++ b/autoopts/funcs.def
@@ -0,0 +1,1620 @@
+/* -*- 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
+ * ../compat/pathfind.c
+ */
+autogen definitions options_h;
+
+/* GLOBALDEFS */
+
+#line 594 "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 206 "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 = '206';
+};
+
+
+#line 35 "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 = '35';
+};
+
+
+#line 164 "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 <stdlib.h>
+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 = '164';
+};
+
+
+#line 77 "configfile.c"
+export_func = {
+ name = 'configFileLoad';
+ what = 'parse a configuration file';
+ arg = {
+ arg_type = 'char const*';
+ arg_name = 'pzFile';
+ 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 = '77';
+};
+
+
+#line 765 "makeshell.c"
+export_func = {
+ name = 'genshelloptUsage';
+ private;
+ what = 'The usage function for the genshellopt generated program';
+ arg = {
+ arg_type = 'tOptions*';
+ arg_name = 'pOpts';
+ arg_desc = 'program options descriptor';
+ };
+ arg = {
+ arg_type = 'int';
+ arg_name = 'exitCode';
+ 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 = '765';
+};
+
+
+#line 32 "alias.c"
+export_func = {
+ name = 'optionAlias';
+ private;
+ what = 'relay an option to its alias';
+ 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 = '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 = '32';
+};
+
+
+#line 33 "boolean.c"
+export_func = {
+ name = 'optionBooleanVal';
+ 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';
+ };
+ 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 = '33';
+};
+
+
+#line 260 "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 = '260';
+};
+
+
+#line 151 "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 = '151';
+};
+
+
+#line 1066 "configfile.c"
+export_func = {
+ name = 'optionFileLoad';
+ what = 'Load the locatable config files, in order';
+ arg = {
+ arg_type = 'tOptions*';
+ arg_name = 'pOpts';
+ arg_desc = 'program options descriptor';
+ };
+ arg = {
+ arg_type = 'char const*';
+ arg_name = 'pzProg';
+ 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 = '1066';
+};
+
+
+#line 211 "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 = 'pOptDesc';
+ 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 = '211';
+};
+
+
+#line 137 "configfile.c"
+export_func = {
+ name = 'optionFindValue';
+ what = 'find a hierarcicaly valued option instance';
+ arg = {
+ arg_type = 'const tOptDesc*';
+ arg_name = 'pOptDesc';
+ 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 = 'value';
+ 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 = '137';
+};
+
+
+#line 166 "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 = '166';
+};
+
+
+#line 280 "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 = '280';
+};
+
+
+#line 237 "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 = '237';
+};
+
+
+#line 478 "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 = '478';
+};
+
+
+#line 1116 "configfile.c"
+export_func = {
+ name = 'optionLoadOpt';
+ private;
+ what = 'Load an option rc/ini file';
+ 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 =
+'Processes the options found in the file named with
+pOptDesc->optArg.argString.';
+ srcfile = 'configfile.c';
+ linenum = '1116';
+};
+
+
+#line 43 "load.c"
+export_func = {
+ name = 'optionMakePath';
+ private;
+ what = 'translate and construct a path';
+ arg = {
+ arg_type = 'char*';
+ arg_name = 'pzBuf';
+ arg_desc = 'The result buffer';
+ };
+ arg = {
+ arg_type = 'int';
+ arg_name = 'bufSize';
+ arg_desc = 'The size of this buffer';
+ };
+ arg = {
+ arg_type = 'char const*';
+ arg_name = 'pzName';
+ arg_desc = 'The input name';
+ };
+ arg = {
+ arg_type = 'char const*';
+ arg_name = 'pzProgPath';
+ 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 = '43';
+};
+
+
+#line 727 "nested.c"
+export_func = {
+ name = 'optionNestedVal';
+ private;
+ what = 'parse a hierarchical option argument';
+ 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 =
+'Nested value was found on the command line';
+ srcfile = 'nested.c';
+ linenum = '727';
+};
+
+
+#line 340 "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 = '340';
+};
+
+
+#line 90 "numeric.c"
+export_func = {
+ name = 'optionNumericVal';
+ private;
+ what = 'process an option with a numeric 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';
+ };
+ doc =
+'Decipher a numeric value.';
+ srcfile = 'numeric.c';
+ linenum = '90';
+};
+
+
+#line 201 "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 = '201';
+};
+
+
+#line 33 "pgusage.c"
+export_func = {
+ name = 'optionPagedUsage';
+ 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';
+ };
+ 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 = '33';
+};
+
+
+#line 73 "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 = '73';
+};
+
+
+#line 176 "version.c"
+export_func = {
+ name = 'optionPrintVersion';
+ private;
+ 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 = '176';
+};
+
+
+#line 607 "autoopts.c"
+export_func = {
+ name = 'optionProcess';
+ what = 'this is the main option processing routine';
+ arg = {
+ arg_type = 'tOptions*';
+ arg_name = 'pOpts';
+ arg_desc = 'program options descriptor';
+ };
+ arg = {
+ arg_type = 'int';
+ arg_name = 'argc';
+ arg_desc = 'program arg count';
+ };
+ arg = {
+ arg_type = 'char**';
+ arg_name = 'argv';
+ 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 = '607';
+};
+
+
+#line 214 "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 = '214';
+};
+
+
+#line 58 "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 = '58';
+};
+
+
+#line 123 "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 = '123';
+};
+
+
+#line 648 "save.c"
+export_func = {
+ name = 'optionSaveFile';
+ what = 'saves the option state to a file';
+ arg = {
+ arg_type = 'tOptions*';
+ arg_name = 'pOpts';
+ 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 = '648';
+};
+
+
+#line 71 "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 = '71';
+};
+
+
+#line 423 "enum.c"
+export_func = {
+ name = 'optionSetMembers';
+ what = 'Convert between bit flag values and strings';
+ 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';
+ };
+ 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 = '423';
+};
+
+
+#line 28 "numeric.c"
+export_func = {
+ name = 'optionShowRange';
+ private;
+ what;
+ 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 = '28';
+};
+
+
+#line 226 "stack.c"
+export_func = {
+ name = 'optionStackArg';
+ private;
+ what = 'put option args on a stack';
+ 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 =
+'Keep an entry-ordered list of option arguments.';
+ srcfile = 'stack.c';
+ linenum = '226';
+};
+
+
+#line 64 "time.c"
+export_func = {
+ name = 'optionTimeDate';
+ private;
+ what = 'process an option with a time and date.';
+ 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 =
+'Decipher a time and date value.';
+ srcfile = 'time.c';
+ linenum = '64';
+};
+
+
+#line 28 "time.c"
+export_func = {
+ name = 'optionTimeVal';
+ private;
+ what = 'process an option with a time duration.';
+ 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 =
+'Decipher a time duration value.';
+ srcfile = 'time.c';
+ linenum = '28';
+};
+
+
+#line 563 "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 = '563';
+};
+
+
+#line 35 "stack.c"
+export_func = {
+ name = 'optionUnstackArg';
+ private;
+ what = 'Remove option args from a stack';
+ 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 =
+'Invoked for options that are equivalenced to stacked options.';
+ srcfile = 'stack.c';
+ linenum = '35';
+};
+
+
+#line 315 "usage.c"
+export_func = {
+ name = 'optionUsage';
+ private;
+ what = 'Print usage text';
+ arg = {
+ arg_type = 'tOptions*';
+ arg_name = 'pOptions';
+ 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 = '315';
+};
+
+
+#line 268 "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 = '268';
+};
+
+
+#line 31 "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 = '31';
+};
+
+
+#line 192 "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 = '192';
+};
+
+
+#line 29 "../compat/pathfind.c"
+export_func = {
+ name = 'pathfind';
+ what = 'fild a file in a list of directories';
+ ifndef = 'HAVE_PATHFIND';
+ arg = {
+ arg_type = 'char const*';
+ arg_name = 'path';
+ arg_desc = 'colon separated list of search directories';
+ };
+ arg = {
+ arg_type = 'char const*';
+ arg_name = 'file';
+ arg_desc = 'the name of the file to look for';
+ };
+ arg = {
+ arg_type = 'char const*';
+ arg_name = 'mode';
+ arg_desc = 'the mode bits that must be set to match';
+ };
+ ret_type = 'char*';
+ ret_desc = 'the path to the located file';
+ doc =
+'pathfind looks for a a file with name "FILE" and "MODE" access
+along colon delimited "PATH", and returns the full pathname as a
+string, or NULL if not found. If "FILE" contains a slash, then
+it is treated as a relative or absolute path and "PATH" is ignored.
+
+@strong{NOTE}: this function is compiled into @file{libopts} only if
+it is not natively supplied.
+
+The "MODE" argument is a string of option letters chosen from the
+list below:
+@example
+Letter Meaning
+r readable
+w writable
+x executable
+f normal file (NOT IMPLEMENTED)
+b block special (NOT IMPLEMENTED)
+c character special (NOT IMPLEMENTED)
+d directory (NOT IMPLEMENTED)
+p FIFO (pipe) (NOT IMPLEMENTED)
+u set user ID bit (NOT IMPLEMENTED)
+g set group ID bit (NOT IMPLEMENTED)
+k sticky bit (NOT IMPLEMENTED)
+s size nonzero (NOT IMPLEMENTED)
+@end example';
+ example =
+'To find the "ls" command using the "PATH" environment variable:
+@example
+#include <stdlib.h>
+char* pz_ls = pathfind( getenv("PATH"), "ls", "rx" );
+<<do whatever with pz_ls>>
+free( pz_ls );
+@end example
+The path is allocated with @code{malloc(3C)}, so you must @code{free(3C)}
+the result. Also, do not use unimplemented file modes. :-)';
+ err = 'returns NULL if the file is not found.';
+ srcfile = '../compat/pathfind.c';
+ linenum = '29';
+};
+
+
+#line 209 "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 = '209';
+};
+
+
+#line 119 "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 = '119';
+};
+
+
+#line 156 "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 = '156';
+};
+
+
+#line 78 "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 = '78';
+};
+
+
+#line 235 "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 = '235';
+};
+
+
+#line 244 "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 <mylib.h>
+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 = '244';
+};
+
+
+#line 317 "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 = '317';
+};
+vers-curr = "147461";
+vers-min = "102400";
+vers-min-str = "25:0:0";
+vers-sovers = "36:5:11";
+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..2762088
--- /dev/null
+++ b/autoopts/genshell.c
@@ -0,0 +1,452 @@
+/* -*- buffer-read-only: t -*- vi: set ro:
+ *
+ * DO NOT EDIT THIS FILE (genshell.c)
+ *
+ * It has been AutoGen-ed August 11, 2012 at 09:41:14 AM by AutoGen 5.16.2pre7
+ * From the definitions genshell.def
+ * and the template file options
+ *
+ * Generated from AutoOpts 36:5:11 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-2012 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>
+ *
+ * genshellopt is free software: you can 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.
+ *
+ * genshellopt is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __doxygen__
+#define OPTION_CODE_COMPILE 1
+#include "genshell.h"
+#include <sys/types.h>
+
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern FILE * option_usage_fp;
+
+/* TRANSLATORS: choose the translation for option names wisely because you
+ cannot ever change your mind. */
+#define zCopyright (genshellopt_opt_strs+0)
+#define zLicenseDescrip (genshellopt_opt_strs+260)
+
+extern tUsageProc genshelloptUsage;
+
+#ifndef NULL
+# define NULL 0
+#endif
+
+/*
+ * genshellopt option static const strings
+ */
+static char const genshellopt_opt_strs[1690] =
+/* 0 */ "genshellopt 1\n"
+ "Copyright (C) 1999-2012 Bruce Korb, all rights reserved.\n"
+ "This is free software. It is licensed for use, modification and\n"
+ "redistribution under the terms of the\n"
+ "GNU General Public License, version 3 or later\n"
+ " <http://gnu.org/licenses/gpl.html>\n\0"
+/* 260 */ "genshellopt is free software: you can redistribute it and/or modify it\n"
+ "under 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"
+ "genshellopt 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 General Public License for\n"
+ "more details.\n\n"
+ "You should have received a copy of the GNU General Public License along\n"
+ "with this program. If not, see <http://www.gnu.org/licenses/>.\n\0"
+/* 871 */ "Output Script File\0"
+/* 890 */ "SCRIPT\0"
+/* 897 */ "script\0"
+/* 904 */ "Shell name (follows \"#!\" magic)\0"
+/* 936 */ "SHELL\0"
+/* 942 */ "no-shell\0"
+/* 951 */ "no\0"
+/* 954 */ "Display extended usage information and exit\0"
+/* 998 */ "help\0"
+/* 1003 */ "Extended usage information passed thru pager\0"
+/* 1048 */ "more-help\0"
+/* 1058 */ "Output version information and exit\0"
+/* 1094 */ "version\0"
+/* 1102 */ "GENSHELLOPT\0"
+/* 1114 */ "genshellopt - Generate Shell Option Processing Script - Ver. 1\n"
+ "USAGE: %s [ -<flag> [<val>] | --<name>[{=| }<val>] ]...\n\0"
+/* 1235 */ "autogen-users@lists.sourceforge.net\0"
+/* 1271 */ "\n"
+ "Note that ``shell'' is only useful if the output file does not already\n"
+ "exist. If it does, then the shell name and optional first argument will be\n"
+ "extracted from the script file.\n\0"
+/* 1452 */ "\n"
+ "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"
+/* 1676 */ "genshellopt 1";
+
+/*
+ * script option description:
+ */
+#define SCRIPT_DESC (genshellopt_opt_strs+871)
+#define SCRIPT_NAME (genshellopt_opt_strs+890)
+#define SCRIPT_name (genshellopt_opt_strs+897)
+#define SCRIPT_FLAGS (OPTST_DISABLED \
+ | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
+
+/*
+ * shell option description:
+ */
+#define SHELL_DESC (genshellopt_opt_strs+904)
+#define SHELL_NAME (genshellopt_opt_strs+936)
+#define NOT_SHELL_name (genshellopt_opt_strs+942)
+#define NOT_SHELL_PFX (genshellopt_opt_strs+951)
+#define SHELL_name (NOT_SHELL_name + 3)
+#define SHELL_FLAGS (OPTST_INITENABLED \
+ | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING))
+
+/*
+ * Help/More_Help/Version option descriptions:
+ */
+#define HELP_DESC (genshellopt_opt_strs+954)
+#define HELP_name (genshellopt_opt_strs+998)
+#ifdef HAVE_WORKING_FORK
+#define MORE_HELP_DESC (genshellopt_opt_strs+1003)
+#define MORE_HELP_name (genshellopt_opt_strs+1048)
+#define MORE_HELP_FLAGS (OPTST_IMM | OPTST_NO_INIT)
+#else
+#define MORE_HELP_DESC NULL
+#define MORE_HELP_name NULL
+#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+1058)
+#define VER_name (genshellopt_opt_strs+1094)
+/*
+ * 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, 0,
+ /* 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, 0,
+ /* 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, 0,
+ /* 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 }
+};
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * Define the genshellopt Option Environment
+ */
+#define zPROGNAME (genshellopt_opt_strs+1102)
+#define zUsageTitle (genshellopt_opt_strs+1114)
+#define zRcName NULL
+#define apzHomeList NULL
+#define zBugsAddr (genshellopt_opt_strs+1235)
+#define zExplain (genshellopt_opt_strs+1271)
+#define zDetail (genshellopt_opt_strs+1452)
+#define zFullVersion (genshellopt_opt_strs+1676)
+/* extracted from optcode.tlib near line 350 */
+
+#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 pOptions the AutoOpts option description structure
+ * @param pOptDesc the descriptor for the "help" (usage) option.
+ * @noreturn
+ */
+static void
+doUsageOpt(tOptions * pOptions, tOptDesc * pOptDesc)
+{
+ genshelloptUsage(&genshelloptOptions, GENSHELLOPT_EXIT_SUCCESS);
+ /* NOTREACHED */
+ (void)pOptDesc;
+ (void)pOptions;
+}
+/* extracted from optmain.tlib near line 1146 */
+
+/**
+ * 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
+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
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <autoopts/usage-txt.h>
+
+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.
+ *
+ * @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* pzRes;
+ if (pz == NULL)
+ return NULL;
+ pzRes = _(pz);
+ if (pzRes == pz)
+ return pzRes;
+ pzRes = strdup(pzRes);
+ if (pzRes == NULL) {
+ fputs(_("No memory for duping translated strings\n"), stderr);
+ exit(GENSHELLOPT_EXIT_FAILURE);
+ }
+ return pzRes;
+}
+
+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 pOpt = &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_usage_text.field_ct != 0) {
+ /*
+ * Do the translations. The first pointer follows the field count
+ * field. The field count field is the size of a pointer.
+ */
+ tOptDesc * pOD = pOpt->pOptDesc;
+ char ** ppz = (char**)(void*)&(option_usage_text);
+ int ix = option_usage_text.field_ct;
+
+ do {
+ ppz++;
+ *ppz = AO_gettext(*ppz);
+ } while (--ix > 0);
+
+ coerce_it((void*)&(pOpt->pzCopyright));
+ coerce_it((void*)&(pOpt->pzCopyNotice));
+ coerce_it((void*)&(pOpt->pzFullVersion));
+ coerce_it((void*)&(pOpt->pzUsageTitle));
+ coerce_it((void*)&(pOpt->pzExplain));
+ coerce_it((void*)&(pOpt->pzDetail));
+ coerce_it((void*)&(pOpt->pzPackager));
+ option_usage_text.field_ct = 0;
+
+ for (ix = pOpt->optCt; ix > 0; ix--, pOD++)
+ coerce_it((void*)&(pOD->pzText));
+ }
+
+ if ((pOpt->fOptSet & OPTPROC_NXLAT_OPT_CFG) == 0) {
+ tOptDesc * pOD = pOpt->pOptDesc;
+ int ix;
+
+ for (ix = pOpt->optCt; ix > 0; ix--, pOD++) {
+ coerce_it((void*)&(pOD->pz_Name));
+ coerce_it((void*)&(pOD->pz_DisableName));
+ coerce_it((void*)&(pOD->pz_DisablePfx));
+ }
+ /* prevent re-translation */
+ genshelloptOptions.fOptSet |= OPTPROC_NXLAT_OPT_CFG | OPTPROC_NXLAT_OPT;
+ }
+}
+
+#endif /* ENABLE_NLS */
+
+#ifdef __cplusplus
+}
+#endif
+/* genshell.c ends here */
diff --git a/autoopts/genshell.def b/autoopts/genshell.def
new file mode 100644
index 0000000..e679b5f
--- /dev/null
+++ b/autoopts/genshell.def
@@ -0,0 +1,79 @@
+
+autogen definitions options;
+
+/**
+ * \file genshell.def
+ *
+ * Time-stamp: "2012-01-29 13:32:43 bkorb"
+ *
+ * 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-2012 by Bruce Korb - all rights reserved
+ * Genshell is free software.
+ * This file is part of AutoGen.
+ *
+ * AutoGen copyright (c) 1992-2012 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/>.
+ */
+
+copyright = {
+ date = "1999-2012";
+ owner = "Bruce Korb";
+ eaddr = "autogen-users@lists.sourceforge.net";
+ type = gpl;
+};
+
+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_;
diff --git a/autoopts/genshell.h b/autoopts/genshell.h
new file mode 100644
index 0000000..2b28efb
--- /dev/null
+++ b/autoopts/genshell.h
@@ -0,0 +1,184 @@
+/* -*- buffer-read-only: t -*- vi: set ro:
+ *
+ * DO NOT EDIT THIS FILE (genshell.h)
+ *
+ * It has been AutoGen-ed August 11, 2012 at 09:41:14 AM by AutoGen 5.16.2pre7
+ * From the definitions genshell.def
+ * and the template file options
+ *
+ * Generated from AutoOpts 36:5:11 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-2012 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>
+ *
+ * genshellopt is free software: you can 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.
+ *
+ * genshellopt is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+/*
+ * This file contains the 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 <autoopts/options.h>
+
+/*
+ * 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 147461
+#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
+
+/*
+ * Enumeration of each option:
+ */
+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;
+
+#define GENSHELL_OPTION_CT 5
+#define GENSHELLOPT_VERSION "1"
+#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])
+#define HAVE_GENSHELL_OPT(n) (! UNUSED_OPT(& GENSHELL_DESC(n)))
+#define GENSHELL_OPT_ARG(n) (GENSHELL_DESC(n).optArg.argString)
+#define STATE_GENSHELL_OPT(n) (GENSHELL_DESC(n).fOptState & OPTST_SET_MASK)
+#define COUNT_GENSHELL_OPT(n) (GENSHELL_DESC(n).optOccCt)
+#define ISSEL_GENSHELL_OPT(n) (SELECTED_OPT(&GENSHELL_DESC(n)))
+#define ISUNUSED_GENSHELL_OPT(n) (UNUSED_OPT(& GENSHELL_DESC(n)))
+#define ENABLED_GENSHELL_OPT(n) (! DISABLED_OPT(& GENSHELL_DESC(n)))
+#define STACKCT_GENSHELL_OPT(n) (((tArgList*)(GENSHELL_DESC(n).optCookie))->useCt)
+#define STACKLST_GENSHELL_OPT(n) (((tArgList*)(GENSHELL_DESC(n).optCookie))->apzArgs)
+#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_LIBOPTS_FAILURE = 70
+} genshellopt_exit_code_t;
+/* * * * * *
+ *
+ * Interface defines for specific options.
+ */
+#define VALUE_GENSHELL_OPT_SCRIPT 'o'
+#define VALUE_GENSHELL_OPT_SHELL 's'
+#define VALUE_GENSHELL_OPT_HELP '?'
+#define VALUE_GENSHELL_OPT_MORE_HELP '!'
+#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)
+/* extracted from opthead.tlib near line 484 */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* * * * * *
+ *
+ * Declare the genshellopt option descriptor.
+ */
+extern tOptions genshelloptOptions;
+
+#if defined(ENABLE_NLS)
+# ifndef _
+# include <stdio.h>
+# ifndef HAVE_GETTEXT
+ extern char * gettext(char const *);
+# else
+# include <libintl.h>
+# endif
+
+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..151ba4f
--- /dev/null
+++ b/autoopts/gettext.h
@@ -0,0 +1,288 @@
+/* Convenience header for conditional use of GNU <libintl.h>.
+ Copyright (C) 1995-1998, 2000-2002, 2004-2006, 2009-2012 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 <http://www.gnu.org/licenses/>. */
+
+#ifndef _LIBGETTEXT_H
+#define _LIBGETTEXT_H 1
+
+/* NLS can be disabled through the configure --disable-nls option. */
+#if ENABLE_NLS
+
+/* Get declarations of GNU message catalog functions. */
+# include <libintl.h>
+
+/* 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 <locale.h> a NOP. We don't include <libintl.h>
+ as well because people using "gettext.h" will not include <libintl.h>,
+ and also including <libintl.h> would fail on SunOS 4, whereas <locale.h>
+ is OK. */
+#if defined(__sun)
+# include <locale.h>
+#endif
+
+/* Many header files from the libstdc++ coming with g++ 3.3 or newer include
+ <libintl.h>, which chokes if dcgettext is defined as a macro. So include
+ it now, to make later inclusions of <libintl.h> a NOP. */
+#if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3)
+# include <cstdlib>
+# if (__GLIBC__ >= 2 && !defined __UCLIBC__) || _GLIBCXX_HAVE_LIBINTL_H
+# include <libintl.h>
+# 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 <string.h>
+
+#if (((__GNUC__ >= 3 || __GNUG__ >= 2) && !defined __STRICT_ANSI__) \
+ /* || __STDC_VERSION__ >= 199901L */ )
+# define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 1
+#else
+# define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS 0
+#endif
+
+#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
+#include <stdlib.h>
+#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
+ {
+ 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);
+#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
+ if (msg_ctxt_id != buf)
+ free (msg_ctxt_id);
+#endif
+ if (translation != msg_ctxt_id)
+ 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
+ {
+ 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);
+#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
+ if (msg_ctxt_id != buf)
+ free (msg_ctxt_id);
+#endif
+ if (!(translation == msg_ctxt_id || translation == msgid_plural))
+ return translation;
+ }
+ return (n == 1 ? msgid : msgid_plural);
+}
+
+#endif /* _LIBGETTEXT_H */
diff --git a/autoopts/install-hook.sh b/autoopts/install-hook.sh
new file mode 100644
index 0000000..a987b7b
--- /dev/null
+++ b/autoopts/install-hook.sh
@@ -0,0 +1,124 @@
+#! /bin/sh
+
+# Time-stamp: "2012-08-11 08:13:30 bkorb"
+#
+## This file is part of AutoOpts, a companion to AutoGen.
+## AutoOpts is free software.
+## AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
+
+egrep '#undef +AUTOOPTS_ENABLED' ${top_builddir}/config.h >/dev/null && \
+ exit 0
+
+srcdir=`dirname $0`
+srcdir=`cd ${srcdir} ; pwd`
+
+. ${top_builddir}/autoopts/test/defs
+
+test -z "${POSIX_SHELL}" && exit 1
+
+rm -f ${DESTdestdir}/options.h
+opthdrsrc=${srcdir}/autoopts/options.h
+cfgf=${top_builddir}/config.h
+
+{
+ sed '/^#include <stdio/q' ${opthdrsrc}
+
+ if ${EGREP} 'define +HAVE_STDINT_H' ${cfgf} >/dev/null
+ then echo '#include <stdint.h>'
+ else echo '#include <inttypes.h>' ; fi
+
+ if ${EGREP} 'define +HAVE_LIMITS_H' ${cfgf} >/dev/null
+ then echo '#include <limits.h>'
+ else echo '#include <sys/limits.h>' ; fi
+
+ if ${EGREP} 'define +HAVE_STDBOOL_H' ${cfgf} >/dev/null
+ then echo '#include <stdbool.h>'
+ 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}
+} > ${DESTdestdir}/options.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
+ optlib.tlib | getopt.tpl | usage.tlib | cmd-doc.tlib | \
+ agtexi-cmd.tpl | agman1.tpl | aginfo.tpl )
+ sed "${rmbuild}" $f > $f.tmp
+ mv -f $f.tmp $f
+ ;;
+
+ *.* ) : ;;
+ * )
+ 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/load.c b/autoopts/load.c
new file mode 100644
index 0000000..06b0079
--- /dev/null
+++ b/autoopts/load.c
@@ -0,0 +1,519 @@
+
+/**
+ * \file load.c
+ * Time-stamp: "2012-08-11 08:20:09 bkorb"
+ *
+ * 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.
+ *
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+ *
+ * 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+ * 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+ * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
+ */
+
+/* = = = START-STATIC-FORWARD = = = */
+static bool
+add_prog_path(char * pzBuf, int bufSize, char const * pzName,
+ char const * pzProgPath);
+
+static bool
+add_env_val(char * buf, int buf_sz, char const * name);
+
+static char *
+assemble_arg_val(char * txt, tOptionLoadMode mode);
+/* = = = END-STATIC-FORWARD = = = */
+
+/*=export_func optionMakePath
+ * private:
+ *
+ * what: translate and construct a path
+ * arg: + char* + pzBuf + The result buffer +
+ * arg: + int + bufSize + The size of this buffer +
+ * arg: + char const* + pzName + The input name +
+ * arg: + char const* + pzProgPath + 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 * pzBuf, int bufSize, char const * pzName,
+ char const * pzProgPath)
+{
+ size_t name_len = strlen(pzName);
+
+ if (((size_t)bufSize <= name_len) || (name_len == 0))
+ return false;
+
+ /*
+ * IF not an environment variable, just copy the data
+ */
+ if (*pzName != '$') {
+ char const* pzS = pzName;
+ char* pzD = pzBuf;
+ int ct = bufSize;
+
+ for (;;) {
+ if ( (*(pzD++) = *(pzS++)) == 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 (pzName[1]) {
+ case NUL:
+ return false;
+
+ case '$':
+ if (! add_prog_path(pzBuf, bufSize, pzName, pzProgPath))
+ return false;
+ break;
+
+ case '@':
+ if (program_pkgdatadir[0] == NUL)
+ return false;
+
+ if (snprintf(pzBuf, bufSize, "%s%s", program_pkgdatadir, pzName + 2)
+ >= bufSize)
+ return false;
+ break;
+
+ default:
+ if (! add_env_val(pzBuf, bufSize, pzName))
+ return false;
+ }
+
+#if defined(HAVE_CANONICALIZE_FILE_NAME)
+ {
+ char * pz = canonicalize_file_name(pzBuf);
+ if (pz == NULL)
+ return false;
+
+ name_len = strlen(pz);
+ if (name_len >= (size_t)bufSize) {
+ free(pz);
+ return false;
+ }
+
+ memcpy(pzBuf, pz, name_len + 1);
+ free(pz);
+ }
+
+#elif defined(HAVE_REALPATH)
+ {
+ char z[PATH_MAX+1];
+
+ if (realpath(pzBuf, z) == NULL)
+ return false;
+
+ name_len = strlen(z);
+ if (name_len >= bufSize)
+ return false;
+
+ memcpy(pzBuf, z, name_len + 1);
+ }
+#endif
+
+ return true;
+}
+
+static bool
+add_prog_path(char * pzBuf, int bufSize, char const * pzName,
+ char const * pzProgPath)
+{
+ char const* pzPath;
+ char const* pz;
+ int skip = 2;
+
+ switch (pzName[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(pzProgPath, DIRCH) != NULL)
+ pzPath = pzProgPath;
+ else {
+ pzPath = pathfind(getenv("PATH"), (char*)pzProgPath, "rx");
+
+ if (pzPath == NULL)
+ return false;
+ }
+
+ pz = strrchr(pzPath, 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;
+
+ pzName += skip;
+
+ /*
+ * Concatenate the file name to the end of the executable path.
+ * The result may be either a file or a directory.
+ */
+ if ((pz - pzPath)+1 + strlen(pzName) >= (unsigned)bufSize)
+ return false;
+
+ memcpy(pzBuf, pzPath, (size_t)((pz - pzPath)+1));
+ strcpy(pzBuf + (pz - pzPath) + 1, pzName);
+
+ /*
+ * If the "pzPath" path was gotten from "pathfind()", then it was
+ * allocated and we need to deallocate it.
+ */
+ if (pzPath != pzProgPath)
+ AGFREE(pzPath);
+ return true;
+}
+
+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;
+
+ if (strlen(dir_part) + 1 + strlen(name) >= (unsigned)buf_sz)
+ return false;
+
+ sprintf(buf, "%s%s", dir_part, name);
+ return true;
+}
+
+LOCAL void
+mungeString(char * txt, tOptionLoadMode mode)
+{
+ char * pzE;
+
+ if (mode == OPTION_LOAD_KEEP)
+ return;
+
+ if (IS_WHITESPACE_CHAR(*txt)) {
+ char * pzS = SPN_WHITESPACE_CHARS(txt+1);
+ size_t l = strlen(pzS) + 1;
+ memmove(txt, pzS, l);
+ pzE = txt + l - 1;
+
+ } else
+ pzE = txt + strlen(txt);
+
+ pzE = SPN_WHITESPACE_BACK(txt, pzE);
+ *pzE = NUL;
+
+ if (mode == OPTION_LOAD_UNCOOKED)
+ return;
+
+ switch (*txt) {
+ default: return;
+ case '"':
+ case '\'': break;
+ }
+
+ switch (pzE[-1]) {
+ default: return;
+ case '"':
+ case '\'': break;
+ }
+
+ (void)ao_string_cook(txt, NULL);
+}
+
+static char *
+assemble_arg_val(char * txt, tOptionLoadMode mode)
+{
+ char* pzEnd = strpbrk(txt, ARG_BREAK_STR);
+ int space_break;
+
+ /*
+ * Not having an argument to a configurable name is okay.
+ */
+ if (pzEnd == 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) {
+ *(pzEnd++) = NUL;
+ return pzEnd;
+ }
+
+ /*
+ * 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(*pzEnd);
+ *(pzEnd++) = NUL;
+
+ pzEnd = SPN_WHITESPACE_CHARS(pzEnd);
+ if (space_break && ((*pzEnd == ':') || (*pzEnd == '=')))
+ pzEnd = SPN_WHITESPACE_CHARS(pzEnd+1);
+
+ return pzEnd;
+}
+
+/**
+ * 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_*)
+ */
+LOCAL void
+loadOptionLine(
+ tOptions * opts,
+ tOptState * opt_state,
+ char * line,
+ tDirection direction,
+ tOptionLoadMode load_mode )
+{
+ line = SPN_LOAD_LINE_SKIP_CHARS(line);
+
+ {
+ char * arg = assemble_arg_val(line, load_mode);
+
+ if (! SUCCESSFUL(opt_find_long(opts, line, opt_state)))
+ return;
+
+ if (opt_state->flags & OPTST_NO_INIT)
+ return;
+
+ opt_state->pzOptArg = arg;
+ }
+
+ switch (opt_state->flags & (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(direction))
+ return;
+ break;
+
+ case OPTST_IMM:
+ if (PRESETTING(direction)) {
+ /*
+ * We are in the presetting direction with an option we handle
+ * immediately for enablement, but normally for disablement.
+ * Therefore, skip if disabled.
+ */
+ if ((opt_state->flags & OPTST_DISABLED) == 0)
+ return;
+ } 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 ((opt_state->flags & OPTST_DISABLED) != 0)
+ return;
+ }
+ break;
+
+ case OPTST_DISABLE_IMM:
+ if (PRESETTING(direction)) {
+ /*
+ * We are in the presetting direction with an option we handle
+ * immediately for disablement, but normally for disablement.
+ * Therefore, skip if NOT disabled.
+ */
+ if ((opt_state->flags & OPTST_DISABLED) != 0)
+ return;
+ } else {
+ /*
+ * We are in the processing direction with an option we handle
+ * immediately for disablement, but normally for disablement.
+ * Therefore, skip if disabled.
+ */
+ if ((opt_state->flags & OPTST_DISABLED) == 0)
+ return;
+ }
+ 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(direction))
+ return;
+ break;
+ }
+
+ /*
+ * 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;
+ AGDUPSTR(pz, line, "user option line");
+ loadOptionLine(opts, &st, pz, DIRECTION_PROCESS, OPTION_LOAD_COOKED);
+ AGFREE(pz);
+}
+/*
+ * 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..5ba949d
--- /dev/null
+++ b/autoopts/makeshell.c
@@ -0,0 +1,873 @@
+
+/**
+ * \file makeshell.c
+ *
+ * Time-stamp: "2012-08-11 08:51:32 bkorb"
+ *
+ * This module will interpret the options set in the tOptions
+ * structure and create a Bourne shell script capable of parsing them.
+ *
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+ *
+ * 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+ * 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+ * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
+ */
+
+tOptions * optionParseShellOptions = NULL;
+
+static char const * shell_prog = NULL;
+static char * script_leader = NULL;
+static char * script_trailer = NULL;
+static char * script_text = NULL;
+
+/* = = = START-STATIC-FORWARD = = = */
+static void
+emit_var_text(char const * prog, char const * var, int fdin);
+
+static void
+text_to_var(tOptions * pOpts, teTextTo whichVar, tOptDesc * pOD);
+
+static void
+emit_usage(tOptions * pOpts);
+
+static void
+emit_setup(tOptions * pOpts);
+
+static void
+emit_action(tOptions * pOpts, tOptDesc* pOptDesc);
+
+static void
+emit_inaction(tOptions * pOpts, tOptDesc* pOptDesc);
+
+static void
+emit_flag(tOptions * pOpts);
+
+static void
+emit_match_expr(char const * pzMatchName, tOptDesc* pCurOpt, tOptions* pOpts);
+
+static void
+emit_long(tOptions * pOpts);
+
+static char *
+load_old_output(char const * fname);
+
+static void
+open_out(char const * fname);
+/* = = = END-STATIC-FORWARD = = = */
+
+/*=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 * pOpts)
+{
+ /*
+ * 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));
+
+ emit_usage(pOpts);
+ emit_setup(pOpts);
+
+ /*
+ * There are four modes of option processing.
+ */
+ switch (pOpts->fOptSet & (OPTPROC_LONGOPT|OPTPROC_SHORTOPT)) {
+ case OPTPROC_LONGOPT:
+ fputs(LOOP_STR, stdout);
+
+ fputs(LONG_OPT_MARK, stdout);
+ fputs(INIT_LOPT_STR, stdout);
+ emit_long(pOpts);
+ printf(LOPT_ARG_FMT, pOpts->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(pOpts);
+ printf(LOPT_ARG_FMT, pOpts->pzPROGNAME);
+ break;
+
+ case OPTPROC_SHORTOPT:
+ fputs(LOOP_STR, stdout);
+
+ fputs(FLAG_OPT_MARK, stdout);
+ fputs(INIT_OPT_STR, stdout);
+ emit_flag(pOpts);
+ printf(OPT_ARG_FMT, pOpts->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(pOpts);
+ printf(LOPT_ARG_FMT, pOpts->pzPROGNAME);
+ fputs(END_OPT_SEL_STR, stdout);
+
+ fputs(FLAG_OPT_MARK, stdout);
+ fputs(INIT_OPT_STR, stdout);
+ emit_flag(pOpts);
+ printf(OPT_ARG_FMT, pOpts->pzPROGNAME);
+ fputs(END_OPT_SEL_STR, stdout);
+
+ fputs(NOT_FOUND_STR, stdout);
+ break;
+ }
+
+ printf(zLoopEnd, pOpts->pzPROGNAME, END_MARK);
+ if ((script_trailer != NULL) && (*script_trailer != NUL))
+ fputs(script_trailer, stdout);
+ else if (ENABLED_GENSHELL_OPT(SHELL))
+ printf(SHOW_PROG_ENV, pOpts->pzPROGNAME);
+
+#ifdef HAVE_FCHMOD
+ fchmod(STDOUT_FILENO, 0755);
+#endif
+ fclose(stdout);
+
+ if (ferror(stdout)) {
+ fputs(zOutputFail, stderr);
+ exit(EXIT_FAILURE);
+ }
+
+ AGFREE(script_text);
+ script_leader = NULL;
+ script_trailer = NULL;
+ script_text = NULL;
+}
+
+#ifdef HAVE_WORKING_FORK
+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(apostrophy, stdout);
+ break;
+
+ case EOF:
+ goto endCharLoop;
+
+ default:
+ while (nlct > 0) {
+ fputc(NL, stdout);
+ nlct--;
+ }
+ fputc(ch, stdout);
+ break;
+ }
+ } endCharLoop:;
+
+ 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.
+ */
+static void
+text_to_var(tOptions * pOpts, teTextTo whichVar, tOptDesc * pOD)
+{
+# define _TT_(n) static char const z ## n [] = #n;
+ TEXTTO_TABLE
+# undef _TT_
+# define _TT_(n) z ## n ,
+ static char const * apzTTNames[] = { TEXTTO_TABLE };
+# undef _TT_
+
+#if ! defined(HAVE_WORKING_FORK)
+ printf(SET_NO_TEXT_FMT, pOpts->pzPROGNAME, apzTTNames[ whichVar]);
+#else
+ int pipeFd[2];
+
+ fflush(stdout);
+ fflush(stderr);
+
+ if (pipe(pipeFd) != 0) {
+ fprintf(stderr, zBadPipe, errno, strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ switch (fork()) {
+ case -1:
+ fprintf(stderr, zForkFail, errno, strerror(errno), pOpts->pzProgName);
+ exit(EXIT_FAILURE);
+ break;
+
+ 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(pipeFd[1], STDERR_FILENO);
+ dup2(pipeFd[1], STDOUT_FILENO);
+ close(pipeFd[0]);
+
+ switch (whichVar) {
+ case TT_LONGUSAGE:
+ (*(pOpts->pUsageProc))(pOpts, EXIT_SUCCESS);
+ /* NOTREACHED */
+
+ case TT_USAGE:
+ (*(pOpts->pUsageProc))(pOpts, EXIT_FAILURE);
+ /* NOTREACHED */
+
+ case TT_VERSION:
+ if (pOD->fOptState & OPTST_ALLOC_ARG) {
+ AGFREE(pOD->optArg.argString);
+ pOD->fOptState &= ~OPTST_ALLOC_ARG;
+ }
+ pOD->optArg.argString = "c";
+ optionPrintVersion(pOpts, pOD);
+ /* NOTREACHED */
+
+ default:
+ exit(EXIT_FAILURE);
+ }
+
+ default:
+ close(pipeFd[1]);
+ }
+
+ emit_var_text(pOpts->pzPROGNAME, apzTTNames[whichVar], pipeFd[0]);
+#endif
+}
+
+
+static void
+emit_usage(tOptions * pOpts)
+{
+ char zTimeBuf[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(zTimeBuf, 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, zTimeBuf);
+ }
+
+ printf(END_PRE_FMT, pOpts->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 = zTimeBuf;
+ char const * pz = pOpts->pzPROGNAME;
+ char ** pp;
+
+ for (;;) {
+ if ((*pzPN++ = (char)tolower(*pz++)) == NUL)
+ break;
+ }
+
+ pp = (char **)(void *)&(pOpts->pzProgPath);
+ *pp = zTimeBuf;
+ pp = (char **)(void *)&(pOpts->pzProgName);
+ *pp = zTimeBuf;
+ }
+
+ text_to_var(pOpts, TT_LONGUSAGE, NULL);
+ text_to_var(pOpts, TT_USAGE, NULL);
+
+ {
+ tOptDesc* pOptDesc = pOpts->pOptDesc;
+ int optionCt = pOpts->optCt;
+
+ for (;;) {
+ if (pOptDesc->pOptProc == optionPrintVersion) {
+ text_to_var(pOpts, TT_VERSION, pOptDesc);
+ break;
+ }
+
+ if (--optionCt <= 0)
+ break;
+ pOptDesc++;
+ }
+ }
+}
+
+
+static void
+emit_setup(tOptions * pOpts)
+{
+ tOptDesc * pOptDesc = pOpts->pOptDesc;
+ int optionCt = pOpts->presetOptCt;
+ char const * pzFmt;
+ char const * pzDefault;
+
+ for (;optionCt > 0; pOptDesc++, --optionCt) {
+ char zVal[32];
+
+ /*
+ * Options that are either usage documentation or are compiled out
+ * are not to be processed.
+ */
+ if (SKIP_OPT(pOptDesc) || (pOptDesc->pz_NAME == NULL))
+ continue;
+
+ if (pOptDesc->optMaxCt > 1)
+ pzFmt = MULTI_DEF_FMT;
+ else pzFmt = 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(pOptDesc->fOptState)) {
+ case OPARG_TYPE_ENUMERATION:
+ (*(pOptDesc->pOptProc))(OPTPROC_EMIT_SHELL, pOptDesc );
+ pzDefault = pOptDesc->optArg.argString;
+ break;
+
+ /*
+ * Numeric and membership bit options are just printed as a number.
+ */
+ case OPARG_TYPE_NUMERIC:
+ snprintf(zVal, sizeof(zVal), "%d",
+ (int)pOptDesc->optArg.argInt);
+ pzDefault = zVal;
+ break;
+
+ case OPARG_TYPE_MEMBERSHIP:
+ snprintf(zVal, sizeof(zVal), "%lu",
+ (unsigned long)pOptDesc->optArg.argIntptr);
+ pzDefault = zVal;
+ break;
+
+ case OPARG_TYPE_BOOLEAN:
+ pzDefault = (pOptDesc->optArg.argBool) ? TRUE_STR : FALSE_STR;
+ break;
+
+ default:
+ if (pOptDesc->optArg.argString == NULL) {
+ if (pzFmt == SGL_DEF_FMT)
+ pzFmt = SGL_NO_DEF_FMT;
+ pzDefault = NULL;
+ }
+ else
+ pzDefault = pOptDesc->optArg.argString;
+ }
+
+ printf(pzFmt, pOpts->pzPROGNAME, pOptDesc->pz_NAME, pzDefault);
+ }
+}
+
+static void
+emit_action(tOptions * pOpts, tOptDesc* pOptDesc)
+{
+ if (pOptDesc->pOptProc == optionPrintVersion)
+ printf(zTextExit, pOpts->pzPROGNAME, VER_STR);
+
+ else if (pOptDesc->pOptProc == optionPagedUsage)
+ printf(zPagedUsageExit, pOpts->pzPROGNAME);
+
+ else if (pOptDesc->pOptProc == optionLoadOpt) {
+ printf(zCmdFmt, NO_LOAD_WARN);
+ printf(zCmdFmt, YES_NEED_OPT_ARG);
+
+ } else if (pOptDesc->pz_NAME == NULL) {
+
+ if (pOptDesc->pOptProc == NULL) {
+ printf(zCmdFmt, NO_SAVE_OPTS);
+ printf(zCmdFmt, OK_NEED_OPT_ARG);
+ } else
+ printf(zTextExit, pOpts->pzPROGNAME, LONG_USE_STR);
+
+ } else {
+ if (pOptDesc->optMaxCt == 1)
+ printf(SGL_ARG_FMT, pOpts->pzPROGNAME, pOptDesc->pz_NAME);
+ else {
+ if ((unsigned)pOptDesc->optMaxCt < NOLIMIT)
+ printf(zCountTest, pOpts->pzPROGNAME,
+ pOptDesc->pz_NAME, pOptDesc->optMaxCt);
+
+ printf(MULTI_ARG_FMT, pOpts->pzPROGNAME, pOptDesc->pz_NAME);
+ }
+
+ /*
+ * Fix up the args.
+ */
+ if (OPTST_GET_ARGTYPE(pOptDesc->fOptState) == OPARG_TYPE_NONE) {
+ printf(zCantArg, pOpts->pzPROGNAME, pOptDesc->pz_NAME);
+
+ } else if (pOptDesc->fOptState & OPTST_ARG_OPTIONAL) {
+ printf(zMayArg, pOpts->pzPROGNAME, pOptDesc->pz_NAME);
+
+ } else {
+ fputs(zMustArg, stdout);
+ }
+ }
+ fputs(zOptionEndSelect, stdout);
+}
+
+
+static void
+emit_inaction(tOptions * pOpts, tOptDesc* pOptDesc)
+{
+ if (pOptDesc->pOptProc == optionLoadOpt) {
+ printf(zCmdFmt, NO_SUPPRESS_LOAD);
+
+ } else if (pOptDesc->optMaxCt == 1)
+ printf(NO_SGL_ARG_FMT, pOpts->pzPROGNAME,
+ pOptDesc->pz_NAME, pOptDesc->pz_DisablePfx);
+ else
+ printf(NO_MULTI_ARG_FMT, pOpts->pzPROGNAME,
+ pOptDesc->pz_NAME, pOptDesc->pz_DisablePfx);
+
+ printf(zCmdFmt, NO_ARG_NEEDED);
+ fputs(zOptionEndSelect, stdout);
+}
+
+
+static void
+emit_flag(tOptions * pOpts)
+{
+ tOptDesc* pOptDesc = pOpts->pOptDesc;
+ int optionCt = pOpts->optCt;
+
+ fputs(zOptionCase, stdout);
+
+ for (;optionCt > 0; pOptDesc++, --optionCt) {
+
+ if (SKIP_OPT(pOptDesc))
+ continue;
+
+ if (IS_GRAPHIC_CHAR(pOptDesc->optValue)) {
+ printf(zOptionFlag, pOptDesc->optValue);
+ emit_action(pOpts, pOptDesc);
+ }
+ }
+ printf(UNK_OPT_FMT, FLAG_STR, pOpts->pzPROGNAME);
+}
+
+
+/*
+ * Emit the match text for a long option
+ */
+static void
+emit_match_expr(char const * pzMatchName, tOptDesc* pCurOpt, tOptions* pOpts)
+{
+ tOptDesc* pOD = pOpts->pOptDesc;
+ int oCt = pOpts->optCt;
+ int min = 1;
+ char zName[ 256 ];
+ char* pz = zName;
+
+ for (;;) {
+ int matchCt = 0;
+
+ /*
+ * Omit the current option, Documentation opts and compiled out opts.
+ */
+ if ((pOD == pCurOpt) || SKIP_OPT(pOD)){
+ if (--oCt <= 0)
+ break;
+ pOD++;
+ 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 ( toupper(pOD->pz_Name[matchCt])
+ == toupper(pzMatchName[matchCt]))
+ matchCt++;
+
+ if (matchCt > min)
+ min = matchCt;
+
+ /*
+ * Check the disablement name, too.
+ */
+ if (pOD->pz_DisableName != NULL) {
+ matchCt = 0;
+ while ( toupper(pOD->pz_DisableName[matchCt])
+ == toupper(pzMatchName[matchCt]))
+ matchCt++;
+ if (matchCt > min)
+ min = matchCt;
+ }
+ if (--oCt <= 0)
+ break;
+ pOD++;
+ }
+
+ /*
+ * IF the 'min' is all or one short of the name length,
+ * THEN the entire string must be matched.
+ */
+ if ( (pzMatchName[min ] == NUL)
+ || (pzMatchName[min+1] == NUL) )
+ printf(zOptionFullName, pzMatchName);
+
+ else {
+ int matchCt = 0;
+ for (; matchCt <= min; matchCt++)
+ *pz++ = pzMatchName[matchCt];
+
+ for (;;) {
+ *pz = NUL;
+ printf(zOptionPartName, zName);
+ *pz++ = pzMatchName[matchCt++];
+ if (pzMatchName[matchCt] == NUL) {
+ *pz = NUL;
+ printf(zOptionFullName, zName);
+ break;
+ }
+ }
+ }
+}
+
+
+/**
+ * Emit GNU-standard long option handling code.
+ */
+static void
+emit_long(tOptions * pOpts)
+{
+ tOptDesc* pOD = pOpts->pOptDesc;
+ int ct = pOpts->optCt;
+
+ fputs(zOptionCase, stdout);
+
+ /*
+ * do each option, ...
+ */
+ do {
+ /*
+ * Documentation & compiled-out options
+ */
+ if (SKIP_OPT(pOD))
+ continue;
+
+ emit_match_expr(pOD->pz_Name, pOD, pOpts);
+ emit_action(pOpts, pOD);
+
+ /*
+ * Now, do the same thing for the disablement version of the option.
+ */
+ if (pOD->pz_DisableName != NULL) {
+ emit_match_expr(pOD->pz_DisableName, pOD, pOpts);
+ emit_inaction(pOpts, pOD);
+ }
+ } while (pOD++, --ct > 0);
+
+ printf(UNK_OPT_FMT, OPTION_STR, pOpts->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)
+{
+ /*
+ * 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))) {
+ fprintf(stderr, zNotFile, fname);
+ exit(EXIT_FAILURE);
+ }
+
+ scan = text = AGALOC(stbf.st_size + 1, "f data");
+
+ /*
+ * Read in all the data as fast as our OS will let us.
+ */
+ for (;;) {
+ int inct = fread((void*)scan, (size_t)1, stbf.st_size, fp);
+ if (inct == 0)
+ break;
+
+ stbf.st_size -= 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)
+{
+
+ do {
+ char * txt = script_text = load_old_output(fname);
+ 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.
+ */
+ 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) {
+ fprintf(stderr, zFreopenFail, errno, strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+}
+
+
+/*=export_func genshelloptUsage
+ * private:
+ * what: The usage function for the genshellopt generated program
+ *
+ * arg: + tOptions* + pOpts + program options descriptor +
+ * arg: + int + exitCode + 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 * pOpts, int exitCode)
+{
+#if ! defined(HAVE_WORKING_FORK)
+ optionUsage(pOpts, exitCode);
+#else
+ /*
+ * IF not EXIT_SUCCESS,
+ * THEN emit the short form of usage.
+ */
+ if (exitCode != EXIT_SUCCESS)
+ optionUsage(pOpts, exitCode);
+ fflush(stderr);
+ fflush(stdout);
+ if (ferror(stdout) || ferror(stderr))
+ exit(EXIT_FAILURE);
+
+ option_usage_fp = stdout;
+
+ /*
+ * First, print our usage
+ */
+ switch (fork()) {
+ case -1:
+ optionUsage(pOpts, EXIT_FAILURE);
+ /* NOTREACHED */
+
+ case 0:
+ pagerState = PAGER_STATE_CHILD;
+ optionUsage(pOpts, EXIT_SUCCESS);
+ /* NOTREACHED */
+ _exit(EXIT_FAILURE);
+
+ default:
+ {
+ int sts;
+ wait(&sts);
+ }
+ }
+
+ /*
+ * Generate the pzProgName, since optionProcess() normally
+ * gets it from the command line
+ */
+ {
+ char * pz;
+ char ** pp = (char **)(void *)&(optionParseShellOptions->pzProgName);
+ AGDUPSTR(pz, optionParseShellOptions->pzPROGNAME, "prog name");
+ *pp = pz;
+ while (*pz != NUL) {
+ *pz = tolower(*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);
+
+ default:
+ {
+ int sts;
+ wait(&sts);
+ }
+ }
+
+ fflush(stdout);
+ if (ferror(stdout)) {
+ fputs(zOutputFail, stderr);
+ exit(EXIT_FAILURE);
+ }
+
+ exit(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..e14d396
--- /dev/null
+++ b/autoopts/mk-autoopts-pc.in
@@ -0,0 +1,78 @@
+#! @CONFIG_SHELL@
+## ---------------------------------------------------------------------
+## mk-autoopts-pc.in -- Describe AutoOpts configuration
+##
+## Autoopts Copyright (c) 1992-2012 by Bruce Korb
+##
+## DO NOT EDIT THIS FILE (mk-autoopts-pc.in)
+##
+## It has been AutoGen-ed August 11, 2012 at 09:41:23 AM by AutoGen 5.16.2pre7
+## 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 )
+ ldopts=''
+ ldflags=-lopts
+ ;;
+
+* )
+ test -n "${ldopts}" && \
+ ldflags="${ldopts}${libdir} ${ldflags}"
+ ;;
+esac
+libs=${ldflags}
+test "${includedir}" = "/usr/include" && cflags=""
+PS4='>mk-aopc> '
+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..5c37b29
--- /dev/null
+++ b/autoopts/mk-tpl-config.sh
@@ -0,0 +1,140 @@
+#! /bin/sh
+
+prog=`basename $0 .sh`
+
+die() {
+ echo "$prog failure: $*"
+ kill -TERM $progpid
+ sleep 1
+ exit 1
+}
+
+init() {
+ PS4='>tpc-${FUNCNAME}> '
+ set -e
+ 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"
+ #define LOCAL static
+ #include "ao-strs.h"
+ _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} '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
+}
+
+set_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
+
+ 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
+}
+
+set_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
+}
+
+init
+collect_src "$@" > ${builddir}/libopts.c
+extension_defines
+set_shell_prog
+set_cat_prog
+touch ${sentinel_file}
diff --git a/autoopts/nested.c b/autoopts/nested.c
new file mode 100644
index 0000000..ed23fd2
--- /dev/null
+++ b/autoopts/nested.c
@@ -0,0 +1,849 @@
+
+/**
+ * \file nested.c
+ *
+ * Time-stamp: "2012-03-04 13:30:07 bkorb"
+ *
+ * Automated Options Nested Values module.
+ *
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+ *
+ * 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+ * 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+ * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/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
+
+/* = = = START-STATIC-FORWARD = = = */
+static void
+remove_continuation(char* pzSrc);
+
+static char const*
+scan_q_str(char const* pzTxt);
+
+static tOptionValue *
+add_string(void ** pp, char const * pzName, size_t nameLen,
+ char const* pzValue, size_t dataLen);
+
+static tOptionValue *
+add_bool(void ** pp, char const * pzName, size_t nameLen,
+ char const* pzValue, size_t dataLen);
+
+static tOptionValue*
+add_number(void** pp, char const* pzName, size_t nameLen,
+ char const* pzValue, size_t dataLen);
+
+static tOptionValue*
+add_nested(void** pp, char const* pzName, size_t nameLen,
+ char* pzValue, size_t dataLen);
+
+static char const *
+scan_name(char const* pzName, tOptionValue* pRes);
+
+static char const*
+scan_xml(char const* pzName, tOptionValue* pRes);
+
+static void
+sort_list(tArgList* pAL);
+/* = = = END-STATIC-FORWARD = = = */
+
+/**
+ * Backslashes are used for line continuations. We keep the newline
+ * characters, but trim out the backslash:
+ */
+static void
+remove_continuation(char* pzSrc)
+{
+ char* pzD;
+
+ do {
+ while (*pzSrc == NL) pzSrc++;
+ pzD = strchr(pzSrc, 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.
+ */
+ pzSrc = pzD--;
+ if (*pzD != '\\')
+ pzD++;
+ } while (pzD == pzSrc);
+
+ /*
+ * Start shifting text.
+ */
+ for (;;) {
+ char ch = ((*pzD++) = *(pzSrc++));
+ switch (ch) {
+ case NUL: return;
+ case '\\':
+ if (*pzSrc == 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.
+ */
+static tOptionValue *
+add_string(void ** pp, char const * pzName, size_t nameLen,
+ char const* pzValue, size_t dataLen)
+{
+ tOptionValue* pNV;
+ size_t sz = nameLen + dataLen + sizeof(*pNV);
+
+ pNV = AGALOC(sz, "option name/str value pair");
+ if (pNV == NULL)
+ return NULL;
+
+ if (pzValue == NULL) {
+ pNV->valType = OPARG_TYPE_NONE;
+ pNV->pzName = pNV->v.strVal;
+
+ } else {
+ pNV->valType = OPARG_TYPE_STRING;
+ if (dataLen > 0) {
+ char const * pzSrc = pzValue;
+ char * pzDst = pNV->v.strVal;
+ int ct = dataLen;
+ do {
+ int ch = *(pzSrc++) & 0xFF;
+ if (ch == NUL) goto data_copy_done;
+ if (ch == '&')
+ ch = get_special_char(&pzSrc, &ct);
+ *(pzDst++) = (char)ch;
+ } while (--ct > 0);
+ data_copy_done:
+ *pzDst = NUL;
+
+ } else {
+ pNV->v.strVal[0] = NUL;
+ }
+
+ pNV->pzName = pNV->v.strVal + dataLen + 1;
+ }
+
+ memcpy(pNV->pzName, pzName, nameLen);
+ pNV->pzName[ nameLen ] = NUL;
+ addArgListEntry(pp, pNV);
+ return pNV;
+}
+
+/**
+ * Associate a name with either a string or no value.
+ */
+static tOptionValue *
+add_bool(void ** pp, char const * pzName, size_t nameLen,
+ char const* pzValue, size_t dataLen)
+{
+ tOptionValue * pNV;
+
+ {
+ size_t sz = nameLen + sizeof(tOptionValue) + 1;
+ pNV = AGALOC(sz, "name/bool value");
+ }
+
+ {
+ char * p = SPN_WHITESPACE_CHARS(pzValue);
+ dataLen -= p - pzValue;
+ pzValue = p;
+ }
+
+ if (dataLen == 0)
+ pNV->v.boolVal = 0;
+
+ else if (IS_DEC_DIGIT_CHAR(*pzValue))
+ pNV->v.boolVal = atoi(pzValue);
+
+ else pNV->v.boolVal = ! IS_FALSE_TYPE_CHAR(*pzValue);
+
+ pNV->valType = OPARG_TYPE_BOOLEAN;
+ pNV->pzName = (char*)(pNV + 1);
+ memcpy(pNV->pzName, pzName, nameLen);
+ pNV->pzName[ nameLen ] = NUL;
+ addArgListEntry(pp, pNV);
+ return pNV;
+}
+
+/**
+ * Associate a name with either a string or no value.
+ */
+static tOptionValue*
+add_number(void** pp, char const* pzName, size_t nameLen,
+ char const* pzValue, size_t dataLen)
+{
+ tOptionValue* pNV;
+ size_t sz = nameLen + sizeof(*pNV) + 1;
+
+ pNV = AGALOC(sz, "option name/bool value pair");
+ if (pNV == NULL)
+ return NULL;
+ while (IS_WHITESPACE_CHAR(*pzValue) && (dataLen > 0)) {
+ dataLen--; pzValue++;
+ }
+ if (dataLen == 0)
+ pNV->v.longVal = 0;
+ else
+ pNV->v.longVal = strtol(pzValue, 0, 0);
+
+ pNV->valType = OPARG_TYPE_NUMERIC;
+ pNV->pzName = (char*)(pNV + 1);
+ memcpy(pNV->pzName, pzName, nameLen);
+ pNV->pzName[ nameLen ] = NUL;
+ addArgListEntry(pp, pNV);
+ return pNV;
+}
+
+/**
+ * Associate a name with either a string or no value.
+ */
+static tOptionValue*
+add_nested(void** pp, char const* pzName, size_t nameLen,
+ char* pzValue, size_t dataLen)
+{
+ tOptionValue* pNV;
+
+ if (dataLen == 0) {
+ size_t sz = nameLen + sizeof(*pNV) + 1;
+ pNV = AGALOC(sz, "empty nested value pair");
+ if (pNV == NULL)
+ return NULL;
+ pNV->v.nestVal = NULL;
+ pNV->valType = OPARG_TYPE_HIERARCHY;
+ pNV->pzName = (char*)(pNV + 1);
+ memcpy(pNV->pzName, pzName, nameLen);
+ pNV->pzName[ nameLen ] = NUL;
+
+ } else {
+ pNV = optionLoadNested(pzValue, pzName, nameLen);
+ }
+
+ if (pNV != NULL)
+ addArgListEntry(pp, pNV);
+
+ return pNV;
+}
+
+/**
+ * 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* pzName, tOptionValue* pRes)
+{
+ tOptionValue* pNV;
+ char const * pzScan = pzName+1; /* we know first char is a name char */
+ char const * pzVal;
+ size_t nameLen = 1;
+ size_t dataLen = 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(pzName + 1);
+ if (pzScan[-1] == ':')
+ pzScan--;
+ nameLen = pzScan - pzName;
+
+ 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(&(pRes->v.nestVal), pzName, nameLen, NULL, (size_t)0);
+ break;
+
+ case '"':
+ case '\'':
+ pzVal = pzScan;
+ pzScan = scan_q_str(pzScan);
+ dataLen = pzScan - pzVal;
+ pNV = add_string(&(pRes->v.nestVal), pzName, nameLen, pzVal,
+ dataLen);
+ if ((pNV != NULL) && (option_load_mode == OPTION_LOAD_COOKED))
+ ao_string_cook(pNV->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--;
+ dataLen = pzScan - pzVal;
+ goto string_done;
+ /* FALLTHROUGH */
+
+ case NL:
+ if ( (pzScan > pzVal + 2)
+ && (pzScan[-2] == '\\')
+ && (pzScan[ 0] != NUL))
+ continue;
+ /* FALLTHROUGH */
+
+ case ',':
+ dataLen = (pzScan - pzVal) - 1;
+ string_done:
+ pNV = add_string(&(pRes->v.nestVal), pzName, nameLen,
+ pzVal, dataLen);
+ if (pNV != NULL)
+ remove_continuation(pNV->v.strVal);
+ goto leave_scan_name;
+ }
+ }
+ break;
+ } leave_scan_name:;
+
+ return pzScan;
+}
+
+/**
+ * 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.
+ */
+static char const*
+scan_xml(char const* pzName, tOptionValue* pRes)
+{
+ size_t nameLen;
+ size_t valLen;
+ char const* pzScan = ++pzName;
+ char const* pzVal;
+ tOptionValue valu;
+ tOptionValue* pNewVal;
+ tOptionLoadMode save_mode = option_load_mode;
+
+ if (! IS_VAR_FIRST_CHAR(*pzName)) {
+ switch (*pzName) {
+ default:
+ pzName = NULL;
+ break;
+
+ case '!':
+ pzName = strstr(pzName, "-->");
+ if (pzName != NULL)
+ pzName += 3;
+ break;
+
+ case '?':
+ pzName = strchr(pzName, '>');
+ if (pzName != NULL)
+ pzName++;
+ break;
+ }
+ return pzName;
+ }
+
+ pzScan = SPN_VALUE_NAME_CHARS(pzName+1);
+ nameLen = pzScan - pzName;
+ if (nameLen > 64)
+ return NULL;
+ valu.valType = OPARG_TYPE_STRING;
+
+ switch (*pzScan) {
+ case ' ':
+ case '\t':
+ pzScan = parse_attrs(
+ NULL, (char*)pzScan, &option_load_mode, &valu );
+ if (*pzScan == '>') {
+ pzScan++;
+ break;
+ }
+
+ if (*pzScan != '/') {
+ option_load_mode = save_mode;
+ return NULL;
+ }
+ /* FALLTHROUGH */
+
+ case '/':
+ if (*++pzScan != '>') {
+ option_load_mode = save_mode;
+ return NULL;
+ }
+ add_string(&(pRes->v.nestVal), pzName, nameLen, NULL, (size_t)0);
+ option_load_mode = save_mode;
+ return pzScan+1;
+
+ default:
+ option_load_mode = save_mode;
+ return NULL;
+
+ case '>':
+ pzScan++;
+ break;
+ }
+
+ pzVal = pzScan;
+
+ {
+ char z[68];
+ char* pzD = z;
+ int ct = nameLen;
+ char const* pzS = pzName;
+
+ *(pzD++) = '<';
+ *(pzD++) = '/';
+
+ do {
+ *(pzD++) = *(pzS++);
+ } while (--ct > 0);
+ *(pzD++) = '>';
+ *pzD = NUL;
+
+ pzScan = strstr(pzScan, z);
+ if (pzScan == NULL) {
+ option_load_mode = save_mode;
+ return NULL;
+ }
+ valLen = (pzScan - pzVal);
+ pzScan += nameLen + 3;
+ pzScan = SPN_WHITESPACE_CHARS(pzScan);
+ }
+
+ switch (valu.valType) {
+ case OPARG_TYPE_NONE:
+ add_string(&(pRes->v.nestVal), pzName, nameLen, NULL, (size_t)0);
+ break;
+
+ case OPARG_TYPE_STRING:
+ pNewVal = add_string(
+ &(pRes->v.nestVal), pzName, nameLen, pzVal, valLen);
+
+ if (option_load_mode == OPTION_LOAD_KEEP)
+ break;
+ mungeString(pNewVal->v.strVal, option_load_mode);
+ break;
+
+ case OPARG_TYPE_BOOLEAN:
+ add_bool(&(pRes->v.nestVal), pzName, nameLen, pzVal, valLen);
+ break;
+
+ case OPARG_TYPE_NUMERIC:
+ add_number(&(pRes->v.nestVal), pzName, nameLen, pzVal, valLen);
+ break;
+
+ case OPARG_TYPE_HIERARCHY:
+ {
+ char* pz = AGALOC(valLen+1, "hierarchical scan");
+ if (pz == NULL)
+ break;
+ memcpy(pz, pzVal, valLen);
+ pz[valLen] = NUL;
+ add_nested(&(pRes->v.nestVal), pzName, nameLen, pz, valLen);
+ AGFREE(pz);
+ break;
+ }
+
+ case OPARG_TYPE_ENUMERATION:
+ case OPARG_TYPE_MEMBERSHIP:
+ default:
+ break;
+ }
+
+ option_load_mode = save_mode;
+ return pzScan;
+}
+
+
+/**
+ * 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.
+ */
+LOCAL void
+unload_arg_list(tArgList* pAL)
+{
+ int ct = pAL->useCt;
+ tCC** ppNV = pAL->apzArgs;
+
+ while (ct-- > 0) {
+ tOptionValue* pNV = (tOptionValue*)(void*)*(ppNV++);
+ if (pNV->valType == OPARG_TYPE_HIERARCHY)
+ unload_arg_list(pNV->v.nestVal);
+ AGFREE(pNV);
+ }
+
+ AGFREE((void*)pAL);
+}
+
+/*=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 * pOV)
+{
+ if (pOV == NULL) return;
+ if (pOV->valType != OPARG_TYPE_HIERARCHY) {
+ errno = EINVAL;
+ return;
+ }
+
+ unload_arg_list(pOV->v.nestVal);
+
+ AGFREE((void*)pOV);
+}
+
+/**
+ * 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* pAL)
+{
+ int ix;
+ int lm = pAL->useCt;
+
+ /*
+ * This loop iterates "useCt" - 1 times.
+ */
+ for (ix = 0; ++ix < lm;) {
+ int iy = ix-1;
+ tOptionValue* pNewNV = (tOptionValue*)(void*)(pAL->apzArgs[ix]);
+ tOptionValue* pOldNV = (tOptionValue*)(void*)(pAL->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(pOldNV->pzName, pNewNV->pzName) > 0) {
+ pAL->apzArgs[iy+1] = (void*)pOldNV;
+ pOldNV = (tOptionValue*)(void*)(pAL->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.
+ */
+ pAL->apzArgs[iy+1] = (void*)pNewNV;
+ }
+}
+
+/*=
+ * 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 + nameLen + 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
+=*/
+LOCAL tOptionValue*
+optionLoadNested(char const* pzTxt, char const* pzName, size_t nameLen)
+{
+ tOptionValue* pRes;
+
+ /*
+ * Make sure we have some data and we have space to put what we find.
+ */
+ if (pzTxt == NULL) {
+ errno = EINVAL;
+ return NULL;
+ }
+ pzTxt = SPN_WHITESPACE_CHARS(pzTxt);
+ if (*pzTxt == NUL) {
+ errno = ENOMSG;
+ return NULL;
+ }
+ pRes = AGALOC(sizeof(*pRes) + nameLen + 1, "nested args");
+ if (pRes == NULL) {
+ errno = ENOMEM;
+ return NULL;
+ }
+ pRes->valType = OPARG_TYPE_HIERARCHY;
+ pRes->pzName = (char*)(pRes + 1);
+ memcpy(pRes->pzName, pzName, nameLen);
+ pRes->pzName[nameLen] = NUL;
+
+ {
+ tArgList * pAL = AGALOC(sizeof(*pAL), "nested arg list");
+ if (pAL == NULL) {
+ AGFREE(pRes);
+ return NULL;
+ }
+
+ pRes->v.nestVal = pAL;
+ pAL->useCt = 0;
+ pAL->allocCt = MIN_ARG_ALLOC_CT;
+ }
+
+ /*
+ * Scan until we hit a NUL.
+ */
+ do {
+ pzTxt = SPN_WHITESPACE_CHARS(pzTxt);
+ if (IS_VAR_FIRST_CHAR(*pzTxt))
+ pzTxt = scan_name(pzTxt, pRes);
+
+ else switch (*pzTxt) {
+ case NUL: goto scan_done;
+ case '<': pzTxt = scan_xml(pzTxt, pRes);
+ if (pzTxt == NULL) goto woops;
+ if (*pzTxt == ',') pzTxt++; break;
+ case '#': pzTxt = strchr(pzTxt, NL); break;
+ default: goto woops;
+ }
+ } while (pzTxt != NULL); scan_done:;
+
+ {
+ tArgList * al = pRes->v.nestVal;
+ if (al->useCt == 0) {
+ errno = ENOMSG;
+ goto woops;
+ }
+ if (al->useCt > 1)
+ sort_list(al);
+ }
+
+ return pRes;
+
+ woops:
+ AGFREE(pRes->v.nestVal);
+ AGFREE(pRes);
+ return NULL;
+}
+
+/*=export_func optionNestedVal
+ * private:
+ *
+ * what: parse a hierarchical option argument
+ * arg: + tOptions* + pOpts + program options descriptor +
+ * arg: + tOptDesc* + pOptDesc + the descriptor for this arg +
+ *
+ * doc:
+ * Nested value was found on the command line
+=*/
+void
+optionNestedVal(tOptions* pOpts, tOptDesc* pOD)
+{
+ if (pOpts < OPTPROC_EMIT_LIMIT)
+ return;
+
+ if (pOD->fOptState & OPTST_RESET) {
+ tArgList* pAL = pOD->optCookie;
+ int ct;
+ tCC ** av;
+
+ if (pAL == NULL)
+ return;
+ ct = pAL->useCt;
+ av = pAL->apzArgs;
+
+ while (--ct >= 0) {
+ void * p = (void *)*(av++);
+ optionUnloadNested((tOptionValue const *)p);
+ }
+
+ AGFREE(pOD->optCookie);
+
+ } else {
+ tOptionValue* pOV = optionLoadNested(
+ pOD->optArg.argString, pOD->pz_Name, strlen(pOD->pz_Name));
+
+ if (pOV != NULL)
+ addArgListEntry(&(pOD->optCookie), (void*)pOV);
+ }
+}
+
+/*
+ * get_special_char
+ */
+LOCAL 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 = ++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, 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
+ */
+LOCAL 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..b709d07
--- /dev/null
+++ b/autoopts/numeric.c
@@ -0,0 +1,165 @@
+
+/**
+ * \file numeric.c
+ *
+ * Time-stamp: "2012-02-25 12:54:32 bkorb"
+ *
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+ *
+ * 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+ * 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+ * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
+ */
+
+/*=export_func optionShowRange
+ * private:
+ *
+ * what:
+ * 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 = BULLET_STR;
+
+ /*
+ * 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 : DEEP_INDENT_STR;
+
+ 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* + pOpts + program options descriptor +
+ * arg: + tOptDesc* + pOptDesc + the descriptor for this arg +
+ *
+ * doc:
+ * Decipher a numeric value.
+=*/
+void
+optionNumericVal(tOptions* pOpts, tOptDesc* pOD )
+{
+ char* pz;
+ long val;
+
+ /*
+ * Numeric options may have a range associated with it.
+ * If it does, the usage procedure requests that it be
+ * emitted by passing a NULL pOD pointer. Also bail out
+ * if there is no option argument or if we are being reset.
+ */
+ if ( (pOD == NULL)
+ || (pOD->optArg.argString == NULL)
+ || ((pOD->fOptState & OPTST_RESET) != 0))
+ return;
+
+ errno = 0;
+ val = strtol(pOD->optArg.argString, &pz, 0);
+ if ((pz == pOD->optArg.argString) || (errno != 0))
+ goto bad_number;
+
+ if ((pOD->fOptState & OPTST_SCALED_NUM) != 0)
+ switch (*(pz++)) {
+ case NUL: pz--; break;
+ case 't': val *= 1000;
+ case 'g': val *= 1000;
+ case 'm': val *= 1000;
+ case 'k': val *= 1000; break;
+
+ case 'T': val *= 1024;
+ case 'G': val *= 1024;
+ case 'M': val *= 1024;
+ case 'K': val *= 1024; break;
+
+ default: goto bad_number;
+ }
+
+ if (*pz != NUL)
+ goto bad_number;
+
+ if (pOD->fOptState & OPTST_ALLOC_ARG) {
+ AGFREE(pOD->optArg.argString);
+ pOD->fOptState &= ~OPTST_ALLOC_ARG;
+ }
+
+ pOD->optArg.argInt = val;
+ return;
+
+ bad_number:
+
+ fprintf( stderr, zNotNumber, pOpts->pzProgName, pOD->optArg.argString );
+ if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0)
+ (*(pOpts->pUsageProc))(pOpts, EXIT_FAILURE);
+
+ errno = EINVAL;
+ pOD->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/optionFileLoad.3 b/autoopts/optionFileLoad.3
new file mode 100644
index 0000000..4e30fa5
--- /dev/null
+++ b/autoopts/optionFileLoad.3
@@ -0,0 +1,52 @@
+.TH optionFileLoad 3 2012-08-11 "" "Programmer's Manual"
+.\" DO NOT EDIT THIS FILE (optionFileLoad.3)
+.\"
+.\" It has been AutoGen-ed August 11, 2012 at 09:44:56 AM by AutoGen 5.16.2
+.\" 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* \fIpOpts\fP, char const* \fIpzProg\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 pOpts
+program options descriptor
+.TP
+.IR pzProg
+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), optionNextValue(3), optionOnlyUsage(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), pathfind(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..1a51859
--- /dev/null
+++ b/autoopts/optionFindNextValue.3
@@ -0,0 +1,50 @@
+.TH optionFindNextValue 3 2012-08-11 "" "Programmer's Manual"
+.\" DO NOT EDIT THIS FILE (optionFindNextValue.3)
+.\"
+.\" It has been AutoGen-ed August 11, 2012 at 09:44:56 AM by AutoGen 5.16.2
+.\" 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* \fIpOptDesc\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 pOptDesc
+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), optionNextValue(3), optionOnlyUsage(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), pathfind(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..2c729f2
--- /dev/null
+++ b/autoopts/optionFindValue.3
@@ -0,0 +1,46 @@
+.TH optionFindValue 3 2012-08-11 "" "Programmer's Manual"
+.\" DO NOT EDIT THIS FILE (optionFindValue.3)
+.\"
+.\" It has been AutoGen-ed August 11, 2012 at 09:44:56 AM by AutoGen 5.16.2
+.\" 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* \fIpOptDesc\fP, char const* \fIname\fP, char const* \fIvalue\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 pOptDesc
+an option with a nested arg type
+.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), optionFindNextValue(3), optionFree(3), optionGetValue(3), optionLoadLine(3), optionNextValue(3), optionOnlyUsage(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), pathfind(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..a8ea0cb
--- /dev/null
+++ b/autoopts/optionFree.3
@@ -0,0 +1,31 @@
+.TH optionFree 3 2012-08-11 "" "Programmer's Manual"
+.\" DO NOT EDIT THIS FILE (optionFree.3)
+.\"
+.\" It has been AutoGen-ed August 11, 2012 at 09:44:56 AM by AutoGen 5.16.2
+.\" 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), optionNextValue(3), optionOnlyUsage(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), pathfind(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..3a908b8
--- /dev/null
+++ b/autoopts/optionGetValue.3
@@ -0,0 +1,47 @@
+.TH optionGetValue 3 2012-08-11 "" "Programmer's Manual"
+.\" DO NOT EDIT THIS FILE (optionGetValue.3)
+.\"
+.\" It has been AutoGen-ed August 11, 2012 at 09:44:56 AM by AutoGen 5.16.2
+.\" 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), optionNextValue(3), optionOnlyUsage(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), pathfind(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..83556a7
--- /dev/null
+++ b/autoopts/optionLoadLine.3
@@ -0,0 +1,45 @@
+.TH optionLoadLine 3 2012-08-11 "" "Programmer's Manual"
+.\" DO NOT EDIT THIS FILE (optionLoadLine.3)
+.\"
+.\" It has been AutoGen-ed August 11, 2012 at 09:44:56 AM by AutoGen 5.16.2
+.\" 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), optionNextValue(3), optionOnlyUsage(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), pathfind(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..7b332a1
--- /dev/null
+++ b/autoopts/optionNextValue.3
@@ -0,0 +1,47 @@
+.TH optionNextValue 3 2012-08-11 "" "Programmer's Manual"
+.\" DO NOT EDIT THIS FILE (optionNextValue.3)
+.\"
+.\" It has been AutoGen-ed August 11, 2012 at 09:44:56 AM by AutoGen 5.16.2
+.\" 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), optionOnlyUsage(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), pathfind(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..a48ddb5
--- /dev/null
+++ b/autoopts/optionOnlyUsage.3
@@ -0,0 +1,31 @@
+.TH optionOnlyUsage 3 2012-08-11 "" "Programmer's Manual"
+.\" DO NOT EDIT THIS FILE (optionOnlyUsage.3)
+.\"
+.\" It has been AutoGen-ed August 11, 2012 at 09:44:56 AM by AutoGen 5.16.2
+.\" 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), optionNextValue(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), pathfind(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..f0d047d
--- /dev/null
+++ b/autoopts/optionProcess.3
@@ -0,0 +1,55 @@
+.TH optionProcess 3 2012-08-11 "" "Programmer's Manual"
+.\" DO NOT EDIT THIS FILE (optionProcess.3)
+.\"
+.\" It has been AutoGen-ed August 11, 2012 at 09:44:56 AM by AutoGen 5.16.2
+.\" 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* \fIpOpts\fP, int \fIargc\fP, char** \fIargv\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 pOpts
+program options descriptor
+.TP
+.IR argc
+program arg count
+.TP
+.IR argv
+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), optionNextValue(3), optionOnlyUsage(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), pathfind(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..0e21e50
--- /dev/null
+++ b/autoopts/optionRestore.3
@@ -0,0 +1,35 @@
+.TH optionRestore 3 2012-08-11 "" "Programmer's Manual"
+.\" DO NOT EDIT THIS FILE (optionRestore.3)
+.\"
+.\" It has been AutoGen-ed August 11, 2012 at 09:44:56 AM by AutoGen 5.16.2
+.\" 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), optionNextValue(3), optionOnlyUsage(3), optionProcess(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), pathfind(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..b443471
--- /dev/null
+++ b/autoopts/optionSaveFile.3
@@ -0,0 +1,44 @@
+.TH optionSaveFile 3 2012-08-11 "" "Programmer's Manual"
+.\" DO NOT EDIT THIS FILE (optionSaveFile.3)
+.\"
+.\" It has been AutoGen-ed August 11, 2012 at 09:44:56 AM by AutoGen 5.16.2
+.\" 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* \fIpOpts\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 pOpts
+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), optionNextValue(3), optionOnlyUsage(3), optionProcess(3), optionRestore(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), pathfind(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..57567db
--- /dev/null
+++ b/autoopts/optionSaveState.3
@@ -0,0 +1,41 @@
+.TH optionSaveState 3 2012-08-11 "" "Programmer's Manual"
+.\" DO NOT EDIT THIS FILE (optionSaveState.3)
+.\"
+.\" It has been AutoGen-ed August 11, 2012 at 09:44:56 AM by AutoGen 5.16.2
+.\" 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), optionNextValue(3), optionOnlyUsage(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionUnloadNested(3), optionVersion(3), pathfind(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..ffa30c8
--- /dev/null
+++ b/autoopts/optionUnloadNested.3
@@ -0,0 +1,28 @@
+.TH optionUnloadNested 3 2012-08-11 "" "Programmer's Manual"
+.\" DO NOT EDIT THIS FILE (optionUnloadNested.3)
+.\"
+.\" It has been AutoGen-ed August 11, 2012 at 09:44:56 AM by AutoGen 5.16.2
+.\" 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), optionNextValue(3), optionOnlyUsage(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionVersion(3), pathfind(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..9de5a36
--- /dev/null
+++ b/autoopts/optionVersion.3
@@ -0,0 +1,27 @@
+.TH optionVersion 3 2012-08-11 "" "Programmer's Manual"
+.\" DO NOT EDIT THIS FILE (optionVersion.3)
+.\"
+.\" It has been AutoGen-ed August 11, 2012 at 09:44:56 AM by AutoGen 5.16.2
+.\" 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), optionNextValue(3), optionOnlyUsage(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), pathfind(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..7f1fb49
--- /dev/null
+++ b/autoopts/parse-duration.c
@@ -0,0 +1,601 @@
+/* Parse a time duration and return a seconds count
+ Copyright (C) 2008-2012 Free Software Foundation, Inc.
+ Written by Bruce Korb <bkorb@gnu.org>, 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 <http://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+/* Specification. */
+#include "parse-duration.h"
+
+#include <ctype.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.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)
+
+#define TIME_MAX 0x7FFFFFFF
+
+/* Wrapper around strtoul that does not require a cast. */
+static unsigned long inline
+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 inline
+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 inline
+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 > TIME_MAX / scale)
+ {
+ errno = ERANGE;
+ return BAD_TIME;
+ }
+
+ val *= scale;
+ if (base > TIME_MAX - 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..05570a0
--- /dev/null
+++ b/autoopts/parse-duration.h
@@ -0,0 +1,90 @@
+/* Parse a time duration and return a seconds count
+ Copyright (C) 2008-2012 Free Software Foundation, Inc.
+ Written by Bruce Korb <bkorb@gnu.org>, 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 <http://www.gnu.org/licenses/>. */
+
+/*
+
+ 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:
+
+ http://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 <time.h>
+
+/* 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..7eae2b0
--- /dev/null
+++ b/autoopts/pgusage.c
@@ -0,0 +1,132 @@
+
+/**
+ * \file pgusage.c
+ *
+ * Time-stamp: "2012-02-28 19:49:32 bkorb"
+ *
+ * Automated Options Paged Usage module.
+ *
+ * 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-2012 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 md5sums:
+ *
+ * 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+ * 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+ * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
+ */
+
+/*=export_func optionPagedUsage
+ * private:
+ *
+ * what: Decipher a boolean value
+ * arg: + tOptions* + pOpts + program options descriptor +
+ * arg: + tOptDesc* + pOptDesc + 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 * pOptions, tOptDesc * pOD)
+{
+#if ! defined(HAVE_WORKING_FORK)
+ if ((pOD->fOptState & OPTST_RESET) != 0)
+ return;
+
+ (*pOptions->pUsageProc)(pOptions, EXIT_SUCCESS);
+#else
+ static pid_t my_pid;
+ char zPageUsage[ 1024 ];
+
+ /*
+ * 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 ((pOD->fOptState & OPTST_RESET) != 0)
+ return;
+
+ my_pid = getpid();
+ snprintf(zPageUsage, sizeof(zPageUsage), TMP_USAGE_FMT, (tAoUL)my_pid);
+ unlink(zPageUsage);
+
+ /*
+ * Set usage output to this temporary file
+ */
+ option_usage_fp = fopen(zPageUsage, "w" FOPEN_BINARY_FLAG);
+ if (option_usage_fp == NULL)
+ _exit(EXIT_FAILURE);
+
+ pagerState = PAGER_STATE_READY;
+
+ /*
+ * 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.
+ */
+ (*pOptions->pUsageProc)(pOptions, EXIT_SUCCESS);
+
+ /* NOTREACHED */
+ _exit(EXIT_FAILURE);
+ }
+
+ case PAGER_STATE_READY:
+ {
+ tCC* pzPager = (tCC*)getenv(PAGER_NAME);
+
+ /*
+ * Use the "more(1)" program if "PAGER" has not been defined
+ */
+ if (pzPager == NULL)
+ pzPager = MORE_STR;
+
+ /*
+ * Page the file and remove it when done.
+ */
+ snprintf(zPageUsage, sizeof(zPageUsage), PAGE_USAGE_FMT, pzPager,
+ (tAoUL)my_pid);
+ fclose(stderr);
+ dup2(STDOUT_FILENO, STDERR_FILENO);
+
+ (void)system(zPageUsage);
+ }
+
+ 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..0b2fe6c
--- /dev/null
+++ b/autoopts/po/usage-txt.pot
@@ -0,0 +1,474 @@
+# Automated Option parsing usage text.
+# copyright (c) 1999-2012 by Bruce Korb - all rights reserved
+# This file is distributed under the same license as the AutoOpts package.
+# Bruce Korb <bkorb@gnu.org> 2012
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: autogen 5.16.2\n"
+"Report-Msgid-Bugs-To: autogen-users@lists.sourceforge.net\n"
+"POT-Creation-Date: 2012-08-11 09:41-0700\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: autoopts.c:70
+msgid "malloc of %d bytes failed\n"
+
+#: configfile.c:1353
+msgid "AutoOpts function called without option descriptor\n"
+
+#: configfile.c:1388
+msgid "\tThis exceeds the compiled library version: "
+
+#: configfile.c:1386
+msgid "Automated Options Processing Error!\n"
+ "\t%s called AutoOpts function with structure version %d:%d:%d.\n"
+
+#: autoopts.c:83
+msgid "realloc of %d bytes at 0x%p failed\n"
+
+#: configfile.c:1390
+msgid "\tThis is less than the minimum library version: "
+
+#: autoopts.c:96
+msgid "strdup of %d byte string failed\n"
+
+#: version.c:124
+msgid "Automated Options version %s\n"
+ "\tcopyright (c) 1999-2012 by Bruce Korb - all rights reserved\n"
+
+#: autoopts.c:360
+msgid "AutoOpts lib error: defaulted to option with optional arg\n"
+
+#: alias.c:55
+msgid "(AutoOpts bug): Aliasing option is out of range."
+
+#: enum.c:488
+msgid "all"
+
+#: usage.c:607
+msgid "\t\t\t\t- an alternate for %s\n"
+
+#: enum.c:230
+msgid "%s error: the keyword `%s' is ambiguous for %s\n"
+
+#: find.c:76
+msgid " The following options match:\n"
+
+#: find.c:258
+msgid "%s: ambiguous option name: %s (matches %d options)\n"
+
+#: find.c:79 find.c:84
+msgid " %s%s\n"
+
+#: check.c:159
+msgid "%s: Command line arguments required\n"
+
+#: alias.c:80 autoopts.c:228
+msgid "%d %s%s options allowed\n"
+
+#: usage.c:867
+msgid "version, usage and configuration options:"
+
+#: makeshell.c:261
+msgid "Error %d (%s) from the pipe(2) syscall\n"
+
+#: version.c:164
+msgid "ERROR: version option argument '%c' invalid. Use:\n"
+ "\t'v' - version only\n"
+ "\t'c' - version and copyright\n"
+ "\t'n' - version and copyright notice\n"
+
+#: check.c:58
+msgid "ERROR: %s option conflicts with the %s option\n"
+
+#: restore.c:109
+msgid "%s(optionSaveState): error: cannot allocate %d bytes\n"
+
+#: configfile.c:588
+msgid "auto-options"
+
+#: configfile.c:587 configfile.c:660 configfile.c:665
+msgid "program"
+
+#: usage.c:656
+msgid "\t\t\t\t- default option for unnamed options\n"
+
+#: usage.c:571
+msgid "\t\t\t\t- disabled as --%s\n"
+
+#: find.c:182 find.c:389
+msgid "%s: The ``%s'' option has been disabled"
+
+#: usage.c:836
+msgid " --- %-14s %s\n"
+
+#: usage.c:834
+msgid "This option has been disabled"
+
+#: usage.c:598
+msgid "\t\t\t\t- enabled by default\n"
+
+#: alias.c:75 autoopts.c:223
+msgid "-equivalence"
+
+#: alias.c:77 autoopts.c:225
+msgid "ERROR: only "
+
+#: usage.c:911
+msgid " - examining environment variables named %s_*\n"
+
+#: usage.c:1015
+msgid " "
+
+#: usage.c:275
+msgid "Options are specified by doubled hyphens and their name or by a single\n"
+ "hyphen and the flag character.\n"
+
+#: usage.c:250 usage.c:255
+msgid "%%-%ds %%s\n"
+
+#: makeshell.c:267
+msgid "fs error %d (%s) on fork - cannot obtain %s usage\n"
+
+#: makeshell.c:759
+msgid "fs error %d (%s) on freopen\n"
+
+#: configfile.c:1149
+msgid "File error %d (%s) opening %s for loading options\n"
+
+#: text_mmap.c:100
+msgid "fs error %d (%s) reading file %s\n"
+
+#: file.c:49 file.c:75 file.c:87 file.c:109 file.c:136
+msgid "fs error %d (%s) on %s %s for option %s\n"
+
+#: file.c:76
+msgid "stat-ing for directory"
+
+#: file.c:88
+msgid "stat-ing for regular file"
+
+#: file.c:50
+msgid "stat-ing for non-existant file"
+
+#: file.c:110
+msgid "open-ing file"
+
+#: file.c:137
+msgid "fopen-ing file"
+
+#: file.c:177
+msgid "\t\t\t\t- file must not pre-exist\n"
+
+#: file.c:181
+msgid "\t\t\t\t- file must pre-exist\n"
+
+#: makeshell.c:837
+msgid "\n"
+ "= = = = = = = =\n\n"
+ "This incarnation of genshell will produce\n"
+ "a shell script to parse the options for %s:\n\n"
+
+#: usage.c:971 usage.c:985
+msgid "=T/F"
+
+#: usage.c:975
+msgid "\n"
+ "%s\n\n"
+
+#: usage.c:967 usage.c:985
+msgid "=KWd"
+
+#: usage.c:970
+msgid "=file"
+
+#: usage.c:968
+msgid "=Mbr"
+
+#: usage.c:969
+msgid "=Tim"
+
+#: usage.c:972
+msgid "=Cplx"
+
+#: usage.c:966 usage.c:985
+msgid "=num"
+
+#: usage.c:973
+msgid "[=arg]"
+
+#: usage.c:980 usage.c:981 usage.c:982
+msgid "--%2$s%1$s"
+
+#: usage.c:964 usage.c:985
+msgid "=str"
+
+#: find.c:428 reset.c:108
+msgid "%s: illegal option -- %c\n"
+
+#: find.c:236 find.c:554 reset.c:116
+msgid "%s: illegal option -- %s\n"
+
+#: find.c:300
+msgid "%s: unknown vendor extension option -- %s\n"
+
+#: enum.c:155 enum.c:165
+msgid " or an integer from %d through %d\n"
+
+#: usage.c:486 usage.c:800
+msgid "AutoOpts ERROR: invalid option descriptor for %s\n"
+
+#: find.c:347
+msgid "%s: invalid option name: %s\n"
+
+#: enum.c:162
+msgid " or an integer mask with any of the lower %d bits set\n"
+
+#: usage.c:631
+msgid "\t\t\t\t- is a set membership option\n"
+
+#: autoopts.c:290
+msgid "%s: option `%s' requires an argument\n"
+
+#: autoopts.c:175
+msgid "Equivalenced option '%s' was equivalenced to both\n"
+ "\t'%s' and '%s'"
+
+#: usage.c:651
+msgid "\t\t\t\t- must appear between %d and %d times\n"
+
+#: check.c:92
+msgid "ERROR: The %s option is required\n"
+
+#: autoopts.c:389
+msgid "%s: option `%s' cannot have an argument\n"
+
+#: check.c:149
+msgid "%s: Command line arguments not allowed\n"
+
+#: save.c:512
+msgid "error %d (%s) creating %s\n"
+
+#: usage.c:277
+msgid "Options are specified by single or double hyphens and their name.\n"
+
+#: enum.c:230
+msgid "%s error: `%s' does not match any %s keywords\n"
+
+#: usage.c:638
+msgid "\t\t\t\t- may appear multiple times\n"
+
+#: usage.c:625
+msgid "\t\t\t\t- may not be preset\n"
+
+#: reset.c:91
+msgid "The 'reset-option' option requires an argument\n"
+
+#: usage.c:1026
+msgid " Arg Option-Name Description\n"
+
+#: usage.c:962 usage.c:1020
+msgid " Flg Arg Option-Name Description\n"
+
+#: save.c:179 save.c:233
+msgid "error %d (%s) stat-ing %s\n"
+
+#: restore.c:150
+msgid "%s(optionRestore): error: no saved option state\n"
+
+#: enum.c:493
+msgid "none"
+
+#: save.c:128
+msgid "'%s' not defined\n"
+
+#: autoopts.c:421
+msgid "'%s' is not a command line option\n"
+
+#: check.c:91
+msgid "ERROR: The %s option must appear %d times\n"
+
+#: configfile.c:1159 makeshell.c:684 save.c:252
+msgid "error: cannot load options from non-regular file %s\n"
+
+#: numeric.c:151
+msgid "%s error: `%s' is not a recognizable number\n"
+
+#: time.c:112
+msgid "%s error: `%s' is not a recognizable date/time\n"
+
+#: time.c:51
+msgid "%s error: `%s' is not a recognizable time duration\n"
+
+#: usage.c:1021 usage.c:1027
+msgid " %3s %s"
+
+#: usage.c:282
+msgid "The '-#<number>' option may omit the hash char\n"
+
+#: alias.c:82 autoopts.c:230
+msgid "one %s%s option allowed\n"
+
+#: usage.c:278
+msgid "All arguments are named options.\n"
+
+#: makeshell.c:176 makeshell.c:859 usage.c:234 usage.c:309 version.c:170
+msgid "Write failure to output file"
+
+#: usage.c:703
+msgid " - reading file %s"
+
+#: usage.c:304 version.c:108 version.c:130
+msgid "\n"
+ "please send bug reports to: %s\n"
+
+#: usage.c:637
+msgid "\t\t\t\t- may NOT appear - preset only\n"
+
+#: save.c:532
+msgid "# preset/initialization file\n"
+ "# %s#\n"
+
+#: usage.c:675 usage.c:909
+msgid "\n"
+ "The following option preset mechanisms are supported:\n"
+
+#: usage.c:421
+msgid "prohibits these options:\n"
+
+#: usage.c:285
+msgid "Operands and options may be intermixed. They will be reordered.\n"
+
+#: numeric.c:75
+msgid "%s%ld to %ld"
+
+#: numeric.c:73
+msgid "%sgreater than or equal to %ld"
+
+#: numeric.c:64
+msgid "%sIt must lie in one of the ranges:\n"
+
+#: numeric.c:64
+msgid "%sIt must be in the range:\n"
+
+#: numeric.c:82
+msgid ", or\n"
+
+#: numeric.c:56
+msgid "%s error: %s option value %ld is out of range.\n"
+
+#: numeric.c:69
+msgid "%s%ld exactly"
+
+#: numeric.c:62
+msgid "%sis scalable with a suffix: k/K/m/M/g/G/t/T\n"
+
+#: numeric.c:71
+msgid "%sless than or equal to %ld"
+
+#: reset.c:86
+msgid "The --reset-option has not been configured.\n"
+
+#: check.c:45
+msgid "ERROR: %s option requires the %s option\n"
+
+#: usage.c:1033 usage.c:1039
+msgid " %3s %-14s %s"
+
+#: usage.c:403
+msgid "requires these options:\n"
+
+#: usage.c:1038
+msgid " Arg Option-Name Req? Description\n"
+
+#: usage.c:1032
+msgid " Flg Arg Option-Name Req? Description\n"
+
+#: configfile.c:1420
+msgid "-_^"
+
+#: enum.c:163
+msgid "or you may use a numeric representation. Preceding these with a '!' will\n"
+ "clear the bits, specifying 'none' will clear all bits, and 'all' will set them\n"
+ "all. Multiple entries may be passed as an option argument list.\n"
+
+#: usage.c:984
+msgid "%s"
+
+#: usage.c:976
+msgid " "
+
+#: usage.c:1010
+msgid "T/F"
+
+#: usage.c:1014
+msgid "\n"
+ "%s\n\n"
+ "%s"
+
+#: usage.c:1009
+msgid "Fil"
+
+#: usage.c:1006
+msgid "KWd"
+
+#: usage.c:1007
+msgid "Mbr"
+
+#: usage.c:1008
+msgid "Tim"
+
+#: usage.c:1011
+msgid "Cpx"
+
+#: usage.c:1013
+msgid "no "
+
+#: usage.c:1005
+msgid "Num"
+
+#: usage.c:1012
+msgid "opt"
+
+#: usage.c:1004
+msgid "YES"
+
+#: usage.c:1003
+msgid "Str"
+
+#: usage.c:395
+msgid "\t\t\t\t- "
+
+#: usage.c:412
+msgid "\t\t\t\t-- and "
+
+#: usage.c:405 usage.c:423 usage.c:514
+msgid "\t\t\t\t%s\n"
+
+#: usage.c:977
+msgid " "
+
+#: enum.c:196
+msgid "%s error: %s exceeds %s keyword count\n"
+
+#: usage.c:1016
+msgid " "
+
+#: usage.c:643
+msgid "\t\t\t\t- may appear up to %d times\n"
+
+#: enum.c:73
+msgid "The valid \"%s\" option keywords are:\n"
+
+#: usage.c:514
+msgid "These additional options are:"
+
+#: usage.c:871
+msgid "The next option supports vendor supported extra options:"
+
diff --git a/autoopts/project.h b/autoopts/project.h
new file mode 100644
index 0000000..c0df391
--- /dev/null
+++ b/autoopts/project.h
@@ -0,0 +1,50 @@
+
+#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
+
+#endif /* AUTOGEN_PROJECT_H */
diff --git a/autoopts/proto.h b/autoopts/proto.h
new file mode 100644
index 0000000..f52c74a
--- /dev/null
+++ b/autoopts/proto.h
@@ -0,0 +1,130 @@
+/* -*- buffer-read-only: t -*- vi: set ro:
+ *
+ * Prototypes for autoopts
+ * Generated Sat Aug 11 09:41:23 PDT 2012
+ */
+#ifndef AUTOOPTS_PROTO_H_GUARD
+#define AUTOOPTS_PROTO_H_GUARD 1
+
+#ifndef LOCAL
+# define LOCAL extern
+# define REDEF_LOCAL 1
+#else
+# undef REDEF_LOCAL
+#endif
+/*
+ * Extracted from autoopts.c
+ */
+LOCAL void *
+ao_malloc(size_t sz);
+
+LOCAL void *
+ao_realloc(void *p, size_t sz);
+
+LOCAL char *
+ao_strdup(char const *str);
+
+LOCAL tSuccess
+handle_opt(tOptions * pOpts, tOptState* pOptState);
+
+LOCAL tSuccess
+immediate_opts(tOptions * pOpts);
+
+LOCAL tSuccess
+regular_opts(tOptions * pOpts);
+
+/*
+ * Extracted from check.c
+ */
+LOCAL bool
+is_consistent(tOptions * pOpts);
+
+/*
+ * Extracted from configfile.c
+ */
+LOCAL void
+intern_file_load(tOptions* pOpts);
+
+LOCAL char*
+parse_attrs(tOptions * pOpts, char * pzText, tOptionLoadMode * pMode,
+ tOptionValue * pType);
+
+LOCAL tSuccess
+validate_struct(tOptions * pOpts, char const * pzProgram);
+
+/*
+ * Extracted from env.c
+ */
+LOCAL void
+doPrognameEnv(tOptions * pOpts, teEnvPresetType type);
+
+LOCAL void
+env_presets(tOptions * pOpts, teEnvPresetType type);
+
+/*
+ * Extracted from find.c
+ */
+LOCAL tSuccess
+opt_find_long(tOptions * opts, char const * opt_name, tOptState * state);
+
+LOCAL tSuccess
+opt_find_short(tOptions* pOpts, uint_t optValue, tOptState* pOptState);
+
+LOCAL tSuccess
+get_opt_arg(tOptions * pOpts, tOptState * pOptState);
+
+LOCAL tSuccess
+find_opt(tOptions * pOpts, tOptState * pOptState);
+
+/*
+ * Extracted from load.c
+ */
+LOCAL void
+mungeString(char * txt, tOptionLoadMode mode);
+
+LOCAL void
+loadOptionLine(
+ tOptions * opts,
+ tOptState * opt_state,
+ char * line,
+ tDirection direction,
+ tOptionLoadMode load_mode );
+
+/*
+ * Extracted from nested.c
+ */
+LOCAL void
+unload_arg_list(tArgList* pAL);
+
+LOCAL tOptionValue*
+optionLoadNested(char const* pzTxt, char const* pzName, size_t nameLen);
+
+LOCAL int
+get_special_char(char const ** ppz, int * ct);
+
+LOCAL void
+emit_special_char(FILE * fp, int ch);
+
+/*
+ * Extracted from sort.c
+ */
+LOCAL void
+optionSort(tOptions* pOpts);
+
+/*
+ * Extracted from stack.c
+ */
+LOCAL void
+addArgListEntry(void** ppAL, void* entry);
+
+/*
+ * Extracted from usage.c
+ */
+LOCAL void
+set_usage_flags(tOptions * opts, char const * flg_txt);
+
+#ifdef REDEF_LOCAL
+# undef LOCAL
+# define LOCAL
+#endif
+#endif /* AUTOOPTS_PROTO_H_GUARD */
diff --git a/autoopts/putshell.c b/autoopts/putshell.c
new file mode 100644
index 0000000..d8e2d91
--- /dev/null
+++ b/autoopts/putshell.c
@@ -0,0 +1,361 @@
+
+/**
+ * \file putshell.c
+ *
+ * Time-stamp: "2012-03-31 13:14:18 bkorb"
+ *
+ * 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.
+ *
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+ *
+ * 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+ * 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+ * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
+ */
+
+/* = = = START-STATIC-FORWARD = = = */
+static void
+print_quot_str(char const * pzStr);
+
+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 * pOpts);
+/* = = = END-STATIC-FORWARD = = = */
+
+/*
+ * Make sure embedded single quotes come out okay. The initial quote has
+ * been emitted and the closing quote will be upon return.
+ */
+static void
+print_quot_str(char const * pzStr)
+{
+ /*
+ * Handle empty strings to make the rest of the logic simpler.
+ */
+ if ((pzStr == NULL) || (*pzStr == 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.
+ */
+ while (*pzStr == '\'') {
+ fputs(QUOT_APOS, stdout);
+ pzStr++;
+ }
+ if (*pzStr == NUL)
+ return;
+
+ /*
+ * Start the single quote string
+ */
+ fputc('\'', stdout);
+ for (;;) {
+ char const * pz = strchr(pzStr, '\'');
+ if (pz == NULL)
+ break;
+
+ /*
+ * Emit the string up to the single quote (apostrophe) we just found.
+ */
+ (void)fwrite(pzStr, (size_t)(pz - pzStr), (size_t)1, stdout);
+ fputc('\'', stdout);
+ pzStr = pz;
+
+ /*
+ * Emit an escaped apostrophe for every one we find.
+ * If that ends the string, do not re-open the single quotes.
+ */
+ while (*++pzStr == '\'') fputs("\\'", stdout);
+ if (*pzStr == NUL)
+ return;
+
+ fputc('\'', stdout);
+ }
+
+ /*
+ * If we broke out of the loop, we must still emit the remaining text
+ * and then close the single quote string.
+ */
+ fputs(pzStr, stdout);
+ fputc('\'', 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 * pz;
+ uintptr_t val = 1;
+ printf(zOptNumFmt, pOpts->pzPROGNAME, pOD->pz_NAME,
+ (int)(uintptr_t)(pOD->optCookie));
+ pOD->optCookie = (void*)(uintptr_t)~0UL;
+ (*(pOD->pOptProc))(OPTPROC_RETURN_VALNAME, pOD);
+
+ /*
+ * We are building the typeset list. The list returned starts with
+ * 'none + ' for use by option saving stuff. We must ignore that.
+ */
+ pz = pOD->optArg.argString + 7;
+ while (*pz != NUL) {
+ printf("typeset -x -i %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 = NULL;
+ pOD->fOptState &= ~OPTST_ALLOC_ARG;
+}
+
+static void
+print_stacked_arg(tOptions * pOpts, tOptDesc * pOD)
+{
+ tArgList* pAL = (tArgList*)pOD->optCookie;
+ tCC** 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);
+ }
+}
+
+static void
+print_reordering(tOptions * pOpts)
+{
+ unsigned int optIx;
+
+ fputs(set_dash, stdout);
+
+ for (optIx = pOpts->curOptIdx;
+ optIx < pOpts->origArgCt;
+ optIx++) {
+
+ char* pzArg = pOpts->origArgVect[ optIx ];
+
+ if (strchr(pzArg, '\'') == NULL)
+ printf(arg_fmt, pzArg);
+
+ else {
+ fputs(" '", stdout);
+ for (;;) {
+ char ch = *(pzArg++);
+ switch (ch) {
+ case '\'': fputs(apostrophy, stdout); break;
+ case NUL: goto arg_done;
+ default: fputc(ch, stdout); break;
+ }
+ } arg_done:;
+ fputc('\'', stdout);
+ }
+ }
+ 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..ba61d12
--- /dev/null
+++ b/autoopts/reset.c
@@ -0,0 +1,138 @@
+
+/**
+ * \file reset.c
+ *
+ * Time-stamp: "2012-08-11 08:35:11 bkorb"
+ *
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+ *
+ * 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+ * 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+ * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/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)) {
+ fputs(zResetNotConfig, stderr);
+ _exit(EX_SOFTWARE);
+ }
+
+ if ((pzArg == NULL) || (*pzArg == NUL)) {
+ fputs(zNoResetArg, stderr);
+ 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, (tAoUC)*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..4fd76f8
--- /dev/null
+++ b/autoopts/restore.c
@@ -0,0 +1,228 @@
+
+/*
+ * \file restore.c
+ *
+ * Time-stamp: "2010-08-22 11:04:00 bkorb"
+ *
+ * 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.
+ *
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+ *
+ * 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+ * 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+ * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/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) + (pOpts->optCt * sizeof(tOptDesc));
+ p = AGALOC(sz, "saved option state");
+ if (p == NULL) {
+ tCC* pzName = pOpts->pzProgName;
+ if (pzName == NULL) {
+ pzName = pOpts->pzPROGNAME;
+ if (pzName == NULL)
+ pzName = zNil;
+ }
+ fprintf(stderr, zCantSave, pzName, sz);
+ exit(EXIT_FAILURE);
+ }
+
+ pOpts->pSavedState = p;
+ }
+
+ memcpy(p, pOpts, sizeof(*p));
+ memcpy(p + 1, pOpts->pOptDesc, 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) {
+ tCC* pzName = pOpts->pzProgName;
+ if (pzName == NULL) {
+ pzName = pOpts->pzPROGNAME;
+ if (pzName == NULL)
+ pzName = zNil;
+ }
+ fprintf(stderr, zNoState, pzName);
+ exit(EXIT_FAILURE);
+ }
+
+ pOpts->pSavedState = NULL;
+ optionFree(pOpts);
+
+ memcpy(pOpts, p, sizeof(*p));
+ memcpy(pOpts->pOptDesc, p+1, 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, 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.c b/autoopts/save.c
new file mode 100644
index 0000000..9e95056
--- /dev/null
+++ b/autoopts/save.c
@@ -0,0 +1,768 @@
+
+/*
+ * \file save.c
+ *
+ * Time-stamp: "2012-03-31 13:15:19 bkorb"
+ *
+ * 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.
+ *
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+ *
+ * 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+ * 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+ * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
+ */
+
+/* = = = START-STATIC-FORWARD = = = */
+static char const *
+find_dir_name(tOptions * pOpts, int * p_free);
+
+static char const *
+find_file_name(tOptions * pOpts, int * p_free_name);
+
+static void
+prt_entry(FILE * fp, tOptDesc * p, char const * pzLA);
+
+static void
+prt_value(FILE * fp, int depth, tOptDesc * pOD, 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 * p);
+
+static FILE *
+open_sv_file(tOptions* pOpts);
+
+static void
+prt_no_arg_opt(FILE * fp, tOptDesc * p, tOptDesc * pOD);
+
+static void
+prt_str_arg(FILE * fp, tOptDesc * pOD);
+
+static void
+prt_enum_arg(FILE * fp, tOptDesc * pOD);
+
+static void
+prt_set_arg(FILE * fp, tOptDesc * pOD);
+
+static void
+prt_file_arg(FILE * fp, tOptDesc * pOD, tOptions* pOpts);
+/* = = = END-STATIC-FORWARD = = = */
+
+static char const *
+find_dir_name(tOptions * pOpts, int * p_free)
+{
+ char const * pzDir;
+
+ if ( (pOpts->specOptIdx.save_opts == NO_EQUIVALENT)
+ || (pOpts->specOptIdx.save_opts == 0))
+ return NULL;
+
+ pzDir = pOpts->pOptDesc[ pOpts->specOptIdx.save_opts ].optArg.argString;
+ if ((pzDir != NULL) && (*pzDir != NUL))
+ return pzDir;
+
+ /*
+ * This function only works if there is a directory where
+ * we can stash the RC (INI) file.
+ */
+ {
+ char const * const* papz = pOpts->papzHomeList;
+ if (papz == NULL)
+ return NULL;
+
+ while (papz[1] != NULL) papz++;
+ pzDir = *papz;
+ }
+
+ /*
+ * IF it does not require deciphering an env value, then just copy it
+ */
+ if (*pzDir != '$')
+ return pzDir;
+
+ {
+ char const * pzEndDir = strchr(++pzDir, DIRCH);
+ char * pzFileName;
+ char * pzEnv;
+
+ if (pzEndDir != NULL) {
+ char z[ AO_NAME_SIZE ];
+ if ((pzEndDir - pzDir) > AO_NAME_LIMIT )
+ return NULL;
+ memcpy(z, pzDir, (size_t)(pzEndDir - pzDir));
+ z[pzEndDir - pzDir] = NUL;
+ pzEnv = getenv(z);
+ } else {
+
+ /*
+ * Make sure we can get the env value (after stripping off
+ * any trailing directory or file names)
+ */
+ pzEnv = getenv(pzDir);
+ }
+
+ if (pzEnv == NULL) {
+ fprintf(stderr, SAVE_WARN, pOpts->pzProgName);
+ fprintf(stderr, zNotDef, pzDir);
+ return NULL;
+ }
+
+ if (pzEndDir == NULL)
+ return pzEnv;
+
+ {
+ size_t sz = strlen(pzEnv) + strlen(pzEndDir) + 2;
+ pzFileName = (char*)AGALOC(sz, "dir name");
+ }
+
+ if (pzFileName == NULL)
+ return NULL;
+
+ *p_free = 1;
+ /*
+ * Glue together the full name into the allocated memory.
+ * FIXME: We lose track of this memory.
+ */
+ sprintf(pzFileName, "%s/%s", pzEnv, pzEndDir);
+ return pzFileName;
+ }
+}
+
+
+static char const *
+find_file_name(tOptions * pOpts, int * p_free_name)
+{
+ struct stat stBuf;
+ int free_dir_name = 0;
+
+ char const * pzDir = find_dir_name(pOpts, &free_dir_name);
+ if (pzDir == NULL)
+ return NULL;
+
+ /*
+ * See if we can find the specified directory. We use a once-only loop
+ * structure so we can bail out early.
+ */
+ if (stat(pzDir, &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, SAVE_WARN, pOpts->pzProgName);
+ fprintf(stderr, zNoStat, errno, strerror(errno), pzDir);
+ if (free_dir_name)
+ AGFREE((void*)pzDir);
+ return NULL;
+ }
+
+ /*
+ * Strip off the last component, stat the remaining string and
+ * that string must name a directory
+ */
+ dirchp = strrchr(pzDir, DIRCH);
+ if (dirchp == NULL) {
+ stBuf.st_mode = S_IFREG;
+ break; /* found directory -- viz., "." */
+ }
+
+ if ((size_t)(dirchp - pzDir) >= sizeof(z))
+ goto bogus_name;
+
+ memcpy(z, pzDir, (size_t)(dirchp - pzDir));
+ z[dirchp - pzDir] = 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(pzDir) + strlen(pOpts->pzRcName) + 2;
+
+ {
+ char * pzPath = (char*)AGALOC(sz, "file name");
+#ifdef HAVE_SNPRINTF
+ snprintf(pzPath, sz, "%s/%s", pzDir, pOpts->pzRcName);
+#else
+ sprintf(pzPath, "%s/%s", pzDir, pOpts->pzRcName);
+#endif
+ if (free_dir_name)
+ AGFREE((void*)pzDir);
+ pzDir = 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(pzDir, &stBuf) != 0) {
+ if (errno != ENOENT) {
+ fprintf(stderr, SAVE_WARN, pOpts->pzProgName);
+ fprintf(stderr, zNoStat, errno, strerror(errno),
+ pzDir);
+ AGFREE((void*)pzDir);
+ 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, SAVE_WARN, pOpts->pzProgName);
+ fprintf(stderr, zNotFile, pzDir);
+ if (free_dir_name)
+ AGFREE((void*)pzDir);
+ return NULL;
+ }
+
+ /*
+ * Get rid of the old file
+ */
+ unlink(pzDir);
+ *p_free_name = free_dir_name;
+ return pzDir;
+}
+
+
+static void
+prt_entry(FILE * fp, tOptDesc * p, char const * pzLA)
+{
+ /*
+ * 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;
+ if (! DISABLED_OPT(p) || (p->optEquivIndex != NO_EQUIVALENT))
+ pz = p->pz_Name;
+ else
+ pz = p->pz_DisableName;
+
+ fprintf(fp, "%-18s", pz);
+ }
+ /*
+ * IF the option is numeric only,
+ * THEN the char pointer is really the number
+ */
+ if (OPTST_GET_ARGTYPE(p->fOptState) == OPARG_TYPE_NUMERIC)
+ fprintf(fp, " %d\n", (int)(t_word)pzLA);
+
+ /*
+ * OTHERWISE, FOR each line of the value text, ...
+ */
+ else if (pzLA == NULL)
+ fputc(NL, fp);
+
+ else {
+ fputc(' ', fp); fputc(' ', fp);
+ for (;;) {
+ char const * pzNl = strchr(pzLA, NL);
+
+ /*
+ * IF this is the last line
+ * THEN bail and print it
+ */
+ if (pzNl == NULL)
+ break;
+
+ /*
+ * Print the continuation and the text from the current line
+ */
+ (void)fwrite(pzLA, (size_t)(pzNl - pzLA), (size_t)1, fp);
+ pzLA = pzNl+1; /* advance the Last Arg pointer */
+ fputs("\\\n", fp);
+ }
+
+ /*
+ * Terminate the entry
+ */
+ fputs(pzLA, fp);
+ fputc(NL, fp);
+ }
+}
+
+
+static void
+prt_value(FILE * fp, int depth, tOptDesc * pOD, 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 (pOD != NULL) {
+ tAoUI opt_state = pOD->fOptState;
+ uintptr_t val = pOD->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.
+ */
+ (*(pOD->pOptProc))(OPTPROC_RETURN_VALNAME, pOD );
+ if (pOD->optArg.argString != NULL) {
+ fputs(pOD->optArg.argString, fp);
+
+ if (ovp->valType != OPARG_TYPE_ENUMERATION) {
+ /*
+ * set membership strings get allocated
+ */
+ AGFREE((void*)pOD->optArg.argString);
+ }
+ }
+
+ pOD->optArg.argEnum = val;
+ pOD->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;
+ }
+}
+
+
+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);
+}
+
+
+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, "</%s>\n", name);
+}
+
+
+static void
+prt_nested(FILE * fp, tOptDesc * p)
+{
+ int opt_ct;
+ tArgList * al = p->optCookie;
+ void ** opt_list;
+
+ if (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, p->pz_Name);
+
+ do {
+ prt_value(fp, 1, p, ovp);
+
+ } while (ovp = optionNextValue(base, ovp),
+ ovp != NULL);
+
+ fprintf(fp, "</%s>\n", p->pz_Name);
+ } while (--opt_ct > 0);
+}
+
+
+static FILE *
+open_sv_file(tOptions* pOpts)
+{
+ FILE * fp;
+
+ {
+ int free_name = 0;
+ char const * pzFName = find_file_name(pOpts, &free_name);
+ if (pzFName == NULL)
+ return NULL;
+
+ fp = fopen(pzFName, "w" FOPEN_BINARY_FLAG);
+ if (fp == NULL) {
+ fprintf(stderr, SAVE_WARN, pOpts->pzProgName);
+ fprintf(stderr, zNoCreat, errno, strerror(errno), pzFName);
+ if (free_name)
+ AGFREE((void*) pzFName );
+ return fp;
+ }
+
+ if (free_name)
+ AGFREE((void*)pzFName);
+ }
+
+ {
+ char const * pz = pOpts->pzUsageTitle;
+ fputs("# ", fp);
+ do { fputc(*pz, fp); } while (*(pz++) != NL);
+ }
+
+ {
+ time_t timeVal = time(NULL);
+ char * pzTime = ctime(&timeVal);
+
+ fprintf(fp, zPresetFile, pzTime);
+#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((void*)pzTime);
+#endif
+ }
+
+ return fp;
+}
+
+static void
+prt_no_arg_opt(FILE * fp, tOptDesc * p, tOptDesc * pOD)
+{
+ /*
+ * 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 "p".
+ */
+ char const * pznm =
+ (DISABLED_OPT(p)) ? 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;
+
+ fprintf(fp, "%s\n", pznm);
+}
+
+static void
+prt_str_arg(FILE * fp, tOptDesc * pOD)
+{
+ if (pOD->fOptState & OPTST_STACKED) {
+ tArgList * pAL = (tArgList*)pOD->optCookie;
+ int uct = pAL->useCt;
+ char const ** ppz = pAL->apzArgs;
+
+ /*
+ * un-disable multiple copies of disabled options.
+ */
+ if (uct > 1)
+ pOD->fOptState &= ~OPTST_DISABLED;
+
+ while (uct-- > 0)
+ prt_entry(fp, pOD, *(ppz++));
+ } else {
+ prt_entry(fp, pOD, pOD->optArg.argString);
+ }
+}
+
+static void
+prt_enum_arg(FILE * fp, tOptDesc * pOD)
+{
+ uintptr_t val = pOD->optArg.argEnum;
+
+ /*
+ * This is a magic incantation that will convert the
+ * bit flag values back into a string suitable for printing.
+ */
+ (*(pOD->pOptProc))(OPTPROC_RETURN_VALNAME, pOD);
+ prt_entry(fp, pOD, (void*)(pOD->optArg.argString));
+
+ pOD->optArg.argEnum = val;
+}
+
+static void
+prt_set_arg(FILE * fp, tOptDesc * pOD)
+{
+ uintptr_t val = pOD->optArg.argEnum;
+
+ /*
+ * This is a magic incantation that will convert the
+ * bit flag values back into a string suitable for printing.
+ */
+ (*(pOD->pOptProc))(OPTPROC_RETURN_VALNAME, pOD);
+ prt_entry(fp, pOD, (void*)(pOD->optArg.argString));
+
+ if (pOD->optArg.argString != NULL) {
+ /*
+ * set membership strings get allocated
+ */
+ AGFREE((void*)pOD->optArg.argString);
+ pOD->fOptState &= ~OPTST_ALLOC_ARG;
+ }
+
+ pOD->optArg.argEnum = val;
+}
+
+static void
+prt_file_arg(FILE * fp, tOptDesc * pOD, tOptions* pOpts)
+{
+ /*
+ * If the cookie is not NULL, then it has the file name, period.
+ * Otherwise, if we have a non-NULL string argument, then....
+ */
+ if (pOD->optCookie != NULL)
+ prt_entry(fp, pOD, pOD->optCookie);
+
+ else if (HAS_originalOptArgArray(pOpts)) {
+ char const * orig =
+ pOpts->originalOptArgArray[pOD->optIndex].argString;
+
+ if (pOD->optArg.argString == orig)
+ return;
+
+ prt_entry(fp, pOD, pOD->optArg.argString);
+ }
+}
+
+
+/*=export_func optionSaveFile
+ *
+ * what: saves the option state to a file
+ *
+ * arg: tOptions*, pOpts, 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* pOpts)
+{
+ tOptDesc* pOD;
+ int ct;
+ FILE * fp = open_sv_file(pOpts);
+
+ if (fp == NULL)
+ return;
+
+ /*
+ * FOR each of the defined options, ...
+ */
+ ct = pOpts->presetOptCt;
+ pOD = pOpts->pOptDesc;
+ do {
+ tOptDesc * p;
+
+ /*
+ * IF the option has not been defined
+ * OR it does not take an initialization value
+ * OR it is equivalenced to another option
+ * THEN continue (ignore it)
+ *
+ * Equivalenced options get picked up when the equivalenced-to
+ * option is processed.
+ */
+ if (UNUSED_OPT(pOD))
+ continue;
+
+ if ((pOD->fOptState & OPTST_DO_NOT_SAVE_MASK) != 0)
+ continue;
+
+ if ( (pOD->optEquivIndex != NO_EQUIVALENT)
+ && (pOD->optEquivIndex != pOD->optIndex))
+ 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!
+ */
+ p = ((pOD->fOptState & OPTST_EQUIVALENCE) != 0)
+ ? (pOpts->pOptDesc + pOD->optActualIndex) : pOD;
+
+ switch (OPTST_GET_ARGTYPE(pOD->fOptState)) {
+ case OPARG_TYPE_NONE:
+ prt_no_arg_opt(fp, p, pOD);
+ break;
+
+ case OPARG_TYPE_NUMERIC:
+ prt_entry(fp, p, (void*)(p->optArg.argInt));
+ break;
+
+ case OPARG_TYPE_STRING:
+ prt_str_arg(fp, p);
+ break;
+
+ case OPARG_TYPE_ENUMERATION:
+ prt_enum_arg(fp, p);
+ break;
+
+ case OPARG_TYPE_MEMBERSHIP:
+ prt_set_arg(fp, p);
+ break;
+
+ case OPARG_TYPE_BOOLEAN:
+ prt_entry(fp, p, p->optArg.argBool ? "true" : "false");
+ break;
+
+ case OPARG_TYPE_HIERARCHY:
+ prt_nested(fp, p);
+ break;
+
+ case OPARG_TYPE_FILE:
+ prt_file_arg(fp, p, pOpts);
+ break;
+
+ default:
+ break; /* cannot handle - skip it */
+ }
+ } while (pOD++, (--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..a05588d
--- /dev/null
+++ b/autoopts/sort.c
@@ -0,0 +1,336 @@
+
+/*
+ * \file sort.c
+ *
+ * Time-stamp: "2011-05-24 18:07:14 bkorb"
+ *
+ * This module implements argument sorting.
+ *
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+ *
+ * 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+ * 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+ * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
+ */
+
+/* = = = START-STATIC-FORWARD = = = */
+static tSuccess
+mustHandleArg(tOptions* pOpts, char* pzArg, tOptState* pOS,
+ char** ppzOpts, int* pOptsIdx);
+
+static tSuccess
+mayHandleArg(tOptions* pOpts, char* pzArg, tOptState* pOS,
+ char** ppzOpts, int* pOptsIdx);
+
+static tSuccess
+checkShortOpts(tOptions* pOpts, char* pzArg, tOptState* pOS,
+ char** ppzOpts, int* pOptsIdx);
+/* = = = END-STATIC-FORWARD = = = */
+
+/*
+ * "mustHandleArg" and "mayHandleArg" 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
+mustHandleArg(tOptions* pOpts, char* pzArg, tOptState* pOS,
+ char** ppzOpts, int* pOptsIdx)
+{
+ /*
+ * 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 (*pzArg != 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 (pOpts->curOptIdx >= pOpts->origArgCt)
+ return FAILURE;
+
+ ppzOpts[ (*pOptsIdx)++ ] = pOpts->origArgVect[ (pOpts->curOptIdx)++ ];
+ return SUCCESS;
+}
+
+static tSuccess
+mayHandleArg(tOptions* pOpts, char* pzArg, tOptState* pOS,
+ char** ppzOpts, int* pOptsIdx)
+{
+ /*
+ * 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 (*pzArg != 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 (pOpts->curOptIdx >= pOpts->origArgCt)
+ return PROBLEM;
+
+ pzArg = pOpts->origArgVect[ pOpts->curOptIdx ];
+ if (*pzArg != '-')
+ ppzOpts[ (*pOptsIdx)++ ] = pOpts->origArgVect[ (pOpts->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
+checkShortOpts(tOptions* pOpts, char* pzArg, tOptState* pOS,
+ char** ppzOpts, int* pOptsIdx)
+{
+ while (*pzArg != NUL) {
+ if (FAILED(opt_find_short(pOpts, (tAoUC)*pzArg, pOS)))
+ return FAILURE;
+
+ /*
+ * See if we can have an arg.
+ */
+ if (OPTST_GET_ARGTYPE(pOS->pOD->fOptState) == OPARG_TYPE_NONE) {
+ pzArg++;
+
+ } 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 (pzArg[1] != NUL)
+ return SUCCESS;
+
+ pzArg = pOpts->origArgVect[ pOpts->curOptIdx ];
+ if (*pzArg != '-')
+ ppzOpts[ (*pOptsIdx)++ ] =
+ pOpts->origArgVect[ (pOpts->curOptIdx)++ ];
+ return SUCCESS;
+
+ } else {
+ /*
+ * IF we need another argument, be sure it is there and
+ * take it.
+ */
+ if (pzArg[1] == NUL) {
+ if (pOpts->curOptIdx >= pOpts->origArgCt)
+ return FAILURE;
+ ppzOpts[ (*pOptsIdx)++ ] =
+ pOpts->origArgVect[ (pOpts->curOptIdx)++ ];
+ }
+ return SUCCESS;
+ }
+ }
+ return SUCCESS;
+}
+
+/*
+ * If the program wants sorted options (separated operands and options),
+ * then this routine will to the trick.
+ */
+LOCAL void
+optionSort(tOptions* pOpts)
+{
+ char** ppzOpts;
+ char** ppzOpds;
+ int optsIdx = 0;
+ int opdsIdx = 0;
+
+ tOptState os = OPTSTATE_INITIALIZER(DEFINED);
+
+ /*
+ * Disable for POSIX conformance, or if there are no operands.
+ */
+ if ( (getenv("POSIXLY_CORRECT") != NULL)
+ || NAMED_OPTS(pOpts))
+ return;
+
+ /*
+ * Make sure we can allocate two full-sized arg vectors.
+ */
+ ppzOpts = malloc(pOpts->origArgCt * sizeof(char*));
+ if (ppzOpts == NULL)
+ goto exit_no_mem;
+
+ ppzOpds = malloc(pOpts->origArgCt * sizeof(char*));
+ if (ppzOpds == NULL) {
+ free(ppzOpts);
+ goto exit_no_mem;
+ }
+
+ pOpts->curOptIdx = 1;
+ pOpts->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* pzArg;
+ tSuccess res;
+
+ /*
+ * If we're out of arguments, we're done. Join the option and
+ * operand lists into the original argument vector.
+ */
+ if (pOpts->curOptIdx >= pOpts->origArgCt) {
+ errno = 0;
+ goto joinLists;
+ }
+
+ pzArg = pOpts->origArgVect[ pOpts->curOptIdx ];
+ if (*pzArg != '-') {
+ ppzOpds[ opdsIdx++ ] = pOpts->origArgVect[ (pOpts->curOptIdx)++ ];
+ continue;
+ }
+
+ switch (pzArg[1]) {
+ case NUL:
+ /*
+ * A single hyphen is an operand.
+ */
+ ppzOpds[ opdsIdx++ ] = pOpts->origArgVect[ (pOpts->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 (pzArg[2] == NUL) {
+ ppzOpts[ optsIdx++ ] =
+ pOpts->origArgVect[ (pOpts->curOptIdx)++ ];
+ goto restOperands;
+ }
+ res = opt_find_long(pOpts, pzArg+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 ((pOpts->fOptSet & OPTPROC_SHORTOPT) == 0) {
+ res = opt_find_long(pOpts, pzArg+1, &os);
+ } else {
+ res = opt_find_short(pOpts, (tAoUC)pzArg[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.
+ */
+ ppzOpts[ optsIdx++ ] = pOpts->origArgVect[ (pOpts->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(checkShortOpts(pOpts, pzArg+2, &os, ppzOpts,
+ &optsIdx)) ) {
+ errno = EINVAL;
+ goto freeTemps;
+ }
+
+ } else if (os.pOD->fOptState & OPTST_ARG_OPTIONAL) {
+ switch (mayHandleArg(pOpts, pzArg+2, &os, ppzOpts, &optsIdx)) {
+ case FAILURE: errno = EIO; goto freeTemps;
+ case PROBLEM: errno = 0; goto joinLists;
+ }
+
+ } else {
+ switch (mustHandleArg(pOpts, pzArg+2, &os, ppzOpts, &optsIdx)) {
+ case PROBLEM:
+ case FAILURE: errno = EIO; goto freeTemps;
+ }
+ }
+ } /* for (;;) */
+
+ restOperands:
+ while (pOpts->curOptIdx < pOpts->origArgCt)
+ ppzOpds[ opdsIdx++ ] = pOpts->origArgVect[ (pOpts->curOptIdx)++ ];
+
+ joinLists:
+ if (optsIdx > 0)
+ memcpy(pOpts->origArgVect + 1, ppzOpts, optsIdx * sizeof(char*));
+ if (opdsIdx > 0)
+ memcpy(pOpts->origArgVect + 1 + optsIdx, ppzOpds,
+ opdsIdx * sizeof(char*));
+
+ freeTemps:
+ free(ppzOpts);
+ 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..ecf52ab
--- /dev/null
+++ b/autoopts/stack.c
@@ -0,0 +1,269 @@
+
+/**
+ * \file stack.c
+ *
+ * Time-stamp: "2012-08-11 08:35:28 bkorb"
+ *
+ * This is a special option processing routine that will save the
+ * argument to an option in a FIFO queue.
+ *
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+ *
+ * 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+ * 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+ * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
+ */
+
+#ifdef WITH_LIBREGEX
+# include REGEX_HEADER
+#endif
+
+/*=export_func optionUnstackArg
+ * private:
+ *
+ * what: Remove option args from a stack
+ * arg: + tOptions* + pOpts + program options descriptor +
+ * arg: + tOptDesc* + pOptDesc + the descriptor for this arg +
+ *
+ * doc:
+ * Invoked for options that are equivalenced to stacked options.
+=*/
+void
+optionUnstackArg(tOptions * pOpts, tOptDesc * pOptDesc)
+{
+ tArgList * pAL;
+
+ (void)pOpts;
+
+ if (pOpts <= OPTPROC_EMIT_LIMIT)
+ return;
+
+ if ((pOptDesc->fOptState & OPTST_RESET) != 0)
+ return;
+
+ pAL = (tArgList*)pOptDesc->optCookie;
+
+ /*
+ * IF we don't have any stacked options,
+ * THEN indicate that we don't have any of these options
+ */
+ if (pAL == NULL) {
+ pOptDesc->fOptState &= OPTST_PERSISTENT_MASK;
+ if ((pOptDesc->fOptState & OPTST_INITENABLED) == 0)
+ pOptDesc->fOptState |= OPTST_DISABLED;
+ return;
+ }
+
+#ifdef WITH_LIBREGEX
+ {
+ regex_t re;
+ int i, ct, dIdx;
+
+ if (regcomp(&re, pOptDesc->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 = pAL->useCt; --ct >= 0; i++) {
+ char const * pzSrc = pAL->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);
+ pAL->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)
+ pAL->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 = pAL->useCt; --ct >= 0; i++) {
+ tCC* pzSrc = pAL->apzArgs[ i ];
+ char* pzEq = strchr(pzSrc, '=');
+
+ if (pzEq != NULL)
+ *pzEq = NUL;
+
+ if (strcmp(pzSrc, pOptDesc->optArg.argString) == 0) {
+ /*
+ * Remove this entry by reducing the in-use count
+ * and *not* putting the string pointer back into
+ * the list.
+ */
+ AGFREE(pzSrc);
+ pAL->useCt--;
+ } else {
+ if (pzEq != NULL)
+ *pzEq = '=';
+
+ /*
+ * IF we have dropped an entry
+ * THEN we have to move the current one.
+ */
+ if (dIdx != i)
+ pAL->apzArgs[ dIdx ] = pzSrc;
+ dIdx++;
+ }
+ }
+ }
+#endif /* WITH_LIBREGEX */
+ /*
+ * IF we have unstacked everything,
+ * THEN indicate that we don't have any of these options
+ */
+ if (pAL->useCt == 0) {
+ pOptDesc->fOptState &= OPTST_PERSISTENT_MASK;
+ if ((pOptDesc->fOptState & OPTST_INITENABLED) == 0)
+ pOptDesc->fOptState |= OPTST_DISABLED;
+ AGFREE((void*)pAL);
+ pOptDesc->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.
+ */
+LOCAL 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 = (void*)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*) * (pAL->allocCt - MIN_ARG_ALLOC_CT);
+ pAL = (tArgList*)AGREALOC((void*)pAL, sz, "expanded opt arg stack");
+ if (pAL == NULL)
+ return;
+ *ppAL = (void*)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* + pOpts + program options descriptor +
+ * arg: + tOptDesc* + pOptDesc + the descriptor for this arg +
+ *
+ * doc:
+ * Keep an entry-ordered list of option arguments.
+=*/
+void
+optionStackArg(tOptions * pOpts, tOptDesc * pOD)
+{
+ char * pz;
+
+ if (pOpts <= OPTPROC_EMIT_LIMIT)
+ return;
+
+ if ((pOD->fOptState & OPTST_RESET) != 0) {
+ tArgList* pAL = (void*)pOD->optCookie;
+ int ix;
+ if (pAL == NULL)
+ return;
+
+ ix = pAL->useCt;
+ while (--ix >= 0)
+ AGFREE(pAL->apzArgs[ix]);
+ AGFREE(pAL);
+
+ } else {
+ if (pOD->optArg.argString == NULL)
+ return;
+
+ AGDUPSTR(pz, pOD->optArg.argString, "stack arg");
+ addArgListEntry(&(pOD->optCookie), (void*)pz);
+ }
+}
+/*
+ * Local Variables:
+ * mode: C
+ * c-file-style: "stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * end of autoopts/stack.c */
diff --git a/autoopts/strequate.3 b/autoopts/strequate.3
new file mode 100644
index 0000000..fee20a1
--- /dev/null
+++ b/autoopts/strequate.3
@@ -0,0 +1,32 @@
+.TH strequate 3 2012-08-11 "" "Programmer's Manual"
+.\" DO NOT EDIT THIS FILE (strequate.3)
+.\"
+.\" It has been AutoGen-ed August 11, 2012 at 09:44:56 AM by AutoGen 5.16.2
+.\" 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), optionNextValue(3), optionOnlyUsage(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), pathfind(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..5e8077f
--- /dev/null
+++ b/autoopts/streqvcmp.3
@@ -0,0 +1,39 @@
+.TH streqvcmp 3 2012-08-11 "" "Programmer's Manual"
+.\" DO NOT EDIT THIS FILE (streqvcmp.3)
+.\"
+.\" It has been AutoGen-ed August 11, 2012 at 09:44:56 AM by AutoGen 5.16.2
+.\" 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), optionNextValue(3), optionOnlyUsage(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), pathfind(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..54a063a
--- /dev/null
+++ b/autoopts/streqvcmp.c
@@ -0,0 +1,267 @@
+
+/**
+ * \file streqvcmp.c
+ *
+ * Time-stamp: "2012-03-31 13:17:39 bkorb"
+ *
+ * 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).
+ *
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+ *
+ * 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+ * 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+ * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/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(tCC* s1, tCC* s2, int ct)
+{
+ for (; ct > 0; --ct) {
+ unsigned char u1 = (unsigned char) *s1++;
+ unsigned char u2 = (unsigned char) *s2++;
+ int 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(tCC* s1, tCC* s2)
+{
+ for (;;) {
+ unsigned char u1 = (unsigned char) *s1++;
+ unsigned char u2 = (unsigned char) *s2++;
+ int 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 chTo = (int)To & 0xFF;
+ unsigned int chFrom = (int)From & 0xFF;
+
+ do {
+ charmap[chFrom] = (unsigned char)chTo;
+ chFrom++;
+ chTo++;
+ if ((chFrom >= sizeof(charmap)) || (chTo >= 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)*s;
+ while (*s != NUL)
+ charmap[ (unsigned)*(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)*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..a4c3518
--- /dev/null
+++ b/autoopts/streqvmap.3
@@ -0,0 +1,48 @@
+.TH streqvmap 3 2012-08-11 "" "Programmer's Manual"
+.\" DO NOT EDIT THIS FILE (streqvmap.3)
+.\"
+.\" It has been AutoGen-ed August 11, 2012 at 09:44:56 AM by AutoGen 5.16.2
+.\" 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), optionNextValue(3), optionOnlyUsage(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), pathfind(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..9433439
--- /dev/null
+++ b/autoopts/strneqvcmp.3
@@ -0,0 +1,43 @@
+.TH strneqvcmp 3 2012-08-11 "" "Programmer's Manual"
+.\" DO NOT EDIT THIS FILE (strneqvcmp.3)
+.\"
+.\" It has been AutoGen-ed August 11, 2012 at 09:44:56 AM by AutoGen 5.16.2
+.\" 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), optionNextValue(3), optionOnlyUsage(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), pathfind(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..6a89b1b
--- /dev/null
+++ b/autoopts/strtransform.3
@@ -0,0 +1,37 @@
+.TH strtransform 3 2012-08-11 "" "Programmer's Manual"
+.\" DO NOT EDIT THIS FILE (strtransform.3)
+.\"
+.\" It has been AutoGen-ed August 11, 2012 at 09:44:56 AM by AutoGen 5.16.2
+.\" 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), optionNextValue(3), optionOnlyUsage(3), optionProcess(3), optionRestore(3), optionSaveFile(3), optionSaveState(3), optionUnloadNested(3), optionVersion(3), pathfind(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..ce8ea2d
--- /dev/null
+++ b/autoopts/test/Makefile.am
@@ -0,0 +1,53 @@
+## -*- Mode: Makefile -*-
+##
+## Makefile.am
+##
+## Time-stamp: "2012-05-13 16:02:42 bkorb"
+## Author: Bruce Korb <bkorb@gnu.org>
+##
+## This file is part of AutoOpts, a companion to AutoGen.
+## AutoOpts is free software.
+## AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
+
+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
+
+testsubdir = ./testdir
+
+TESTS_ENVIRONMENT = TERM='' top_builddir="$(top_builddir)"
+
+distclean-local:
+ -rm -rf $(testsubdir) FAILURES
+
+check : perm-stamp
+
+perm-stamp :
+ @-cd $(srcdir) ; chmod +x *.test 2>/dev/null
+
+verbose :
+ rm -rf FAILURES testdir ; VERBOSE=true ; export VERBOSE ; \
+ $(MAKE) check TESTS="$(TESTS)"
+
+# Makefile.am ends here
diff --git a/autoopts/test/Makefile.in b/autoopts/test/Makefile.in
new file mode 100644
index 0000000..a5a0d5b
--- /dev/null
+++ b/autoopts/test/Makefile.in
@@ -0,0 +1,560 @@
+# Makefile.in generated by automake 1.12.2 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994-2012 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__make_dryrun = \
+ { \
+ am__dry=no; \
+ case $$MAKEFLAGS in \
+ *\\[\ \ ]*) \
+ echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
+ | grep '^AM OK$$' >/dev/null || am__dry=yes;; \
+ *) \
+ for am__flg in $$MAKEFLAGS; do \
+ case $$am__flg in \
+ *=*|--*) ;; \
+ *n*) am__dry=yes; break;; \
+ esac; \
+ done;; \
+ esac; \
+ test $$am__dry = yes; \
+ }
+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
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(srcdir)/defs.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/config/ag_macros.m4 \
+ $(top_srcdir)/config/extensions.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/snprintfv.m4 \
+ $(top_srcdir)/config/unlocked-io.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES = defs
+CONFIG_CLEAN_VPATH_FILES =
+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__tty_colors_dummy = \
+ mgn= red= grn= lgn= blu= brg= std=; \
+ am__color_tests=no
+am__tty_colors = $(am__tty_colors_dummy)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AGEN5_TESTS = @AGEN5_TESTS@
+AG_GUILE = @AG_GUILE@
+AG_LDFLAGS = @AG_LDFLAGS@
+AG_MAJOR_VERSION = @AG_MAJOR_VERSION@
+AG_MINOR_VERSION = @AG_MINOR_VERSION@
+AG_TIMEOUT = @AG_TIMEOUT@
+AG_VERSION = @AG_VERSION@
+AG_XML2 = @AG_XML2@
+AGexe = @AGexe@
+AGnam = @AGnam@
+AMTAR = @AMTAR@
+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_VERSION = @GUILE_VERSION@
+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@
+LIBGUILE_CFLAGS = @LIBGUILE_CFLAGS@
+LIBGUILE_LIBS = @LIBGUILE_LIBS@
+LIBGUILE_PATH = @LIBGUILE_PATH@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBSNPRINTFV = @LIBSNPRINTFV@
+LIBTOOL = @LIBTOOL@
+LIBXML2_CFLAGS = @LIBXML2_CFLAGS@
+LIBXML2_LIBS = @LIBXML2_LIBS@
+LIBXML2_PATH = @LIBXML2_PATH@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+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@
+POSIX_SHELL = @POSIX_SHELL@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+TEXI2HTML = @TEXI2HTML@
+VERSION = @VERSION@
+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@
+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
+
+testsubdir = ./testdir
+TESTS_ENVIRONMENT = TERM='' top_builddir="$(top_builddir)"
+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 autoopts/test/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu autoopts/test/Makefile
+.PRECIOUS: 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__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ 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
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+cscope cscopelist:
+
+
+check-TESTS: $(TESTS)
+ @failed=0; all=0; xfail=0; xpass=0; skip=0; \
+ srcdir=$(srcdir); export srcdir; \
+ list=' $(TESTS) '; \
+ $(am__tty_colors); \
+ if test -n "$$list"; then \
+ for tst in $$list; do \
+ if test -f ./$$tst; then dir=./; \
+ elif test -f $$tst; then dir=; \
+ else dir="$(srcdir)/"; fi; \
+ if $(TESTS_ENVIRONMENT) $${dir}$$tst $(AM_TESTS_FD_REDIRECT); then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xpass=`expr $$xpass + 1`; \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=XPASS; \
+ ;; \
+ *) \
+ col=$$grn; res=PASS; \
+ ;; \
+ esac; \
+ elif test $$? -ne 77; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xfail=`expr $$xfail + 1`; \
+ col=$$lgn; res=XFAIL; \
+ ;; \
+ *) \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=FAIL; \
+ ;; \
+ esac; \
+ else \
+ skip=`expr $$skip + 1`; \
+ col=$$blu; res=SKIP; \
+ fi; \
+ echo "$${col}$$res$${std}: $$tst"; \
+ done; \
+ if test "$$all" -eq 1; then \
+ tests="test"; \
+ All=""; \
+ else \
+ tests="tests"; \
+ All="All "; \
+ fi; \
+ if test "$$failed" -eq 0; then \
+ if test "$$xfail" -eq 0; then \
+ banner="$$All$$all $$tests passed"; \
+ else \
+ if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
+ banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
+ fi; \
+ else \
+ if test "$$xpass" -eq 0; then \
+ banner="$$failed of $$all $$tests failed"; \
+ else \
+ if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
+ banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
+ fi; \
+ fi; \
+ dashes="$$banner"; \
+ skipped=""; \
+ if test "$$skip" -ne 0; then \
+ if test "$$skip" -eq 1; then \
+ skipped="($$skip test was not run)"; \
+ else \
+ skipped="($$skip tests were not run)"; \
+ fi; \
+ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$skipped"; \
+ fi; \
+ report=""; \
+ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
+ report="Please report to $(PACKAGE_BUGREPORT)"; \
+ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$report"; \
+ fi; \
+ dashes=`echo "$$dashes" | sed s/./=/g`; \
+ if test "$$failed" -eq 0; then \
+ col="$$grn"; \
+ else \
+ col="$$red"; \
+ fi; \
+ echo "$${col}$$dashes$${std}"; \
+ echo "$${col}$$banner$${std}"; \
+ test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \
+ test -z "$$report" || echo "$${col}$$report$${std}"; \
+ echo "$${col}$$dashes$${std}"; \
+ test "$$failed" -eq 0; \
+ else :; fi
+
+distdir: $(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:
+
+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 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 \
+ uninstall uninstall-am
+
+
+distclean-local:
+ -rm -rf $(testsubdir) FAILURES
+
+check : perm-stamp
+
+perm-stamp :
+ @-cd $(srcdir) ; chmod +x *.test 2>/dev/null
+
+verbose :
+ rm -rf FAILURES testdir ; VERBOSE=true ; export VERBOSE ; \
+ $(MAKE) check TESTS="$(TESTS)"
+
+# 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..1cde083
--- /dev/null
+++ b/autoopts/test/alias.test
@@ -0,0 +1,120 @@
+#! /bin/sh
+#
+# alias.test --- test option aliasing
+#
+# Time-stamp: "2012-05-12 19:56:13 bkorb"
+# Author: Bruce Korb <bkorb@gnu.org>
+##
+## This file is part of AutoOpts, a companion to AutoGen.
+## AutoOpts is free software.
+## AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
+
+. ./defs
+failure() { exit 1 ; }
+# # # # # # # # # # 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 [ -<flag> [<val>] | --<name>[{=| }<val>] ]... arg [...]
+ Flg Arg Option-Name Description
+ -o Str option The option option descrip
+ -s Num second The second option descrip
+ -a Str a-opt This is an alias for 'option'
+ -b Num b-second This is an alias for 'second'
+ -? 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} '^This is 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..ee7fa0d
--- /dev/null
+++ b/autoopts/test/argument.test
@@ -0,0 +1,209 @@
+#! /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.
+#
+# Time-stamp: "2012-08-11 08:12:41 bkorb"
+# Author: Bruce Korb <bkorb@gnu.org>
+##
+## This file is part of AutoOpts, a companion to AutoGen.
+## AutoOpts is free software.
+## AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/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 [ -<flag> [<val>] ]...
+ 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[0] = ' /* no-op zero */;';
+ flag-code[1] = ' /* no-op one */;';
+ };
+ include = '#include <stdlib.h>';
+ _EOF_
+exec 3>&-
+
+${AG_L} ${testname}2.def || \
+ failure AutoGen could not process
+{
+ ${SED} '/^#if.*TEST MAIN PROCEDURE:/,/#endif.*defined TEST_/d
+ /^#/s/_ARGUMENT_/_ARGUMENT2_/' \
+ ${testname}2.c
+ cat <<EOF
+int main( int argc, char** argv ) {
+ optionProcess( &test_argumentOptions, argc, argv );
+ return 0; }
+EOF
+} > 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 [ -<flag> [<val>] ]...
+ 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 <<EOF
+int main( int argc, char** argv ) {
+ optionProcess( &test_argumentOptions, argc, argv );
+ for (;;) { int ch = getc(OPT_VALUE_SECOND);
+ if (ch == EOF) break;
+ putc(ch, stdout); }
+ return fclose(OPT_VALUE_SECOND); }
+EOF
+} > 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 [ -<flag> [<val>] ]...
+ 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 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..506ca10
--- /dev/null
+++ b/autoopts/test/cfg-edit.test
@@ -0,0 +1,330 @@
+#! /bin/sh
+# -*- Mode: Shell-script -*-
+# ----------------------------------------------------------------------
+# rc.test --- test loading and saving of rc files
+#
+# Time-stamp: "2012-03-31 13:10:38 bkorb"
+# Author: Bruce Korb <bkorb@gnu.org>
+##
+## This file is part of AutoOpts, a companion to AutoGen.
+## AutoOpts is free software.
+## AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
+#
+# ----------------------------------------------------------------------
+. ./defs
+
+# # # # # # # # # # DEFINITIONS FILE # # # # # # # # #
+
+test_name=`echo ${testname} | ${SED} 's/-/_/g'`
+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 = '[ <output-config-file> ]';
+
+ 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} [ -<flag> [<val>] ]... [ <output-config-file> ]
+ 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
+cmp -s ${basehelp} ${testname}.help || \
+ failure "`diff ${basehelp} ${testname}.help`"
+
+./${testname} -m 'one + three + seven' '->'
+members=`${SED} -n 's/^members *//p' ${cfg_file}`
+case "${members}" in
+'none + 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>foo${ht}lish</foo>, <bar type=integer>1234</bar>, able"
+arg2='foo, <bar type=integer>4321</bar> <gr type=nested>one, two=2, three</gr>'
+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_
+ <struct type=nested>
+ <able/>
+ <bar type=integer>0x4D2</bar>
+ <foo>foo&#x09;lish</foo>
+ <stumble/>
+ </struct>
+ <struct type=nested>
+ <bar type=integer>0x10E1</bar>
+ <foo/>
+ <gr type=nested>
+ <one/>
+ <three/>
+ <two>2</two>
+ </gr>
+ </struct>
+ members none + 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..8767eda
--- /dev/null
+++ b/autoopts/test/cond.test
@@ -0,0 +1,194 @@
+#! /bin/sh
+# -*- Mode: Shell-script -*-
+# ----------------------------------------------------------------------
+# cond.test --- test conditionally compiled option
+#
+# Time-stamp: "2012-03-31 13:09:15 bkorb"
+# Author: Bruce Korb <bkorb@gnu.org>
+##
+## This file is part of AutoOpts, a companion to AutoGen.
+## AutoOpts is free software.
+## AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/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 <<EOF
+flag = {
+ name = condition;
+ value = c;
+ ifdef = COND;
+ descrip = "cond test";
+ arg-type = number;
+ doc = mumble;
+};
+
+flag = {
+ name = interfere;
+ value = I;
+ descrip = "cond interference test";
+ arg-type = number;
+ doc = stumble;
+};
+EOF
+echo ${AG_L} ${testname}.def
+${AG_L} ${testname}.def || \
+ failure AutoGen could not process
+
+# # # # # # # # # # FIRST TEST # # # # # # # # #
+
+compile "-?"
+mv ${testname} ${testname}-1
+echo creating ${testname}-1.help
+clean_help > ${testname}-1.help <<'_EOF_'
+test_cond - Test AutoOpts for cond
+USAGE: cond [ -<flag> [<val>] ]...
+ 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 [ -<flag> [<val>] ]...
+ 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 [ -<flag> [<val>] ]...
+ 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 [ -<flag> [<val>] ]...
+ 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..d8b6280
--- /dev/null
+++ b/autoopts/test/config.test
@@ -0,0 +1,201 @@
+#! /bin/sh
+# -*- Mode: Shell-script -*-
+# ----------------------------------------------------------------------
+# rc.test --- test loading and saving of rc files
+#
+# Time-stamp: "2011-02-02 12:10:27 bkorb"
+# Author: Bruce Korb <bkorb@gnu.org>
+##
+## This file is part of AutoOpts, a companion to AutoGen.
+## AutoOpts is free software.
+## AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
+#
+# ----------------------------------------------------------------------
+. ./defs
+
+# # # # # # # # # # PROGRAM FILE # # # # # # # # #
+
+cat > ${testname}.c <<- _EOTest_
+ #include <stdio.h>
+ #include "config.h"
+ #include <autoopts/options.h>
+
+ 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.
+
+ <n4_ty type=nested>
+ foo : foolish
+ <b4r type=bool> YES!! </b4r>
+ </n4_ty>
+ alpha, beta ', gamma'
+ <beta cooked> "Carol\tTine\n"
+ </beta>
+ <zzyzx type=integer> 42 </zzyzx>
+ _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..d7669ab
--- /dev/null
+++ b/autoopts/test/defs.in
@@ -0,0 +1,351 @@
+#! /bin/echo this_file_should_be_sourced,_not_executed
+# -*- Mode: Shell-script -*-
+#
+# defs --- define the environment for autogen tests.
+#
+# Time-stamp: "2012-05-13 16:02:07 bkorb"
+# Author: Bruce Korb <bkorb@gnu.org>
+##
+## This file is part of AutoOpts, a companion to AutoGen.
+## AutoOpts is free software.
+## AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/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
+
+ script_name=$1
+ set -a
+ . ${top_builddir}/config/shdefs
+ progname=`echo "$script_name" | ${SED} 's,^.*/,,'`
+ testname=`echo "$progname" | ${SED} 's,\..*$,,'`
+ test_name=`echo ${testname} | ${SED} 's/-/_/g'`
+ PS4=">${testname}-\${FUNCNAME}> "
+ test -z "$srcdir" && exit 1
+ srcdir=`cd $srcdir >/dev/null && pwd`
+ ( exec 2>/dev/null; ulimit -c unlimited ) && \
+ ulimit -c unlimited
+
+ test -z "${CFLAGS}" && CFLAGS='@CFLAGS@'
+ CFLAGS="${CFLAGS} @DEFS@"
+ test -z "${testsubdir}" && testsubdir=testdir
+ test -z "${PAGER}" && PAGER=more
+ nl='
+' ht=' '
+
+ 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
+ test "X$vars" = X || unset $vars
+}
+
+# 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
+
+ set -- $bad
+ test "x${RANDOM}" = "x${RANDOM}" && RANDOM=`expr 0${RANDOM} + 1 2>/dev/null`
+
+ f=ZZPURGE-${1}-${RANDOM}-$$
+ if test $# -gt 1
+ then mkdir ${f}
+ mv $* ${f}/.
+ else mv $1 ${f}
+ fi
+}
+
+init_tests()
+{
+ logfile=`pwd`/testdir/${testname}.log
+ exec 8>&2 1>${logfile} 2>&1
+
+ TMPDIR=`pwd`/testdir/${testname}-tmpd
+ mkdir ${TMPDIR}
+
+ f=`\cd ${LIBGUILE_PATH}/../bin && pwd`
+ PATH=${f}:${PATH}
+ echo PATH is ${PATH} >&2
+
+ builddir=`pwd`
+ testsubdir=testdir
+ CFLAGS=`echo ${CFLAGS} | \
+ ${SED} "s/-Werror[^ ${ht}]*//g;s/-Wextra//g"`
+
+ lo_dir=${top_builddir}/autoopts
+ test -d ${lo_dir}/.libs && lo_dir=${lo_dir}/.libs
+ 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
+ lo_lib=`find ${lo_dir} -type f -name libopts*.${OBJEXT}`
+ LIB="${lo_lib} ${LIB}"
+
+ AG_L=run_ag\ ao
+ agl_opts="-L${top_builddir}/autoopts/tpl -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=:
+ VERBOSE=false
+ purge testdir
+
+ # Sometimes, MSDos FS cannot even rename the directory!!
+ #
+ if test -d testdir
+ then purge testdir/* testdir/.??*
+ else msg=echo
+ mkdir testdir || exit 1
+ fi
+
+ run_ag()
+ {
+ local 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 testdir || mkdir testdir || exit 1
+
+ run_ag()
+ {
+ local tfile=${testname}-aglog-${1}-$$.log
+ shift
+ local opts=''
+ local tr="--trace=every --trace-out=>>${tfile}"
+
+ case " $* " in
+ *' -L'* ) : ;;
+ * ) opts="${agl_opts}" ;;
+ esac
+
+ MALLOC_CHECK_=2 \
+ ${AGexe} ${opts} ${tr} "$@"
+ }
+
+ init_tests
+}
+
+cfg_inc()
+{
+ cd testdir || {
+ echo "Cannot make or change into testdir" >&8
+ exit 1
+ }
+ testsubdir=`pwd`
+
+ 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() {
+ test -z "$sedcmd" && s= || s="${sedcmd}${nl}"
+ s="${s}/^Packaged by/d${nl}"
+ s="${s}/^Report .* bugs to/d${nl}"
+ s="${s}/[Pp]lease send bug reports/d${nl}"
+ s="${s}/^[ ${ht}]*\$/d"
+
+ ${SED} "${s}"
+}
+
+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 | /usr/bin/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
+ ./${Cexe} ${*} ${dosed} || \
+ failure cannot obtain help output for ${Csrc}
+ fi | clean_help > ${Csrc}.help
+ Csrc='' Cexe='' Dnam=''
+}
+
+cleanup()
+{
+ trap '' 15
+ ${setx}
+ ${VERBOSE} || {
+ cd ${builddir}
+ purge testdir
+ test -d testdir && mv testdir ZZJUNK-$$
+ }
+ ${msg} ${testname} done
+}
+
+# A standard failure function
+#
+failure()
+{
+ trap '' 15
+ ${setx}
+ cd ${testsubdir}
+ if test -d ../FAILURES
+ then ( \cd ../FAILURES ; purge -rf ${testname}* .*${testname}* )
+ else mkdir ../FAILURES ; fi
+
+ exec > /dev/tty 2>&8
+ cat ${logfile} >&2
+
+ {
+ mv -f ${testname}* .*${testname}* ../FAILURES || :
+ } 2>/dev/null
+ for f in core*
+ do test -f ${f} && mv -f ${f} ../FAILURES/${testname}-${f} ; done
+
+ echo FAILURE: "$*" >&8
+ exit 1
+}
+
+# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+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
+
+cfg_inc
+
+trap "failure 'test ${testname} killed on timeout'" 15
+( ( exec > /dev/null 2>&1 </dev/null
+ test -z "${kill_delay}" && kill_delay=3
+ kill_delay=`expr $kill_delay '*' $AG_TIMEOUT`
+ sleep ${kill_delay}
+ ps -p $$ || exit
+ kill -15 $$
+ sleep 1
+ ps -p $$ || exit
+ mv -f `dirname $logfile` ${builddir}/FAILED-${testname}
+ kill -9 $$
+) &
+)
+
+## 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..d0c2989
--- /dev/null
+++ b/autoopts/test/doc.test
@@ -0,0 +1,848 @@
+#! /bin/sh
+# -*- Mode: Shell-script -*-
+#
+# doc.test --- test doc templates
+#
+# Time-stamp: "2012-08-11 08:54:27 bkorb"
+# Author: Bruce Korb <bkorb@gnu.org>
+#
+## This file is part of AutoOpts, a companion to AutoGen.
+## AutoOpts is free software.
+## AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
+
+. ./defs
+
+test_src=${srcdir}/${testname}.test
+
+# # # # # # # # # # 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 # # # # # # # # #
+${AGexe} ${agl_opts} -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 "1,/^##* *BEGIN-TEXI/d
+ /^@ignore/,/^@end ignore/d
+ /^## END-TEXI/{;s/.*//;q;}" \
+ ${test_src} > ${testname}-base.texi
+
+outfiles="${testname}-res.texi ${testname}-base.texi"
+cmp -s ${outfiles} || \
+ failure "Differences: ${outfiles}${nl}`diff ${outfiles}`"
+
+# # # # # # # # # # MAN DOC CHECK # # # # # # # # #
+${AGexe} ${agl_opts} -Tagman-cmd ${testname}.def
+test -f ${testname}.1 || \
+ failure "${testname}.1 not built"
+
+{
+ sed '/^\.\\"/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 ${outfiles}`"
+
+# # # # # # # # # # MDOC DOC CHECK # # # # # # # # #
+${AGexe} ${agl_opts} -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 ${outfiles}`"
+
+# # # # # # # # # # POT CHECK # # # # # # # # #
+${AGexe} ${agl_opts} -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 ${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-2012";
+ 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;
+
+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 an argument number.
+really enable debugging
+@subsubheading mtu option.
+@anchor{doc mtu}
+@cindex doc-mtu
+
+This is the ``set mtu for datagram tls'' option.
+This option takes an argument number.
+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 an argument number.
+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 an argument string.
+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
+.TH doc 1
+.SH NAME
+doc \- GnuTLS client
+.SH SYNOPSIS
+.B doc
+.RB [ \-\fIflag\fP " [\fIvalue\fP]]... [" \-\-\fIopt\-name\fP " [[=| ]\fIvalue\fP]]..." [hostname]
+.PP
+Operands and options may be intermixed. They will be reordered.
+.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
+.BR \-d " \fInumber\fP, " \-\-debug "=" \fInumber\fP
+Enable \fBdebugging\fP.
+This option takes an integer number as its argument.
+The value of \fInumber\fP is constrained to being:
+.in +4
+.nf
+.na
+in the range 0 through 9999
+.fi
+.in -4
+.sp
+really enable debugging
+.TP
+.BR \-\-mtu "=\fInumber\fP"
+Set MTU for datagram TLS.
+This option takes an integer number as its argument.
+The value of \fInumber\fP 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
+.BR \-\-crlf
+Send CR LF instead of LF.
+.sp
+Really send CR LF instead of LF
+.TP
+.BR \-\-x509fmtder
+Use DER format for certificates to read from.
+.sp
+Really use DER format for certificates to read from
+.SS "third group of options"
+.TP
+.BR \-\-recordsize "=\fInumber\fP"
+The maximum record size to advertize.
+This option takes an integer number as its argument.
+The value of \fInumber\fP 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
+.BR \-\-priority "=\fIstring\fP"
+Priorities string.
+.sp
+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 \(lqPriority strings\(rq for more
+information on allowed keywords
+.TP
+.BR \-h , " \-\-help"
+Display usage information and exit.
+.TP
+.BR \-M , " \-\-more-help"
+Pass the extended usage information through a pager.
+.TP
+.BR \-v " [{\fIv|c|n\fP}]," " \-\-version" "[=\fI{v|c|n}\fP]"
+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.
+.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
+- 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
+.BR 0 " (EXIT_SUCCESS)"
+Successful program execution.
+.TP
+.BR 1 " (EXIT_FAILURE)"
+The operation failed or the command syntax was not valid.
+.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-2012 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_
+
+# # # # # # # # # # # MAN PAGE
+
+cat <<_End_Of_MdocPage_
+## BEGIN-MDOC
+.Dt DOC 1 User Commands
+.Sh NAME
+.Nm doc
+.Nd GnuTLS client
+.Sh SYNOPSIS
+.Nm
+.Op Fl flags
+.Op Fl flag Ar value
+.Op Fl \-option-name Ar value
+[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 \-d " \fInumber\fP, " \-\-debug "=" \fInumber\fP
+Enable \fBdebugging\fP.
+This option takes an integer number as its argument.
+The value of \fInumber\fP is constrained to being:
+.in +4
+.nf
+.na
+in the range 0 through 9999
+.fi
+.in -4
+.sp
+really enable debugging
+.It \-\-mtu "=\fInumber\fP"
+Set MTU for datagram TLS.
+This option takes an integer number as its argument.
+The value of \fInumber\fP 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 \-\-crlf
+Send CR LF instead of LF.
+.sp
+Really send CR LF instead of LF
+.It \-\-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 \-\-recordsize "=\fInumber\fP"
+The maximum record size to advertize.
+This option takes an integer number as its argument.
+The value of \fInumber\fP 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 \-\-priority "=\fIstring\fP"
+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 \-h , " \-\-help"
+Display usage information and exit.
+.It \-M , " \-\-more-help"
+Pass the extended usage information through a pager.
+.It \-v " [{\fIv|c|n\fP}]," " \-\-version" "[=\fI{v|c|n}\fP]"
+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
+.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
+- 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.
+.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-2012 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 <bug-gnutls@gnu.org>.
+#
+#, 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 <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\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:41
+msgid "Enable debugging"
+msgstr ""
+
+#: doc.def:42
+msgid "really enable debugging"
+msgstr ""
+
+#: doc.def:49
+msgid "Set MTU for datagram TLS"
+msgstr ""
+
+#: doc.def:50
+msgid "Really set MTU for datagram TLS"
+msgstr ""
+
+#: doc.def:55
+msgid "second group of options"
+msgstr ""
+
+#: doc.def:61
+msgid "Send CR LF instead of LF"
+msgstr ""
+
+#: doc.def:62
+msgid "Really send CR LF instead of LF"
+msgstr ""
+
+#: doc.def:67
+msgid "Use DER format for certificates to read from"
+msgstr ""
+
+#: doc.def:68
+msgid "Really use DER format for certificates to read from"
+msgstr ""
+
+#: doc.def:73
+msgid "third group of options"
+msgstr ""
+
+#: doc.def:81
+msgid "The maximum record size to advertize"
+msgstr ""
+
+#: doc.def:82
+msgid "Really the maximum record size to advertize"
+msgstr ""
+
+#: doc.def:88
+msgid "Priorities string"
+msgstr ""
+
+#: doc.def:90
+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:104
+msgid "gnutls-cli-debug(1), gnutls-serv(1)"
+msgstr ""
+
+#: doc.def:111
+msgid "To connect to a server using PSK authentication, you need to enable the\n"
+ "choice of PSK by using a cipher priority parameter such as in the\n"
+ "example below. @example $ ./gnutls-cli -p 5556 localhost --pskusername\n"
+ "psk_identity \\\\ --pskkey 88f3824b3e5659f52d00e959bacab954b6540344 \\\\\n"
+ "--priority NORMAL:-KX-ALL:+ECDHE-PSK:+DHE-PSK:+PSK Resolving\n"
+ "'localhost'... Connecting to '127.0.0.1:5556'... - PSK authentication.\n"
+ "- Version: TLS1.1 - Key Exchange: PSK - Cipher: AES-128-CBC - MAC: SHA1\n"
+ "- Compression: NULL - Handshake was completed\n\n"
+ "- Simple Client Mode: @end example By keeping the --pskusername\n"
+ "parameter and removing the --pskkey parameter, it will query only for\n"
+ "the password during the handshake.\n\n"
+ "To list the ciphersuites in a priority string: @example $ ./gnutls-cli\n"
+ "--priority SECURE192 -l Cipher suites for SECURE192\n"
+ "TLS_ECDHE_ECDSA_AES_256_CBC_SHA384 0xc0, 0x24 TLS1.2\n"
+ "TLS_ECDHE_ECDSA_AES_256_GCM_SHA384 0xc0, 0x2e TLS1.2\n"
+ "TLS_ECDHE_RSA_AES_256_GCM_SHA384 0xc0, 0x30 TLS1.2\n"
+ "TLS_DHE_RSA_AES_256_CBC_SHA256 0x00, 0x6b TLS1.2\n"
+ "TLS_DHE_DSS_AES_256_CBC_SHA256 0x00, 0x6a TLS1.2\n"
+ "TLS_RSA_AES_256_CBC_SHA256 0x00, 0x3d TLS1.2 @end example"
+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..d3edf55
--- /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.
+#
+# Time-stamp: "2012-08-11 08:31:49 bkorb"
+# Author: Bruce Korb <bkorb@gnu.org>
+##
+## This file is part of AutoOpts, a companion to AutoGen.
+## AutoOpts is free software.
+## AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/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 = '[ <node> ]';
+ 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 <sys/types.h>\n"
+ "#include <sys/stat.h>\n"
+ "#include <stdio.h>\n"
+ "#include <stdlib.h>\n"
+ "#include <fcntl.h>\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} { -<flag> [<val>] | --<name>[{=| }<val>] }... [ <node> ]
+ 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..2c4cc74
--- /dev/null
+++ b/autoopts/test/equiv.test
@@ -0,0 +1,274 @@
+#! /bin/sh
+# -*- Mode: Shell-script -*-
+#
+# equiv.test --- test option equivivalence classes
+#
+# Time-stamp: "2012-02-12 09:28:59 bkorb"
+# Author: Bruce Korb <bkorb@gnu.org>
+##
+## This file is part of AutoOpts, a companion to AutoGen.
+## AutoOpts is free software.
+## AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/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 [ -<flag> [<val>] | --<name>[{=| }<val>] ]...
+ 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 [ -<flag> [<val>] | --<name>[{=| }<val>] ]...
+ 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 ..../testdir/.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 .*/testdir/, file ..../testdir/,' \
+ ${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..89f508e
--- /dev/null
+++ b/autoopts/test/errors.test
@@ -0,0 +1,232 @@
+#! /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.
+#
+# Time-stamp: "2011-08-07 17:37:02 bkorb"
+# Author: Bruce Korb <bkorb@gnu.org>
+##
+## This file is part of AutoOpts, a companion to AutoGen.
+## AutoOpts is free software.
+## AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
+
+. ./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 [ -<flag> [<val>] | --<name>[{=| }<val>] ]... 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 [ -<flag> [<val>] | --<name>[{=| }<val>] ]... 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..383c6fc
--- /dev/null
+++ b/autoopts/test/getopt.test
@@ -0,0 +1,668 @@
+#! /bin/sh
+# -*- Mode: Shell-script -*-
+#
+# getopt.test --- test getopt_long argument processing
+#
+# Time-stamp: "2012-05-12 19:54:26 bkorb"
+# Author: Bruce Korb <bkorb@gnu.org>
+#
+## This file is part of AutoOpts, a companion to AutoGen.
+## AutoOpts is free software.
+## AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
+
+. ./defs
+
+set -x
+PS4='>${FUNCNAME:-go}> '
+
+CC="${CC} ${CFLAGS} ${INC}"
+CFLAGS=''
+INC=''
+export AUTOGEN_TEMPL_DIRS=${TMPDIR}
+
+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} '2,/and the template file/d
+ /\$''Id.*\$/d
+ /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
+
+ CFLAGS="-I${TMPDIR}"
+ LDFLAGS="${LDFLAGS} ${LIB}"
+ export CFLAGS LDFLAGS TMPDIR
+
+ aolib=`find ${top_builddir}/autoopts -type f -name libopts.a`
+ case " ${LDFLAGS} " in
+ *' -lgen '* ) aolib=${aolib}\ -lgen ;;
+ esac
+
+ cd ${top_srcdir}/autoopts/tpl
+ cp *.* ${TMPDIR}/.
+ chmod u+w ${TMPDIR}/*
+
+ cd ${top_builddir}/autoopts/tpl
+ cp *.* ${TMPDIR}/.
+ chmod u+w ${TMPDIR}/*
+
+ cd ${builddir}/testdir
+ ${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}" \
+ ${SHELLX} -x ${top_srcdir}/autoopts/install-hook.sh
+ AUTOGEN_TEMPL_DIRS=${TMPDIR}
+ export AUTOGEN_TEMPL_DIRS
+}
+
+# # # # # # # # # # DEFINITIONS FILE # # # # # # # # #
+go_samples() {
+
+echo "creating ${testname}.def in `pwd`"
+
+cat >> ${testname}.def <<_EOF_
+AutoGen definitions getopt;
+
+prog-name = "test_${testname}";
+prog-title = "Test AutoOpts for ${testname}";
+test-main = 'yes';
+config-header = 'config.h';
+
+settable;
+version = '1.2.3';
+help-value = 'h';
+gnu-usage;
+no-libopts;
+
+copyright = {
+ date = "2003-2012";
+ 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';
+};
+_EOF_
+
+# # # # # # # # # # BASE-1 OUTPUT FILE # # # # # # # # #
+
+echo creating ${testname}1-base.c
+
+cat > ${testname}1-base.c <<\_EndOfSample_
+#include "getopt-test_getopt.h"
+
+#include <sys/types.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#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:
+ */
+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 - Ver. 1.2.3\n\
+USAGE: test_getopt { -<flag> [<val>] }...\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);
+}
+
+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-2012 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 = (char **)(void *)&(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;
+}
+_EndOfSample_
+
+# # # # # # # # # # BASE-2 OUTPUT FILE # # # # # # # # #
+
+echo creating ${testname}2-base.c
+
+cat > ${testname}2-base.c <<\_EndOfSample_
+#include "getopt-test_getopt.h"
+
+#include <sys/types.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <getopt.h>
+#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:
+ */
+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 - Ver. 1.2.3\n\
+USAGE: test_getopt { -<flag> [<val>] | --<name>[{=| }<val>] }...\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);
+}
+
+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-2012 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 = (char **)(void *)&(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;
+}
+_EndOfSample_
+}
+
+# # # # # # # # # # 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}2.def ${testname}.def
+
+ compile_getopt 2
+}
+
+cleanup
+
+## 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..ac7d4a4
--- /dev/null
+++ b/autoopts/test/handler.test
@@ -0,0 +1,254 @@
+#! /bin/sh
+# -*- Mode: Shell-script -*-
+# ----------------------------------------------------------------------
+# handler.test --- test option handling
+# make sure that when it is not specified
+# then option processing consumes all args.
+#
+# Time-stamp: "2012-08-11 08:14:34 bkorb"
+# Author: Bruce Korb <bkorb@gnu.org>
+##
+## This file is part of AutoOpts, a companion to AutoGen.
+## AutoOpts is free software.
+## AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/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 pOptions the AutoOpts option description structure
+ * @param pOptDesc the descriptor for the "help" (usage) option.
+ * @noreturn
+ */
+static void
+doUsageOpt(tOptions * pOptions, tOptDesc * pOptDesc)
+{
+ optionUsage(&handlerOptions, HANDLER_EXIT_SUCCESS);
+ /* NOTREACHED */
+ (void)pOptDesc;
+ (void)pOptions;
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/**
+ * Code to handle the first option.
+ *
+ * @param pOptions the handler options data structure
+ * @param 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 pOptions the handler options data structure
+ * @param 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 azNames[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, azNames, 5);
+ return; /* protect AutoOpts client code from internal callbacks */
+ }
+
+ pOptDesc->optArg.argEnum =
+ optionEnumerationVal(pOptions, pOptDesc, azNames, 5);
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/**
+ * Code to handle the third option.
+ *
+ * @param pOptions the handler options data structure
+ * @param pOptDesc the option descriptor for this option.
+ */
+static void
+doOptThird(tOptions* pOptions, tOptDesc* pOptDesc)
+{
+ /* extracted from handler.def, line 21 */
+ SomeCodeOrOther();
+ (void)pOptDesc;
+ (void)pOptions;
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/**
+ * Code to handle the fourth option.
+ *
+ * @param pOptions the handler options data structure
+ * @param pOptDesc the option descriptor for this option.
+ */
+static void
+doOptFourth(tOptions* pOptions, tOptDesc* pOptDesc)
+{
+
+ static char const * const azNames[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, azNames, 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, azNames, 4);
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/**
+ * Code to handle the sixth option.
+ *
+ * @param pOptions the handler options data structure
+ * @param pOptDesc the option descriptor for this option.
+ */
+static void
+doOptSixth(tOptions* pOptions, tOptDesc* pOptDesc)
+{
+
+ static char const * const azNames[4] = {
+ "alpha", "beta", "gamma", "omega"
+ };
+ /*
+ * This function handles special invalid values for "pOptions"
+ */
+ optionSetMembers(pOptions, pOptDesc, azNames, 4);
+}
+
+/**
+ * The directory containing the data associated with handler.
+ */
+_EOF_
+
+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
+## End:
+
+# end of handler.test
diff --git a/autoopts/test/immediate.test b/autoopts/test/immediate.test
new file mode 100755
index 0000000..c7edbce
--- /dev/null
+++ b/autoopts/test/immediate.test
@@ -0,0 +1,121 @@
+#! /bin/sh
+# -*- Mode: Shell-script -*-
+# ----------------------------------------------------------------------
+# immediate.test --- test immediate option handling
+#
+# Time-stamp: "2012-01-29 13:33:03 bkorb"
+# Author: Bruce Korb <bkorb@gnu.org>
+##
+## This file is part of AutoOpts, a companion to AutoGen.
+## AutoOpts is free software.
+## AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
+#
+# ----------------------------------------------------------------------
+
+. ./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 <stdio.h>\nint invocation_ct = 0;";
+config-header = 'config.h';
+version = '1.0';
+copyright = {
+ date = "1992-2012";
+ 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 , ,;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 [ <option-name>[{=| }<val>] ]...
+ 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..03b8720
--- /dev/null
+++ b/autoopts/test/keyword.test
@@ -0,0 +1,449 @@
+#! /bin/sh
+# -*- Mode: Shell-script -*-
+# ----------------------------------------------------------------------
+# keyword.test --- keyword option processing
+#
+# Time-stamp: "2012-02-28 19:42:00 bkorb"
+# Author: Bruce Korb <bkorb@gnu.org>
+##
+## This file is part of AutoOpts, a companion to AutoGen.
+## AutoOpts is free software.
+## AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/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}.res-help
+clean_help > ${testname}.res-help <<\_EOF_
+test_keyword - Test AutoOpts for keyword
+USAGE: keyword [ -<flag> [<val>] | --<name>[{=| }<val>] ]...
+ 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}.bas-help
+cmp -s ${testname}.*-help || \
+ failure "help output: `diff ${testname}.*-help`"
+
+./${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"
+
+./${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 none + second + third + fourth + ninth + thirteenth
+ _EndIni_
+
+cmp -s ${testname}base.cfg ${testname}res.cfg || \
+ failure "`diff ${testname}base.cfg ${testname}res.cfg`"
+
+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
+ typeset -x -i SETS_FIRST=1 # 0x1
+ typeset -x -i SETS_SECOND=2 # 0x2
+ typeset -x -i SETS_THIRD=4 # 0x4
+ typeset -x -i SETS_FOURTH=8 # 0x8
+ typeset -x -i SETS_FIFTH=16 # 0x10
+ typeset -x -i SETS_SIXTH=32 # 0x20
+ typeset -x -i SETS_SEVENTH=64 # 0x40
+ typeset -x -i SETS_EIGHTH=128 # 0x80
+ typeset -x -i SETS_NINTH=256 # 0x100
+ typeset -x -i SETS_TENTH=512 # 0x200
+ typeset -x -i SETS_ELEVENTH=1024 # 0x400
+ typeset -x -i SETS_TWELFTH=2048 # 0x800
+ typeset -x -i SETS_THIRTEENTH=4096 # 0x1000
+ typeset -x -i SETS_FOURTEENTH=8192 # 0x2000
+ typeset -x -i SETS_FIFTEENTH=16384 # 0x4000
+ typeset -x -i SETS_SIXTEENTH=32768 # 0x8000
+ typeset -x -i SETS_SEVENTEENTH=65536 # 0x10000
+ typeset -x -i SETS_EIGHTEENTH=131072 # 0x20000
+ _EndTst_
+
+cmp -s ${testname}.t1-* || \
+ failure "`diff ${testname}.t1-*`"
+
+${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
+
+cat > ${testname}-base.1 <<\_EOMan_
+test_keyword \- Test AutoOpts for keyword
+.SH SYNOPSIS
+.B test_keyword
+.\" Mixture of short (flag) options and long options
+.RB [ \-\fIflag\fP " [\fIvalue\fP]]... [" \-\-\fIopt\-name\fP " [[=| ]\fIvalue\fP]]..."
+.PP
+All arguments must be options.
+.SH "DESCRIPTION"
+There is no description for this command.
+.SH "OPTIONS"
+.TP
+.BR \-o " \fIstring\fP, " \-\-option "=" \fIstring\fP
+The option option descrip.
+The default \fIstring\fP for this option is:
+.ti +4
+ opt init
+.sp
+This option has not been fully documented.
+.TP
+.BR \-\-trace "=\fIlevel\fP"
+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 \fIlevel\fP for this option is:
+.ti +4
+ nothing
+.sp
+This option has not been fully documented.
+.TP
+.BR \-\-sets "=\fImember\-list\fP"
+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 \fImember\-list\fP for this option is:
+.ti +4
+ second + fourth
+.sp
+This option has not been fully documented.
+.TP
+.BR \-X , " \-\-help"
+Display usage information and exit.
+.TP
+.BR \-! , " \-\-more-help"
+Pass the extended usage information through a pager.
+.TP
+.BR \-> " [\fIrcfile\fP]," " \-\-save-opts" "[=\fIrcfile\fP]"
+Save the option state to \fIrcfile\fP. The default is the \fIlast\fP
+configuration file listed in the \fBOPTION PRESETS\fP section, below.
+.TP
+.BR \-< " \fIrcfile\fP," " \-\-load-opts" "=\fIrcfile\fP," " \-\-no-load-opts"
+Load options from \fIrcfile\fP.
+The \fIno-load-opts\fP form will disable the loading
+of earlier RC/INI files. \fI\-\-no-load-opts\fP is handled early,
+out of order.
+.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
+.BR 0 " (EXIT_SUCCESS)"
+Successful program execution.
+.TP
+.BR 1 " (EXIT_FAILURE)"
+The operation failed or the command syntax was not valid.
+.TP
+.BR 66 " (EX_NOINPUT)"
+A specified configuration file could not be loaded.
+.TP
+.BR 70 " (EX_SOFTWARE)"
+libopts had an internal operational error. Please report
+it to autogen-users@lists.sourceforge.net. Thank you.
+.SH "NOTES"
+This manual page was \fIAutoGen\fP-erated from the \fBtest_keyword\fP
+option definitions.
+_EOMan_
+
+${SED} '1,/^\.SH NAME/d' ${testname}.1 > ${testname}-res.1
+cmp -s ${testname}-base.1 ${testname}-res.1 || \
+ failure "`diff ${testname}-base.1 ${testname}-res.1`"
+
+# # # # # # # # # # 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
+
+cat > ${testname}-base.mdoc <<\_EOMan_
+.Dt TEST_KEYWORD 1 User Commands
+.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 Ar value
+.Op Fl \-option-name Ar value
+.Pp
+All arguments must be options.
+.Pp
+.Sh "DESCRIPTION"
+There is no description for this command.
+.Sh "OPTIONS"
+.Bl -tag
+.It \-o " \fIstring\fP, " \-\-option "=" \fIstring\fP
+The option option descrip.
+The default \fIstring\fP for this option is:
+.ti +4
+ opt init
+.sp
+This option has not been fully documented.
+.It \-\-trace "=\fIlevel\fP"
+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 \fIlevel\fP for this option is:
+.ti +4
+ nothing
+.sp
+This option has not been fully documented.
+.It \-\-sets "=\fImember\-list\fP"
+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 \fImember\-list\fP for this option is:
+.ti +4
+ second + fourth
+.sp
+This option has not been fully documented.
+.It \-X , " \-\-help"
+Display usage information and exit.
+.It \-! , " \-\-more-help"
+Pass the extended usage information through a pager.
+.It \-> " [\fIrcfile\fP]," " \-\-save-opts" "[=\fIrcfile\fP]"
+Save the option state to \fIrcfile\fP. The default is the \fIlast\fP
+configuration file listed in the \fBOPTION PRESETS\fP section, below.
+.It \-< " \fIrcfile\fP," " \-\-load-opts" "=\fIrcfile\fP," " \-\-no-load-opts"
+Load options from \fIrcfile\fP.
+The \fIno-load-opts\fP form will disable the loading
+of earlier 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.
+_EOMan_
+
+${SED} '/DO NOT EDIT/,/and the template file/d;/^\.Os /d;/^\.Dd /d' \
+ ${testname}.mdoc > ${testname}-res.mdoc
+cmp -s ${testname}-base.mdoc ${testname}-res.mdoc || \
+ failure "`diff ${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 <stdio.h>';
+ 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
+
+## 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..f463e3e
--- /dev/null
+++ b/autoopts/test/library.test
@@ -0,0 +1,170 @@
+#! /bin/sh
+# -*- Mode: Shell-script -*-
+# ----------------------------------------------------------------------
+# library.test --- test library options
+#
+# Time-stamp: "2013-03-10 07:14:58 bkorb"
+# Author: Bruce Korb <bkorb@gnu.org>
+##
+## This file is part of AutoOpts, a companion to AutoGen.
+## AutoOpts is free software.
+## AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/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 <autoopts\/options.h>/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 <stdlib.h>
+ #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 <stdio.h>
+ #include <stdlib.h>
+ #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 [ -<flag> ]...
+ 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..0c4b124
--- /dev/null
+++ b/autoopts/test/main.test
@@ -0,0 +1,127 @@
+#! /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.
+#
+# Time-stamp: "2011-08-07 17:33:19 bkorb"
+# Author: Bruce Korb <bkorb@gnu.org>
+##
+## This file is part of AutoOpts, a companion to AutoGen.
+## AutoOpts is free software.
+## AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/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 = '[ <argument> ... ]';
+ main = {
+ handler-proc = fumble;
+ fumble-code = 'printf( "%s\n", pz_entry );';
+ main-type = for-each;
+ };
+ _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 [ -<flag> [<val>] ]... [ <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
+
+
+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.
+'stdin' may not be a terminal (tty).
+_EOF_
+
+cmp -s ${testname}.h*lp || \
+ failure "`diff ${basehlp} ${testname}.help`"
+
+# # # # # # # # # # TEST OPERATION # # # # # # # # # #
+
+./${testname} > ${testname}.out < ${testname}.hlp
+
+clean_help > ${testname}.base <<\_EOF_
+test_main - Test AutoOpts for main
+USAGE: main [ -<flag> [<val>] ]... [ <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
+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.
+'stdin' may not be a terminal (tty).
+_EOF_
+
+cmp -s ${testname}.base ${testname}.out || \
+ failure "`diff ${testname}.base ${testname}.out`"
+
+./${testname} -s 5 the quick 'brown fox' > ${testname}.out2
+
+cat > ${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..34c9a55
--- /dev/null
+++ b/autoopts/test/nested.test
@@ -0,0 +1,266 @@
+#! /bin/sh
+# -*- Mode: Shell-script -*-
+# ----------------------------------------------------------------------
+# nested.test --- test nested option values
+#
+# Time-stamp: "2012-03-31 13:10:48 bkorb"
+# Author: Bruce Korb <bkorb@gnu.org>
+##
+## This file is part of AutoOpts, a companion to AutoGen.
+## AutoOpts is free software.
+## AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/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 <stdio.h>
+
+ 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} [ -<flag> [<val>] ]...
+ 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, <bar type=integer>1234</bar> able' | \
+${SED} '/ nested:/s/ 0x.*/ 0xXXXXXXXX/' > ${testname}-res1.out || \
+ failure "FAILED: \
+./${testname} -s 'stumble, foo, <bar type=integer>1234</bar> baz'"
+
+cmp -s ${testname}-res1.* || \
+ failure "`diff ${testname}-res1.*`"
+
+# # # # # # # # # # DOUBLE ARG TEST # # # # # # # # #
+
+arg1="stumble, <foo>foo${ht}lish</foo>, <bar type=integer>1234</bar>, able"
+arg2='foo, <bar type=integer>4321</bar> <gr type=nested>one, two=2, three</gr>'
+(./${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***
+ #
+ <struct type=nested>
+ <able/>
+ <bar type=integer>0x4D2</bar>
+ <foo>foo&#x09;lish</foo>
+ <stumble/>
+ </struct>
+ <struct type=nested>
+ <bar type=integer>0x10E1</bar>
+ <foo/>
+ <gr type=nested>
+ <one/>
+ <three/>
+ <two>2</two>
+ </gr>
+ </struct>
+ _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..1455515
--- /dev/null
+++ b/autoopts/test/nls.test
@@ -0,0 +1,156 @@
+#! /bin/sh
+# -*- Mode: Shell-script -*-
+# ----------------------------------------------------------------------
+# nls.test --- test NLS, sort-of
+#
+# Time-stamp: "2011-08-07 17:36:29 bkorb"
+# Author: Bruce Korb <bkorb@gnu.org>
+##
+## This file is part of AutoOpts, a companion to AutoGen.
+## AutoOpts is free software.
+## AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
+#
+# ----------------------------------------------------------------------
+
+. ./defs
+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]
+ cat >> ${testname}.c <<'_EOF_'
+#include <ctype.h>
+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 (void *)pzS;
+ *--pzD = '\0';
+ while (*pzS == ' ') pzS++;
+ for (;;) {
+ char ch = *(pzS++);
+ if (ch == '\0')
+ break;
+ *(--pzD) = ch;
+ ct++;
+ if (ch != '\n')
+ continue;
+ found_nl = 1;
+ while (*pzS == ' ') 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 "--pleh"
+ 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 [ -<flag> [<val>] | --<name>[{=| }<val>] ]...
+noitpircseD emaN-noitpO grA glF
+ -o rtS noitpo pircsed noitpo noitpo ehT
+ -s muN dnoces pircsed noitpo dnoces ehT
+ -? on pleh tixe dna noitamrofni egasu dednetxe yalpsiD
+ -! on pleh-erom 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 [ -<flag> [<val>] | --<name>[{=| }<val>] ]...
+ 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_'
+.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 ?-
+pircsed dnoces ehT dnoces muN s-
+pircsed noitpo ehT noitpo rtS o-
+noitpircseD emaN-noitpO grA glF
+...] ]>lav<} |={[>eman<-- | ]>lav<[ >galf<- [ sln :EGASU
+sln rof stpOotuA tseT - sln_tset
+_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..18e005d
--- /dev/null
+++ b/autoopts/test/rc.test
@@ -0,0 +1,240 @@
+#! /bin/sh
+# -*- Mode: Shell-script -*-
+
+# rc.test --- test loading and saving of rc files
+#
+# Time-stamp: "2012-05-13 13:21:58 bkorb"
+# Author: Bruce Korb <bkorb@gnu.org>
+##
+## This file is part of AutoOpts, a companion to AutoGen.
+## AutoOpts is free software.
+## AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
+
+. ./defs
+
+AUTOOPTS_TRACE=every
+AUTOOPTS_TRACE_OUT=">>`pwd`/${testname}-ag-trace.txt"
+export AUTOOPTS_TRACE AUTOOPTS_TRACE_OUT
+
+# # # # # # # # # # DEFINITIONS FILE # # # # # # # # #
+
+: "creating ${testname}.def in `pwd`"
+
+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 [ -<flag> [<val>] | --<name>[{=| }<val>] ]... 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
+<!-- This is a comment
+ and it should have no effect -->
+[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_
+ <?program test-mumble>
+ second fourth
+ <!-- This is a comment
+ and it should have no effect -->
+ <?program test-${testname}>
+ <second cooked>
+ fifth
+ </second>
+ # this is another comment
+ #
+ <?program test-stumble>
+ second : sixth
+ _EOF_
+) > ../${testname}.rc/${testname}.file
+
+../${testname} -t yyy MUMBLE > ${testname}.cmds
+
+cmp ${testname}.cmds ${testname}.test || {
+ df="USING <?program>: `diff -c ${testname}.test ${testname}.cmds`"
+ cd ..
+ failure "${df}"
+}
+
+# # # # # # # # # # THIRD TEST OUTPUT FILE # # # # # # # # #
+
+cd ${testsubdir}
+
+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' \
+ -e '/ save-opts *Save /d' \
+ ${testname}-base1.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..1a47b2f
--- /dev/null
+++ b/autoopts/test/shell.test
@@ -0,0 +1,457 @@
+#! /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.
+#
+# Time-stamp: "2012-08-11 08:51:08 bkorb"
+# Author: Bruce Korb <bkorb@gnu.org>
+##
+## This file is part of AutoOpts, a companion to AutoGen.
+## AutoOpts is free software.
+## AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/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"
+
+echo ${AG_L} ${testname}.def
+${AG_L} ${testname}.def || \
+ failure AutoGen could not process
+
+compile "-?"
+
+# # # # # # # # # # HELP OUTPUT FILE # # # # # # # # #
+
+echo creating ${testname}.hlp
+clean_help > ${testname}.hlp <<'_EOF_'
+test_shell - Test AutoOpts for shell
+USAGE: shell [ -<flag> [<val>] | --<name>[{=| }<val>] ]... \
+ reg-arg [ ... ]
+ Flg Arg Option-Name Description
+ -o Str option The option option descrip
+ -s no second The second option 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_
+
+cmp -s ${testname}.h*lp || \
+ failure "`diff ${testname}.hlp ${testname}.help`"
+
+./${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
+
+# # # # # # # # # # 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
+
+cmp -s ${testname}.test ${testname}.out || \
+ failure "`diff ${testname}.out ${testname}.test`"
+
+${SED} '/test-main/s/yes/optionParseShell/' ${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 [ -<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.
+
+= = = = = = = =
+
+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 [ -<flag> [<val>] | --<name>[{=| }<val>] ]... \
+ reg-arg [ ... ]
+ Flg Arg Option-Name Description
+ -o Str option The option option descrip
+ -s no second The second option 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_
+
+files=${testname}.hlp\ ${testname}.help
+cmp -s ${files} || \
+ failure "script generator help output mismatch: `diff -c ${files}`"
+
+# # # # # # # # # # 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 [ -<flag> [<val>] | --<name>[{=| }<val>] ]... \
+ reg-arg [ ... ]
+ Flg Arg Option-Name Description
+ -o Str option The option option descrip
+ -s no second The second option 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.'
+
+TEST_SHELL_USAGE_TEXT='test_shell - Test AutoOpts for shell
+USAGE: test_shell [ -<flag> [<val>] | --<name>[{=| }<val>] ]... \
+ reg-arg [ ... ]
+ Flg Arg Option-Name Description
+ -o Str option The option option descrip
+ -s no second The second option 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.'
+
+
+TEST_SHELL_OPTION=${TEST_SHELL_OPTION}
+TEST_SHELL_OPTION_set=false
+export TEST_SHELL_OPTION
+
+TEST_SHELL_SECOND=${TEST_SHELL_SECOND}
+TEST_SHELL_SECOND_set=false
+export TEST_SHELL_SECOND
+
+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 >&2
+ echo "$TEST_SHELL_USAGE_TEXT"
+ exit 1 ; fi
+ TEST_SHELL_OPTION_set=true
+ OPT_NAME='OPTION'
+ OPT_ARG_NEEDED=YES
+ ;;
+
+ 'se' | \
+ 'sec' | \
+ 'seco' | \
+ 'secon' | \
+ 'second' )
+ if [ -n "${TEST_SHELL_SECOND}" ] && ${TEST_SHELL_SECOND_set} ; then
+ echo Error: duplicate SECOND option >&2
+ echo "$TEST_SHELL_USAGE_TEXT"
+ exit 1 ; fi
+ TEST_SHELL_SECOND_set=true
+ 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"
+ 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 >&2
+ echo "$TEST_SHELL_USAGE_TEXT"
+ exit 1
+ fi
+ 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 >&2
+ echo "$TEST_SHELL_USAGE_TEXT"
+ exit 1 ; fi
+ TEST_SHELL_OPTION_set=true
+ OPT_NAME='OPTION'
+ OPT_ARG_NEEDED=YES
+ ;;
+
+ 's' )
+ if [ -n "${TEST_SHELL_SECOND}" ] && ${TEST_SHELL_SECOND_set} ; then
+ echo Error: duplicate SECOND option >&2
+ echo "$TEST_SHELL_USAGE_TEXT"
+ exit 1 ; fi
+ TEST_SHELL_SECOND_set=true
+ 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"
+ 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 >&2
+ echo "$TEST_SHELL_USAGE_TEXT"
+ exit 1
+ fi
+ 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
+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 '^TEST_SHELL_'
+_EOF_
+exec 3>&-
+
+# # # # # # # # # # SCRIPT OUTPUT TESTING # # # # # # # # #
+
+rm -f ${testname}.sh
+./${testname} -o ${testname}.sh
+
+sedcmd='2,/From the.*option def/d'
+${FGREP} 'Packaged by ' ${testname}.sh >/dev/null && {
+ sedcmd=${sedcmd}${nl}'/^Packaged by /d
+ /^Report .* bugs to /d
+ /and the flag character\.$/s/$/'"'/"
+}
+
+${SED} "$sedcmd" ${testname}.sh > ${testname}.shx
+cmp -s ${testname}.sh[tx] || \
+ failure "`diff ${testname}.sh[tx]`"
+
+# # # # # # # # # # 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=true
+_EOF_
+
+cmp -s ${testname}.out ${testname}.test || \
+ failure "`diff ${testname}.out ${testname}.test`"
+
+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..e89745c
--- /dev/null
+++ b/autoopts/test/stdopts.def
@@ -0,0 +1,109 @@
+#! /bin/sh
+
+## Time-stamp: "2012-05-13 12:44:49 bkorb"
+##
+## This file is part of AutoOpts, a companion to AutoGen.
+## AutoOpts is free software.
+## AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/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..21ba56c
--- /dev/null
+++ b/autoopts/test/stdopts.test
@@ -0,0 +1,161 @@
+#! /bin/sh
+# -*- Mode: Shell-script -*-
+# ----------------------------------------------------------------------
+# stdopts.test --- test standard options
+#
+# Time-stamp: "2013-03-10 07:14:45 bkorb"
+# Author: Bruce Korb <bkorb@gnu.org>
+##
+## This file is part of AutoOpts, a companion to AutoGen.
+## AutoOpts is free software.
+## AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/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';
+ test-main;
+ 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 [ -<flag> [<val>] | --<name>[{=| }<val>] ]...
+
+ 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" ${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 [ -<flag> [<val>] | --<name>[{=| }<val>] ]...
+ 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..855ae88
--- /dev/null
+++ b/autoopts/test/time.test
@@ -0,0 +1,101 @@
+#! /bin/sh
+# -*- Mode: Shell-script -*-
+# ----------------------------------------------------------------------
+# time.test --- test time duration argument
+#
+# Time-stamp: "2011-08-07 17:34:14 bkorb"
+# Author: Bruce Korb <bkorb@gnu.org>
+##
+## This file is part of AutoOpts, a companion to AutoGen.
+## AutoOpts is free software.
+## AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/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 [ -<flag> [<val>] ]...
+ 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..33a21a5
--- /dev/null
+++ b/autoopts/test/usage.test
@@ -0,0 +1,656 @@
+#! /bin/sh
+# -*- Mode: Shell-script -*-
+# ----------------------------------------------------------------------
+# usage.test --- test all the ways usage text can be printed.
+#
+## Time-stamp: "2011-08-07 17:20:27 bkorb"
+# Author: Bruce Korb <bkorb@gnu.org>
+##
+## This file is part of AutoOpts, a companion to AutoGen.
+## AutoOpts is free software.
+## AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
+#
+# ----------------------------------------------------------------------
+
+${VERBOSE} && kill_delay=10 || kill_delay=5
+. ./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 { -<flag> [<val>] | --<name>[{=| }<val>] }... \
+ 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 { -<flag> | --<name> }... 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 [ -<flag> [<val>] | --<name>[{=| }<val>] ]... \
+ 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 [ -<flag> | --<name> ]... 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 { --<name>[{=| }<val>] }... 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 { --<name> }... 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 [ --<name>[{=| }<val>] ]... 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 [ --<name> ]... 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 { -<flag> [<val>] | --<name>[{=| }<val>] }... \
+ 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 { -<flag> | --<name> }... 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 [ -<flag> [<val>] | --<name>[{=| }<val>] ]... \
+ 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 [ -<flag> | --<name> ]... 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 { --<name>[{=| }<val>] }... 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 { --<name> }... 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 [ --<name>[{=| }<val>] ]... 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 [ --<name> ]... 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 { -<flag> [<val>] }... 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 { -<flag> }... 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 [ -<flag> [<val>] ]... 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 [ -<flag> ]... 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 { <option-name>[{=| }<val>] }...
+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 { <option-name> }...
+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 [ <option-name>[{=| }<val>] ]...
+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 [ <option-name> ]...
+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 { -<flag> [<val>] }... 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 { -<flag> }... 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 [ -<flag> [<val>] ]... 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 [ -<flag> ]... 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 { <option-name>[{=| }<val>] }...
+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 { <option-name> }...
+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 [ <option-name>[{=| }<val>] ]...
+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 [ <option-name> ]...
+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..a9d0ac8
--- /dev/null
+++ b/autoopts/test/vendor.test
@@ -0,0 +1,174 @@
+#! /bin/sh
+# -*- Mode: shell-script -*-
+# ----------------------------------------------------------------------
+# vendor.test --- test the vendor-opt option
+#
+# Time-stamp: "2012-03-31 13:11:19 bkorb"
+# Author: Bruce Korb <bkorb@gnu.org>
+##
+## This file is part of AutoOpts, a companion to AutoGen.
+## AutoOpts is free software.
+## AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/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} [ -<flag> [<val>] ]... [ <def-file> ]
+The following options select definitions, templates and scheme functions
+to use:
+ -L str Template search directory list
+ - may appear multiple times
+ -T str Override template file
+ - may not be preset
+ -l str Library template file
+ - may appear multiple times
+ -S str Scheme code file to load
+ -F str Load scheme function library
+ -m Do not use in-mem streams
+The following options modify how output is handled:
+ -b str Base name for output file(s)
+ - may not be preset
+The following options are often useful while debugging new templates:
+ -t num Time limit for server shell
+ - 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 Omit the file with this suffix
+ - prohibits these options:
+ 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
+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 Definitions input 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
+${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 `
+ echo ${testname} | tr 'a-z' 'A-Z'`_*
+
+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_
+
+cmp -s ${testname}.h*lp || \
+ failure "`diff ${testname}.hlp ${testname}.help`"
+
+cleanup
diff --git a/autoopts/test/vers.test b/autoopts/test/vers.test
new file mode 100755
index 0000000..55fb435
--- /dev/null
+++ b/autoopts/test/vers.test
@@ -0,0 +1,107 @@
+#! /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.
+#
+# Time-stamp: "2011-08-07 17:35:55 bkorb"
+# Author: Bruce Korb <bkorb@gnu.org>
+##
+## This file is part of AutoOpts, a companion to AutoGen.
+## AutoOpts is free software.
+## AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/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 [ -<flag> ]...
+ 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 [ -<flag> ]...
+ 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..4a7aa1a
--- /dev/null
+++ b/autoopts/text_mmap.c
@@ -0,0 +1,370 @@
+/**
+ * @file text_mmap.c
+ *
+ * Map a text file, ensuring the text always has an ending NUL byte.
+ *
+ * Time-stamp: "2012-01-29 09:40:21 bkorb"
+ *
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+ *
+ * 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+ * 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+ * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/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 ((void*)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;
+ fprintf(stderr, zFSErrReadFile,
+ errno, strerror(errno), pzFile);
+ free(mapinfo->txt_data);
+ return;
+ }
+
+ pz += rdct;
+ sz -= rdct;
+ }
+
+ *pz = NUL;
+ }
+
+ mapinfo->txt_errno = 0;
+
+#else /* HAVE mmap */
+ size_t const pgsz = 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;
+
+ /*
+ * Make sure we can stat the regular file. Save the file size.
+ */
+ {
+ struct stat sb;
+ if (stat(fname, &sb) != 0) {
+ mapinfo->txt_errno = errno;
+ return;
+ }
+
+ if (! S_ISREG(sb.st_mode)) {
+ mapinfo->txt_errno = errno = EINVAL;
+ return;
+ }
+
+ mapinfo->txt_size = sb.st_size;
+ }
+
+ /*
+ * 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 = 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 == 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(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 <mylib.h>
+ * 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..e8e4f05
--- /dev/null
+++ b/autoopts/time.c
@@ -0,0 +1,143 @@
+
+/**
+ * \file time.c
+ *
+ * Time-stamp: "2012-08-11 08:34:17 bkorb"
+ *
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+ *
+ * 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+ * 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+ * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
+ */
+
+/*=export_func optionTimeVal
+ * private:
+ *
+ * what: process an option with a time duration.
+ * arg: + tOptions* + pOpts + program options descriptor +
+ * arg: + tOptDesc* + pOptDesc + the descriptor for this arg +
+ *
+ * doc:
+ * Decipher a time duration value.
+=*/
+void
+optionTimeVal(tOptions * pOpts, tOptDesc * pOD)
+{
+ time_t val;
+
+ if (pOpts <= OPTPROC_EMIT_LIMIT)
+ return;
+
+ if ((pOD->fOptState & OPTST_RESET) != 0)
+ return;
+
+ val = parse_duration(pOD->optArg.argString);
+ if (val == BAD_TIME) {
+ fprintf(stderr, zNotDuration, pOpts->pzProgName, pOD->optArg.argString);
+ if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0)
+ (*(pOpts->pUsageProc))(pOpts, EXIT_FAILURE);
+ }
+
+ if (pOD->fOptState & OPTST_ALLOC_ARG) {
+ AGFREE(pOD->optArg.argString);
+ pOD->fOptState &= ~OPTST_ALLOC_ARG;
+ }
+
+ pOD->optArg.argInt = (unsigned long)val;
+}
+
+/*=export_func optionTimeDate
+ * private:
+ *
+ * what: process an option with a time and date.
+ * arg: + tOptions* + pOpts + program options descriptor +
+ * arg: + tOptDesc* + pOptDesc + the descriptor for this arg +
+ *
+ * doc:
+ * Decipher a time and date value.
+=*/
+void
+optionTimeDate(tOptions * pOpts, tOptDesc * pOD)
+{
+#if defined(HAVE_GETDATE_R) && defined(HAVE_PUTENV)
+ if (pOpts <= OPTPROC_EMIT_LIMIT)
+ return;
+
+ if ((! HAS_pzPkgDataDir(pOpts)) || (pOpts->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";
+ envptr = AGALOC(sizeof(fmt) + strlen(pOpts->pzPkgDataDir), fmt);
+ sprintf(envptr, fmt, pOpts->pzPkgDataDir);
+
+ 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(pOD->optArg.argString, &stm) != 0) {
+ fprintf(stderr, zNotDate, pOpts->pzProgName,
+ pOD->optArg.argString);
+ if ((pOpts->fOptSet & OPTPROC_ERRSTOP) != 0)
+ (*(pOpts->pUsageProc))(pOpts, EXIT_FAILURE);
+ return;
+ }
+
+ tm = mktime(&stm);
+
+ if (pOD->fOptState & OPTST_ALLOC_ARG) {
+ AGFREE(pOD->optArg.argString);
+ pOD->fOptState &= ~OPTST_ALLOC_ARG;
+ }
+
+ pOD->optArg.argInt = tm;
+ }
+ return;
+
+default_action:
+
+#endif
+ optionTimeVal(pOpts, pOD);
+ if (pOD->optArg.argInt != BAD_TIME)
+ pOD->optArg.argInt += (unsigned 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..9563713
--- /dev/null
+++ b/autoopts/tokenize.c
@@ -0,0 +1,333 @@
+/*
+ * This file defines the string_tokenize interface
+ * Time-stamp: "2012-03-04 13:23:50 bkorb"
+ *
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+ *
+ * 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+ * 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+ * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
+ */
+
+#include <errno.h>
+#include <stdlib.h>
+
+#define cc_t const unsigned char
+#define ch_t unsigned char
+
+/* = = = START-STATIC-FORWARD = = = */
+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);
+/* = = = END-STATIC-FORWARD = = = */
+
+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) + (pz - str)
+ + (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 <stdlib.h>
+ * 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 <stdio.h>
+#include <string.h>
+
+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/aginfo.tpl b/autoopts/tpl/aginfo.tpl
new file mode 100644
index 0000000..01e4e2f
--- /dev/null
+++ b/autoopts/tpl/aginfo.tpl
@@ -0,0 +1,10 @@
+[= AutoGen5 template
+
+texi
+
+=]
+[= `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..6c79e22
--- /dev/null
+++ b/autoopts/tpl/aginfo3.tpl
@@ -0,0 +1,128 @@
+{+ AutoGen5 template -*- nroff -*-
+
+texi
+
+## ---------------------------------------------------------------------
+## aginfo3.tpl -- Template for function texi doc
+##
+## Time-stamp: "2011-02-01 06:38:27 bkorb"
+## Author: Bruce Korb <bkorb@gnu.org>
+##
+## This file is part of AutoOpts, a companion to AutoGen.
+## AutoOpts is free software.
+## AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f 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..1ba4908
--- /dev/null
+++ b/autoopts/tpl/agman-cmd.tpl
@@ -0,0 +1,123 @@
+[+: -*- Mode: nroff -*-
+
+ AutoGen5 template man
+
+## agman-cmd.tpl -- Template for command line man pages
+##
+## Time-stamp: "2011-11-18 07:48:17 bkorb"
+##
+## This file is part of AutoOpts, a companion to AutoGen.
+## AutoOpts is free software.
+## Copyright (c) 1992-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f 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.
+#
+:+][+:
+
+(define head-line (lambda()
+ (sprintf ".TH %s %s \"%s\" \"%s\" \"%s\"\n.\\\"\n"
+ (get "prog-name") man-sect
+ (shell "date '+%d %b %Y'") package-text section-name) ))
+
+(define man-page #t)
+
+:+][+:
+
+INCLUDE "cmd-doc.tlib"
+
+:+]
+.\"
+.SH NAME
+[+: prog-name :+] \- [+: prog-title :+]
+[+:
+
+(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 [+: prog-name :+][+:
+
+ IF (. use-flags) :+][+:
+ IF (exist? "long-opts") :+]
+.\" Mixture of short (flag) options and long options
+.RB [ \-\fIflag\fP " [\fIvalue\fP]]... [" \-\-\fIopt\-name\fP[+:#
+:+] " [[=| ]\fIvalue\fP]]..."[+:
+
+ ELSE no long options: :+]
+.\" Short (flag) options only
+.RB [ \-\fIflag\fP " [\fIvalue\fP]]..."[+:
+ ENDIF
+ :+][+:
+ ELIF (exist? "long-opts")
+ :+]
+.\" Long options only
+.RB [ \-\-\fIopt\-name\fP [ = "| ] \fIvalue\fP]]..."[+:
+
+ ELIF (not (exist? "argument")) :+]
+.RI [ opt\-name "[\fB=\fP" 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? "explain")
+ (string-append "\n.PP\n"
+ (join "\n.PP\n" (stack "explain"))) ) :+][+:
+
+(out-pop) :+][+:
+
+ENDDEF mk-synopsis
+
+agman-cmd.tpl ends here :+]
diff --git a/autoopts/tpl/agman.tlib b/autoopts/tpl/agman.tlib
new file mode 100644
index 0000000..1a0a322
--- /dev/null
+++ b/autoopts/tpl/agman.tlib
@@ -0,0 +1,81 @@
+[+: AutoGen5 template -*- shell-script -*-
+
+null
+
+:+][+:
+
+## agman-lib.tpl -- Template for command line man pages
+##
+## Time-stamp: "2010-07-10 14:28:52 bkorb"
+## Author: Jim Van Zandt <jrv@vanzandt.mv.com>
+##
+## This file is part of AutoOpts, a companion to AutoGen.
+## AutoOpts is free software.
+## AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f 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
+
+:+][+:
+
+(out-push-new)
+
+\:+]
+sed \
+ -e 's;@code{\([^}]*\)};\\fB\1\\fP;g' \
+ -e 's;@var{\([^}]*\)};\\fB\1\\fP;g' \
+ -e 's;@samp{\([^}]*\)};\\fB\1\\fP;g' \
+ -e 's;@i{\([^}]*\)};\\fI\1\\fP;g' \
+ -e 's;@file{\([^}]*\)};\\fI\1\\fP;g' \
+ -e 's;@emph{\([^}]*\)};\\fI\1\\fP;g' \
+ -e 's;@strong{\([^}]*\)};\\fB\1\\fP;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:~=_ -]*\)\*/\\fB\1\\fP/g' \
+ -e 's/``\([a-zA-Z0-9:~+=_ -]*\)'"''"'/\\(lq\1\\(rq/g' \
+ -e "s/^'/\\'/" \
+ -e 's/^@\*/.br/' \
+ -e 's/ -/ \\-/g;s/^\.in \\-/.in -/' <<'_End_Of_Man_'
+[+:
+
+DEFINE emit-man-text :+]
+_End_Of_Man_[+:
+
+(shell (out-pop #t) ) :+][+:
+
+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..95e2a9c
--- /dev/null
+++ b/autoopts/tpl/agman1.tpl
@@ -0,0 +1,10 @@
+[+: -*- Mode: nroff -*-
+
+AutoGen5 template man=%s.1
+
+:+]
+[+: `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..6837c00
--- /dev/null
+++ b/autoopts/tpl/agman3.tpl
@@ -0,0 +1,142 @@
+{+ AutoGen5 template -*- nroff -*-
+
+null
+
+## agman3.tpl -- Template for command line man pages
+##
+## Time-stamp: "2011-02-24 10:39:17 bkorb"
+## Author: Bruce Korb <bkorb@gnu.org>
+##
+## This file is part of AutoOpts, a companion to AutoGen.
+## AutoOpts is free software.
+## AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f 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 {+ `date +%Y-%m-%d` +} "" "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..be8af95
--- /dev/null
+++ b/autoopts/tpl/agmdoc-cmd.tpl
@@ -0,0 +1,115 @@
+[+: -*- Mode: nroff -*-
+
+ AutoGen5 template mdoc
+
+## agman-cmd.tpl -- Template for command line mdoc pages
+##
+## Time-stamp: "2011-11-18 07:48:29 bkorb"
+##
+## This file is part of AutoOpts, a companion to AutoGen.
+## AutoOpts is free software.
+## AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f 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.
+#
+:+][+:
+
+(define head-line (lambda() (string-append
+ ".Dd " (shell "date '+%B %e %Y' | sed 's/ */ /g'")
+ "\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
+.Nm[+:
+
+ IF (. use-flags) :+][+:
+ IF (exist? "long-opts") :+]
+.\" Mixture of short (flag) options and long options
+.Op Fl flags
+.Op Fl flag Ar value
+.Op Fl \-option-name Ar value
+[+: ELSE no long options: :+]
+.Op Fl flags
+.Op Fl flag 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 :+]
+.Pp
+[+:
+
+FOR explain "\n.Pp\n" :+][+:
+ explain :+][+:
+ENDFOR :+][+:
+
+(out-pop) :+][+:
+
+ENDDEF mk-synopsis
+
+agmdoc-cmd.tpl ends here :+]
diff --git a/autoopts/tpl/agpl.lic b/autoopts/tpl/agpl.lic
new file mode 100644
index 0000000..99661e4
--- /dev/null
+++ b/autoopts/tpl/agpl.lic
@@ -0,0 +1,19 @@
+<PFX>Copyright (C) <years> <owner>, all rights reserved.
+<PFX>This is free software. It is licensed for use, modification and
+<PFX>redistribution under the terms of the
+<PFX>GNU Affero GPL, version 3 or later <http://gnu.org/licenses/gpl.html>
+
+<PFX><program> is free software: you can redistribute it and/or modify it
+<PFX>under the terms of the GNU General Public License as published by the
+<PFX>Free Software Foundation, either version 3 of the License, or
+<PFX>(at your option) any later version.
+<PFX>
+<PFX><program> is distributed in the hope that it will be useful, but
+<PFX>WITHOUT ANY WARRANTY; without even the implied warranty of
+<PFX>MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+<PFX>See the GNU Affero General Public License for more details.
+<PFX>
+<PFX>You should have received a copy of the GNU Affero General Public License
+<PFX>along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+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..75330a0
--- /dev/null
+++ b/autoopts/tpl/agtexi-cmd.tpl
@@ -0,0 +1,894 @@
+[= AutoGen5 template -*- Mode: texinfo -*-
+
+texi
+
+# Documentation template
+#
+# Time-stamp: "2012-08-11 08:33:08 bkorb"
+# Author: Bruce Korb <bkorb@gnu.org>
+#
+# This file is part of AutoOpts, a companion to AutoGen.
+# AutoOpts is free software.
+# AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+#
+# 43b91e8ca915626ed3818ffb1b71248b COPYING.gplv3
+# 06a1a2e4760c90ea5e1dad8dfaac4d39 COPYING.lgplv3
+# 66a5cedaf62c4b2637025f049f9b826f COPYING.mbsd
+
+=][=
+
+INVOKE initialization =][=
+
+(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)
+(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"))
+ (convert-divert) =][=
+ 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) =][=
+
+INVOKE emit-usage-opt =][=
+
+;; FOR all options, ...
+;;
+(define opt-name "")
+(define extra-ct 0)
+(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 =][=
+
+ (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 (exist? "homerc"))
+ (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")
+(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 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 [= 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 an [= (if (exist? "arg-optional") "optional " "")
+ =]argument [= arg-type =][=
+(if (exist? "arg-name") (string-append " @file{"
+ (string-substitute (get "arg-name") "@" "@@") "}"))
+ =].[=
+ ENDIF =][=
+
+ (set! extra-ct 0)
+ (out-push-new) =][=
+
+ IF (exist? "min") =]@item
+is required to appear on the command line.
+[= (set! extra-ct (+ extra-ct 1)) =][=
+ ENDIF=][=
+
+ IF (exist? "max") =]@item
+may appear [=
+ IF % max (== "%s" "NOLIMIT")
+ =]an unlimited number of times[=
+ ELSE
+ =]up to [=max=] times[=
+ ENDIF=].
+[= (set! extra-ct (+ extra-ct 1)) =][=
+ ENDIF=][=
+
+ IF (exist? "enabled") =]@item
+is enabled by default.
+[= (set! extra-ct (+ extra-ct 1)) =][=
+ ENDIF=][=
+
+ IF (exist? "ifdef") =]@item
+must be compiled in by defining @code{[=(get "ifdef")
+ =]} during the compilation.
+[= (set! extra-ct (+ extra-ct 1)) =][=
+ ENDIF =][=
+
+ IF (exist? "ifndef") =]@item
+must be compiled in by @strong{un}-defining @code{[=(get "ifndef")
+ =]} during the compilation.
+[= (set! extra-ct (+ extra-ct 1)) =][=
+ ENDIF=][=
+
+ IF (exist? "no_preset") =]@item
+may not be preset with environment variables or configuration (rc/ini) files.
+[= (set! extra-ct (+ extra-ct 1)) =][=
+ ENDIF=][=
+
+ IF (exist? "equivalence") =]@item
+is a member of the [=equivalence=] class of options.
+[= (set! extra-ct (+ extra-ct 1)) =][=
+ ENDIF=][=
+
+ IF (exist? "flags_must") =]@item
+must appear in combination with the following options:
+[= FOR flags_must ", " =][=flags_must=][=
+ ENDFOR=].
+[= (set! extra-ct (+ extra-ct 1)) =][=
+ ENDIF=][=
+
+ IF (exist? "flags_cant") =]@item
+must not appear in combination with any of the following options:
+[= FOR flags_cant ", " =][=flags_cant=][=
+ ENDFOR=].
+[= (set! extra-ct (+ extra-ct 1)) =][=
+ ENDIF=][=
+
+ IF (~* (get "arg-type") "key|set") =]@item
+This option takes a keyword as its argument[=
+
+ CASE arg-type =][=
+ =* key =][= (set! extra-ct (+ extra-ct 1)) =].
+The argument sets an enumeration value that can be tested by comparing[=
+
+ =* set =][= (set! extra-ct (+ extra-ct 1)) =] 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 (> extra-ct 0) =][=
+ (set! extra-text (out-pop #t)) =]
+
+@noindent
+This option has some usage constraints. It:
+@itemize @bullet
+[=(. extra-text)
+=]@end itemize
+[= ELSE =][=
+ (out-pop) =][=
+ ENDIF =][=
+
+?% doc "\n%s" "\nThis option has no @samp{doc} documentation." =][=
+ IF (exist? "deprecated") =]
+
+@strong{NOTE: 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 \=]
+[=
+ (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 =][=
+ (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 =]
+
+@noindent
+@code{libopts} will search in [=
+
+ IF (define rc-count (count "homerc"))
+ (define cfg-file-name "")
+ (> rc-count 1) =][=
+
+ INVOKE emit-multiple-rc =][=
+
+ ELSE =][=
+ 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
+<?program [= prog-name =]>
+@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
+<option-name>
+ <sub-opt>...&lt;...&gt;...</sub-opt>
+</option-name>
+@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)=]_<OPTION_NAME>}. @code{<OPTION_NAME>} 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 infomation 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 (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.
+[=
+ ENDIF disable-save =][=
+
+ IF (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=${AGexe%/autogen}/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! help-opt (string-append "-" tmp-str))
+ (set! 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))
+ \=]
+@node [= prog-name =] Invocation
+@[=(. doc-level) =] Invoking [= 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..6de0458
--- /dev/null
+++ b/autoopts/tpl/bits.tpl
@@ -0,0 +1,721 @@
+[= AutoGen5 Template -*- Mode: C -*-
+
+h
+c
+
+#!/bin/sh
+
+## Time-stamp: "2011-12-30 08:28:20 bkorb"
+## Author: Bruce Korb <bkorb@gnu.org>
+##
+## This file is part of AutoOpts, a companion to AutoGen.
+## AutoOpts is free software.
+## AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f 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") "\"")
+ "<stdint.h>" ) =]
+
+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 <ctype.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+[=
+
+ (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 = (void*)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..b59cef9
--- /dev/null
+++ b/autoopts/tpl/cmd-doc.tlib
@@ -0,0 +1,1001 @@
+[+: -*- Mode: nroff -*-
+
+ AutoGen5 template man
+
+# cmd-doc.tlib -- Template for command line man/mdoc pages
+#
+# Time-stamp: "2012-05-12 20:52:33 bkorb"
+#
+# This file is part of AutoOpts, a companion to AutoGen.
+# AutoOpts is free software.
+# Copyright (c) 1992-2012 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 md5sums:
+#
+# 43b91e8ca915626ed3818ffb1b71248b COPYING.gplv3
+# 06a1a2e4760c90ea5e1dad8dfaac4d39 COPYING.lgplv3
+# 66a5cedaf62c4b2637025f049f9b826f 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=${AGexe%/autogen}/columns")
+
+# END-INSTALL-ONLY-CODE :+][+:
+
+(define down-prog-name (string-downcase! (get "prog-name")))
+(define UP-PROG-NAME (get-up-name "prog-name"))
+
+(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)
+
+(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.")
+
+(set! tmp-str (find-file (if man-page "texi2man" "texi2mdoc")))
+(if (not (defined? 'tmp-str))
+ (error (string-append "cannot locate "
+ (if man-page "texi2man" "texi2mdoc"))))
+(shell (string-append "cvt_prog='" tmp-str
+ "'\ntest -x \"$cvt_prog\" || die 'no conversion program'" ))
+
+(define get-cvt (lambda (nm alt-txt)
+ (shell (string-append
+ "{\n${cvt_prog} || die ${cvt_prog} failed in $PWD\n"
+ "} <<\\_EndOfTexiSection_\n"
+ (get nm alt-txt)
+ "\n_EndOfTexiSection_"
+ ))
+))
+
+(emit (head-line))
+(dne ".\\\" ") :+][+:
+
+INCLUDE "tpl-config.tlib" :+][+:#
+
+.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
+.\" B U I L D D O C
+.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = :+][+:
+
+DEFINE build-doc :+][+:
+
+INVOKE doc-sections :+][+:
+INVOKE ao-sections :+][+:
+
+(out-push-new (string-append tmp-dir "/.assemble")) \:+]
+
+cat_n_rm() {
+ test -f ${tmp_dir}/$1 || return 0
+ [+:(. egrep-prog):+] -v '^[ ]*$' ${tmp_dir}/$1
+ rm -f ${tmp_dir}/$1
+}
+
+#.\" Insert these sections first, in the prescribed order
+#
+for f in synopsis description options option-presets
+do cat_n_rm $f ; done
+test -f ${tmp_dir}/name && rm -f ${tmp_dir}/name
+
+#.\" These sections go last, in the prescribed order
+#
+for f in implementation-notes environment files examples exit-status errors \
+ compatibility see-also conforming-to history authors copyright bugs notes
+do cat_n_rm $f ; done > ${tmp_dir}/.fini
+
+#.\" Insert the contents of all remaining files in alphabetic order,
+#.\" except remove any blank lines.
+#
+set XX ${tmp_dir}/* ; shift
+test -f "$1" && cat $* | [+:(. egrep-prog):+] -v '^[ ]*$'
+
+#.\" Now insert the sections we squirreled away for the end.
+#
+cat ${tmp_dir}/.fini
+[+: (out-pop)
+ (shell ". ${tmp_dir}/.assemble") :+][+:
+
+ENDDEF build-doc
+
+.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
+.\" D O C S E C T I O N S
+.\"
+.\" Emit the files for each section that was provided.
+.\"
+.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = :+][+:
+
+DEFINE doc-sections :+][+:
+
+FOR doc-section :+][+:
+
+ CASE
+ (define sec-type (string-upcase (get "ds-type")))
+ (define sec-name (name-to-fname sec-type))
+ (out-push-new (string-append tmp-dir "/" sec-name))
+ (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"))))
+ sec-type :+][+:
+ == "" :+][+: (error "unnamed doc-section") :+][+:
+ *==* " " :+].Sh "[+: (. sec-type) :+]"[+:
+ * :+].Sh [+: (. sec-type) :+][+:
+ ESAC :+]
+[+:
+ (shell (string-append
+ "fn='" cvt-fn "'\n"
+ "test -f ${fn} || die ${fn} not found from $PWD\n"
+ "${fn} <<\\_EndOfDocSection_ || die ${fn} failed in $PWD\n"
+ (get "ds-text")
+ "\n_EndOfDocSection_"
+ )) :+][+:
+
+ CASE (. 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 :+][+:
+
+INVOKE cond-section sec = "OPTIONS" mode = "replace" :+][+:
+INVOKE cond-section sec = "SYNOPSIS" mode = "alt" :+][+:
+INVOKE cond-section sec = "DESCRIPTION" mode = "append" :+][+:
+INVOKE cond-section sec = "EXIT STATUS" mode = "insert" :+][+:
+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 :+][+:
+
+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 :+][+:
+
+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 "/" macro-name))
+
+ (not (access? file-name R_OK)) :+][+:
+
+ INVOKE (sect-line-fname) :+][+:
+ (out-pop) :+][+:
+
+ ELSE file exists :+][+:
+
+ CASE (get "mode") :+][+:
+
+ == replace :+][+:
+ INVOKE (sect-line-fname) :+][+:
+ (out-pop) :+][+:
+
+ == append :+][+:
+ (out-push-add file-name) :+][+:
+ INVOKE (string-append "append-" macro-name) :+][+:
+ (out-pop) :+][+:
+
+ == insert :+][+:
+ (set! fname-line (shellf "sed '1s/.Sh .*/.Pp/' %s" file-name)) :+][+:
+ INVOKE (sect-line-fname) :+][+:
+ (emit fname-line)
+ (out-pop) :+][+:
+
+ # * -- otherwise, do nothing :+][+:
+
+ ESAC :+][+:
+
+ ENDIF file existence/non-existence :+][+:
+ENDDEF cond-section
+
+.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
+.\" M K - D E S C R I P T I O N
+.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = :+][+:
+
+DEFINE mk-description :+][+:
+
+ (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."
+ ) ) :+]
+[+:
+ INVOKE append-description :+][+:
+
+ENDDEF mk-description
+
+.\" = = = = = APPEND TO IT: :+][+:
+
+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" exists :+][+:
+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-doc-format"))
+
+(if formatted-doc (begin
+ (out-push-new)
+ (set! cvt-cmd (string-append (get "option-doc-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-cvt "descrip" "") :+]"[+:
+
+ IF (set! tmp-str (get-cvt "documentation" ""))
+ (> (string-length tmp-str) 3) :+]
+[+: (. tmp-str) :+]
+[+: ENDIF :+][+:
+
+ ENDIF :+][+:
+ENDFOR flag
+
+.\" = = = = = = = = = = = = = = = = =
+.\" help option
+.\" = = = = = = = = = = = = = = = = =
+
+:+]
+.It [+:
+
+ IF (. use-flags) :+]\-[+: (get "help-value" "?") :+][+:
+ (if (exist? "long-opts") " , \" \\-\\-help\"") :+][+:
+ ELSE :+][+:
+ (if (exist? "long-opts") "\\-\\-") :+]help[+:
+ ENDIF :+]
+Display usage information and exit.[+:#
+
+.\" = = = = = = = = = = = = = = = = =
+.\" more-help option
+.\" = = = = = = = = = = = = = = = = = :+][+:
+
+ IF (not (exist? "no-libopts")) :+]
+.It [+:
+
+ IF (. use-flags) :+]\-[+: ?% more-help-value "%s" "!" :+][+:
+ IF (exist? "long-opts") :+] , " \-\-more-help"[+: ENDIF :+][+:
+ ELSE :+][+:
+ IF (exist? "long-opts") :+]\-\-[+: ENDIF :+]more-help[+:
+ ENDIF :+]
+Pass the extended usage information through a pager.[+:
+
+ENDIF no no-libopts
+
+.\" = = = = = = = = = = = = = = = = =
+.\" save and load configuration
+.\" = = = = = = = = = = = = = = = = = :+][+:
+
+IF (exist? "homerc") :+]
+.It [+:
+
+ IF (. use-flags) :+]\-[+: ?% save-opts-value "%s" ">"
+ :+] " [\fIrcfile\fP][+:
+ IF (exist? "long-opts") :+]," " \-\-save-opts" "[=\fIrcfile\fP][+:
+ ENDIF :+]"[+:
+ ELSE :+][+:
+ IF (exist? "long-opts") :+]\-\-[+:
+ ENDIF :+]save-opts "[=\fIrcfile\fP]"[+:
+ ENDIF :+]
+Save the option state to \fIrcfile\fP. The default is the \fIlast\fP
+configuration file listed in the \fBOPTION PRESETS\fP section, below.
+.It [+:
+
+ IF (. use-flags) :+]\-[+: ?% load-opts-value "%s" "<"
+ :+] " \fIrcfile\fP[+:
+ IF (exist? "long-opts")
+ :+]," " \-\-load-opts" "=\fIrcfile\fP," " \-\-no-load-opts[+:
+ ENDIF :+]"[+:
+ ELSE :+][+:
+ IF (exist? "long-opts") :+]\-\-[+:
+ ENDIF :+]load-opts "=\fIrcfile\fP," " \-\-no-load-opts"[+:
+ ENDIF :+]
+Load options from \fIrcfile\fP.
+The \fIno-load-opts\fP form will disable the loading
+of earlier RC/INI files. \fI\-\-no-load-opts\fP is handled early,
+out of order.[+:
+ENDIF (exist? "homerc")
+
+.\" = = = = = = = = = = = = = = = = =
+.\" version
+.\" = = = = = = = = = = = = = = = = = :+][+:
+
+IF (exist? "version") :+]
+.It [+:
+
+ IF (. use-flags) :+]\-[+: ?% version-value "%s" "v"
+ :+] " [{\fIv|c|n\fP}][+:
+ IF (exist? "long-opts") :+]," " \-\-version" "[=\fI{v|c|n}\fP][+:
+ ENDIF :+]"[+:
+ ELSE :+][+:
+ IF (exist? "long-opts") :+]\-\-[+:
+ ENDIF :+]version "[=\fI{v|c|n}\fP]"[+:
+ ENDIF :+]
+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) :+]_<option-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-cvt "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-cvt "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-cvt "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-noinput
+ (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 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
+.\"
+.\" This section is guaranteed to be the last section in the man page
+.\" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = :+][+:
+
+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 "Please 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") \:+]
+ \-[+:value:+] ", " -\-[+: name :+][+:
+ ELSE \:+]
+ \-[+:value:+][+:
+ ENDIF (exist? "long-opts") :+][+:
+
+ ELSE value does not exist -- named option only :+][+:
+
+ IF (not (exist? "long-opts")) \:+]
+ [+: name :+][+:
+ ELSE \:+]
+ \-\-[+: (. opt-name) :+][+:
+ ENDIF :+][+:
+ ENDIF :+]
+This is an alias for the [+: aliases :+] option.[+:
+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 "\\fI"
+ (fix-optname (if (exist? "arg-name")
+ (get "arg-name")
+ (string-downcase! (get "arg-type")) ))
+ "\\fP" ))
+ )
+
+:+]
+.It [+:
+ IF (exist? "value") :+][+:
+ IF (exist? "long-opts") :+][+:
+
+ # * * * * * * * * * * * * * * * * * * * *
+ *
+ * The option has a flag value (character) AND
+ * the program uses long options
+ *
+ \:+]
+ \-[+:value:+][+:
+ IF (not (exist? "arg-type")) :+] ", " -\-[+:
+ ELSE :+] " [+:(. opt-arg):+], " \-\-[+:
+ ENDIF :+][+: (. opt-name) :+][+:
+ IF (exist? "arg-type") :+][+:
+ ? arg-optional " [ =" ' "=" '
+ :+][+: (. opt-arg) :+][+:
+ arg-optional " ]" :+][+:
+ ENDIF :+][+:
+ IF (exist? "disable") :+], " \fB\-\-[+:(. dis-name):+]\fP"[+:
+ ENDIF :+][+:
+
+ ELSE :+][+:
+
+ # * * * * * * * * * * * * * * * * * * * *
+ *
+ * The option has a flag value (character) BUT
+ * the program does _NOT_ use long options
+ *
+ \:+]
+ \-[+:value:+][+:
+ IF (exist? "arg-type") :+][+:
+ arg-optional "[" :+] "[+:(. opt-arg):+][+:
+ arg-optional '"]"' :+][+:
+ 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 " [ =" ' "=" '
+ :+][+:(. opt-arg) :+][+:
+ arg-optional "]" :+][+:
+ ENDIF:+][+:
+ IF (exist? "disable") :+], " \fB[+:(. dis-name):+]\fP"[+:
+ ENDIF :+][+:
+
+
+ ELSE :+][+:
+ # * * * * * * * * * * * * * * * * * * * *
+ *
+ * The option does not have a flag value (character).
+ * The program, instead, only accepts long options.
+ *
+ \:+]
+ \-\-[+: (. opt-name) :+][+:
+
+ IF (exist? "arg-type") :+] "[+: #" :+][+:
+ arg-optional "[" :+]=[+:(. opt-arg):+][+:
+ arg-optional "]" :+]"[+: #" :+][+:
+ ENDIF :+][+:
+
+ IF (exist? "disable")
+ :+], " \fB\-\-[+:(. dis-name):+]\fP"[+:
+ ENDIF :+][+:
+ ENDIF :+][+:
+ ENDIF :+]
+[+: (get-cvt "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" :+]
+[+: (shellf "
+range='%s'
+
+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"
+
+(get "arg-range") )
+:+][+:
+ 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")
+ (get-cvt "doc" "")
+ "This option has not been fully documented." ) :+][+:
+ IF (exist? "deprecated") :+]
+.sp
+.B
+NOTE: THIS OPTION IS DEPRECATED
+.R[+:
+ ENDIF :+][+:
+
+ENDDEF emit-flag-text
+
+.\" cmd-doc.tlib ends here \:+]
diff --git a/autoopts/tpl/def2pot.tpl b/autoopts/tpl/def2pot.tpl
new file mode 100644
index 0000000..d2c5cc4
--- /dev/null
+++ b/autoopts/tpl/def2pot.tpl
@@ -0,0 +1,131 @@
+[= 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
+#
+
+====================== 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=${AGexe%/autogen}/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 <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+[=
+genmsg msgid=prog-title =][=
+
+FOR flag =][=
+ genmsg msgid=descrip =][=
+ genmsg msgid=doc =][=
+ENDFOR =][=
+
+FOR explain =][=
+ genmsg msgid=explain =][=
+ENDFOR =][=
+
+FOR doc-section =][=
+ genmsg msgid=ds-text =][=
+ENDFOR =][=
+
+FOR prog-man-descrip =][=
+ genmsg msgid=prog-man-descrip =][=
+ENDFOR =][=
+
+FOR prog-info-descrip =][=
+ genmsg msgid=prog-info-descrip =][=
+ENDFOR =][=
+
+FOR detail =][=
+ genmsg msgid=detail =][=
+ENDFOR =][=
+
+FOR exit-desc =][=
+ genmsg msgid=exit-desc =][=
+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..374c8b6
--- /dev/null
+++ b/autoopts/tpl/getopt.tpl
@@ -0,0 +1,517 @@
+[+ AutoGen5 Template -*- Mode: C -*-
+
+ h=%s-temp.h
+ c=%s-temp.c +][+
+
+`stamp=\`sed 's,.*stamp: *",,;s,".*,,' <<\_EOF_
+ Time-stamp: "2012-04-29 08:54:45 bkorb"
+_EOF_
+\` ` +][+
+
+;; This file is part of AutoOpts, a companion to AutoGen.
+;; AutoOpts is free software.
+;; AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+;;
+;; 43b91e8ca915626ed3818ffb1b71248b COPYING.gplv3
+;; 06a1a2e4760c90ea5e1dad8dfaac4d39 COPYING.lgplv3
+;; 66a5cedaf62c4b2637025f049f9b826f 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) \+]
+{
+ test -x "${AGexe}" || die "AGexe not properly set: ${AGexe}"
+[+ # 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@/[^/]*$@@'`
+
+ if ! test -x ${aobdir}/autoopts-config
+ then
+ # Check for autoopts-config in build directory layout
+ #
+ aobdir=`echo ${aobdir} | sed 's@/[^/]*$@@'`/autoopts
+ test -x ${aobdir}/autoopts-config || {
+ aobdir=`echo ${aobdir} | sed 's@/[^/]*/autoopts$@@'`/autoopts
+ test -x ${aobdir}/autoopts-config || \
+ die 'cannot locate autoopts-config'
+ }
+ fi
+
+ agopts=`dirname [+ (tpl-file #t) +]`
+ agopts="-L${aobdir}/tpl -L$agopts "
+ tarfile=`set -- ${aobdir}/libopts*.tar.*
+ test -f $1 || {
+ cd ${aobdir}
+ ${MAKE:-make} libsrc
+ 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
+ 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
+
+ ${AGexe} -b[+ (base-name) +] ${agopts} -Toptions.tpl [+ (def-file) +]
+ def_hdr=[+ (base-name) +].h
+ sed 's@<autoopts/options.h>@"[+ (. 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* pOptions, tOptDesc* pOptDesc);
+
+ CPLUSPLUS_CLOSER
+ _EOF_
+
+sed '1,/^CPLUSPLUS_CLOSER/d' <&3
+exec 3<&-
+rm -rf $untardir
+[+ (shell (out-pop #t)) +]
+[+ == c +]
+#include "[+ (. header-file) +]"
+
+#include <sys/types.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#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:
+ */
+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);
+}
+
+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 +][+
+*= 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 = (char **)(void *)&([+ (. 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" +][+
+ (kr-string (string-append (shell (string-append
+ "sed -e '/version information/s/ -v \\[arg\\]/ -v /' \
+ -e '/: illegal option --/d' \
+ -e 's/ --version\\[=arg\\]/ --version /' <<_EOF_\n"
+ (out-pop #t) "\n_EOF_"
+ )) "\n" )) +][+
+
+ENDDEF
+
+# end of getopt.tpl \+]
diff --git a/autoopts/tpl/gpl.lic b/autoopts/tpl/gpl.lic
new file mode 100644
index 0000000..47cdf95
--- /dev/null
+++ b/autoopts/tpl/gpl.lic
@@ -0,0 +1,20 @@
+<PFX>Copyright (C) <years> <owner>, all rights reserved.
+<PFX>This is free software. It is licensed for use, modification and
+<PFX>redistribution under the terms of the
+<PFX>GNU General Public License, version 3 or later
+<PFX> <http://gnu.org/licenses/gpl.html>
+
+<PFX><program> is free software: you can redistribute it and/or modify it
+<PFX>under the terms of the GNU General Public License as published by the
+<PFX>Free Software Foundation, either version 3 of the License, or
+<PFX>(at your option) any later version.
+<PFX>
+<PFX><program> is distributed in the hope that it will be useful, but
+<PFX>WITHOUT ANY WARRANTY; without even the implied warranty of
+<PFX>MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+<PFX>See the GNU General Public License for more details.
+<PFX>
+<PFX>You should have received a copy of the GNU General Public License along
+<PFX>with this program. If not, see <http://www.gnu.org/licenses/>.
+
+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..31965d3
--- /dev/null
+++ b/autoopts/tpl/gplv2.lic
@@ -0,0 +1,19 @@
+<PFX>Copyright (C) <years> <owner>, all rights reserved.
+<PFX>This is free software. It is licensed for use, modification and
+<PFX>redistribution under the terms of the
+<PFX>GNU General Public License, version 2 <http://gnu.org/licenses/gpl.html>
+
+<PFX><program> is free software: you can redistribute it and/or modify it
+<PFX>under the terms of version 2 of the GNU General Public License,
+<PFX>as published by the Free Software Foundation.
+<PFX>
+<PFX><program> is distributed in the hope that it will be useful, but
+<PFX>WITHOUT ANY WARRANTY; without even the implied warranty of
+<PFX>MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+<PFX>See the GNU General Public License for more details.
+<PFX>
+<PFX>You should have received a copy of the GNU General Public License,
+<PFX>version 2, along with this program.
+<PFX>If not, see <http://www.gnu.org/licenses/>.
+
+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..86c7cf6
--- /dev/null
+++ b/autoopts/tpl/lgpl.lic
@@ -0,0 +1,20 @@
+<PFX>Copyright (C) <years> <owner>, all rights reserved.
+<PFX>This is free software. It is licensed for use, modification and
+<PFX>redistribution under the terms of the
+<PFX>GNU Lesser General Public License, version 3 or later
+<PFX> <http://gnu.org/licenses/lgpl.html>
+
+<PFX><program> is free software: you can redistribute it and/or modify it
+<PFX>under the terms of the GNU Lesser General Public License as published
+<PFX>by the Free Software Foundation, either version 3 of the License, or
+<PFX>(at your option) any later version.
+<PFX>
+<PFX><program> is distributed in the hope that it will be useful, but
+<PFX>WITHOUT ANY WARRANTY; without even the implied warranty of
+<PFX>MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+<PFX>See the GNU Lesser General Public License for more details.
+<PFX>
+<PFX>You should have received a copy of the GNU Lesser General Public License
+<PFX>along with this program. If not, see <http://www.gnu.org/licenses/>.";
+
+the GNU Lesser General Public License, version 3 or later
diff --git a/autoopts/tpl/man2mdoc.pl b/autoopts/tpl/man2mdoc.pl
new file mode 100755
index 0000000..64d3570
--- /dev/null
+++ b/autoopts/tpl/man2mdoc.pl
@@ -0,0 +1,279 @@
+#!/usr/bin/perl
+
+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 = <STDIN>)
+{
+ 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 = <DATA>;
+
+ $retval =~ s/\\fB/ Nm /;
+ $retval =~ s/\\fI/ Ar /;
+ $retval =~ s/\\fR/ /g;
+
+ print ".It ".$retval."\n";
+ last;
+ }
+
+ if ($optlistold) {
+ $retval = <DATA>;
+ $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..6578a51
--- /dev/null
+++ b/autoopts/tpl/man2texi.sh
@@ -0,0 +1,29 @@
+#! /bin/sh
+
+## man2texi.sh -- script to convert man page isms to texi-isms
+##
+## Time-stamp: "2012-02-12 09:25:29 bkorb"
+##
+## This file is part of AutoOpts, a companion to AutoGen.
+## AutoOpts is free software.
+## AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f 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..2537463
--- /dev/null
+++ b/autoopts/tpl/mbsd.lic
@@ -0,0 +1,31 @@
+<PFX>Copyright (C) <years> <owner>, all rights reserved.
+<PFX>This is free software. It is licensed for use, modification and
+<PFX>redistribution under the terms of the
+<PFX>Modified (3 clause) Berkeley Software Distribution License
+<PFX> <http://www.xfree86.org/3.3.6/COPYRIGHT2.html>
+
+<PFX>Redistribution and use in source and binary forms, with or without
+<PFX>modification, are permitted provided that the following conditions
+<PFX>are met:
+<PFX>1. Redistributions of source code must retain the above copyright
+<PFX> notice, this list of conditions and the following disclaimer.
+<PFX>2. Redistributions in binary form must reproduce the above copyright
+<PFX> notice, this list of conditions and the following disclaimer in the
+<PFX> documentation and/or other materials provided with the distribution.
+<PFX>3. Neither the name ``<owner>'' nor the name of any other
+<PFX> contributor may be used to endorse or promote products derived
+<PFX> from this software without specific prior written permission.
+<PFX>
+<PFX><program> IS PROVIDED BY <owner> ``AS IS'' AND ANY EXPRESS
+<PFX>OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+<PFX>WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+<PFX>ARE DISCLAIMED. IN NO EVENT SHALL <owner> OR ANY OTHER CONTRIBUTORS
+<PFX>BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+<PFX>CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+<PFX>SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+<PFX>BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+<PFX>WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+<PFX>OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+<PFX>ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+the Modified Berkeley Software Distribution License
diff --git a/autoopts/tpl/mdoc2man.sh b/autoopts/tpl/mdoc2man.sh
new file mode 100755
index 0000000..815f716
--- /dev/null
+++ b/autoopts/tpl/mdoc2man.sh
@@ -0,0 +1,298 @@
+#! /bin/sh
+
+## mdoc2man.sh -- script to convert mdoc-isms to man-isms
+##
+## Time-stamp: "2012-04-15 07:38:27 bkorb"
+##
+## This file is part of AutoOpts, a companion to AutoGen.
+## AutoOpts is free software.
+## AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f COPYING.mbsd
+
+## This "library" converts mdoc-isms into man-isms. It gets included
+## by the man page template at the point where mdoc-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 mdoc-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`
+NmName=
+
+die() {
+ echo "$prog error: $*" >&2
+ ps -p ${AG_pid:-999999999} >/dev/null 2>&1 && \
+ kill -TERM ${AG_pid}
+ kill -TERM $parent_pid
+ sleep 1
+ kill -9 $parent_pid
+ sleep 1
+ exit 1
+}
+
+had_no_arg() {
+ die "'$1' command had no argument: <$line>"
+}
+
+# One function for each mdoc structure.
+#
+do_nest_enum() {
+ do_enum
+}
+
+do_enum() {
+ echo '.in +4'
+ local ix=1
+
+ while IFS='' read -r line
+ do
+ case "${line}" in
+ .It* ) printf '.ti -4\n%d\n\t' $ix
+ ix=`expr $ix + 1`
+ ;;
+
+ .Bl' '*enum* ) do_nest_enum ;;
+ .Bl' '*tag* ) do_nest_tag ;;
+ .Bl' '*bullet* ) do_nest_bullet ;;
+ .Bd' '* ) do_nest_block ;;
+ .Op' '* ) do_nest_optional ;;
+ .Fl' '* ) do_nest_flag ;;
+ .Ar' '* ) do_nest_arg ;;
+
+ .El* ) echo '.in -4'
+ return 0 ;;
+
+ * ) echo "$line" ;;
+ esac
+ done
+ die "EOF reached processing '.Bl -enum'"
+}
+
+do_nest_tag() {
+ echo '.in +4'
+ while IFS='' read -r line
+ do
+ case "${line}" in
+ .It* ) printf '.ti -4\n.IR '
+ echo ${line#.It} ;;
+
+ .Bl' '*enum* ) do_nest_enum ;;
+ .Bl' '*tag* ) do_nest_tag ;;
+ .Bl' '*bullet* ) do_nest_bullet ;;
+ .Bd' '* ) do_nest_block ;;
+ .Op' '* ) do_nest_optional ;;
+ .Fl' '* ) do_nest_flag ;;
+ .Ar' '* ) do_nest_arg ;;
+
+ .El* ) echo '.in -4'
+ return 0 ;;
+
+ * ) echo "$line" ;;
+ esac
+ done
+ die "EOF reached processing '.Bl -tag'"
+}
+
+do_tag() {
+ while IFS='' read -r line
+ do
+ case "${line}" in
+ .It* ) printf '.TP\n.BR '
+ echo ${line#.It} ;;
+
+ .Bl' '*enum* ) do_nest_enum ;;
+ .Bl' '*tag* ) do_nest_tag ;;
+ .Bl' '*bullet* ) do_nest_bullet ;;
+ .Bd' '* ) do_nest_block ;;
+ .Op' '* ) do_nest_optional ;;
+ .Fl' '* ) do_nest_flag ;;
+ .Ar' '* ) do_nest_arg ;;
+ .El* ) return 0 ;;
+ * ) echo "$line" ;;
+ esac
+ done
+ die "EOF reached processing '.Bl -tag'"
+}
+
+do_nest_bullet() {
+ do_bullet
+}
+
+do_bullet() {
+ echo '.in +4'
+ while IFS='' read -r line
+ do
+ case "${line}" in
+ .It* ) printf '.ti -4\n\\fB*\\fP\n'
+ echo ${line#.It}
+ ;;
+
+ .Bl' '*enum* ) do_nest_enum ;;
+ .Bl' '*tag* ) do_nest_tag ;;
+ .Bl' '*bullet* ) do_nest_bullet ;;
+ .Bd' '* ) do_nest_block ;;
+ .Op' '* ) do_nest_optional ;;
+ .Fl' '* ) do_nest_flag ;;
+ .Ar' '* ) do_nest_arg ;;
+
+ .El* ) echo '.in -4'
+ return 0 ;;
+
+ * ) echo "$line" ;;
+ esac
+ done
+ die "EOF reached processing '.Bl -bullet'"
+}
+
+do_nest_block() {
+ do_block
+}
+
+do_block() {
+ printf '.br\n.in +4\n.nf\n'
+ while IFS='' read -r line
+ do
+ case "${line}" in
+ .B* ) die ".Bx command nested within .Bd" ;;
+
+ .Ed* ) echo .in -4
+ echo .fi
+ return 0 ;;
+
+ * ) echo "$line" ;;
+ esac
+ done
+ die "EOF reached processing '.Bd'"
+}
+
+do_nest_optional() {
+ do_optional
+}
+
+do_optional() {
+ set -- $line
+ shift
+ local text='['
+ while test $# -gt 0
+ do
+ m1="$1"
+ case "X$1" in
+ 'X...' | 'X\*' )
+ text=${text}' "\fI'${1}'\fR"'
+ shift
+ ;;
+ XAr | XCm )
+ text=${text}' "\fI'${2}'\fR"'
+ shift 2 || had_no_arg "$m1"
+ ;;
+ XFl )
+ text=${text}' \fB-'${2}'\fR'
+ shift 2 || had_no_arg "$m1"
+ ;;
+ * ) text="${text} \"$2\""
+ m1="$1"
+ shift 2 || had_no_arg "$m1"
+ ;;
+ esac
+ done
+ echo "${text} ]"
+}
+
+do_nest_flag() {
+ do_flag
+}
+
+do_flag() {
+ echo ${line#.Fl}
+}
+
+do_nest_arg() {
+ do_arg
+}
+
+do_arg() {
+ line=`echo ${line#.Ar}`
+ echo "\\fI${line}\\fR"
+}
+
+do_NmName() {
+ # do we want to downcase the line first? Yes...
+ set -- `echo ${line#.Nm} | \
+ sed -e 's/-/\\-/g' \
+ -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
+ NmNameSfx=
+
+ if test $# -gt 0
+ then case "$1" in
+ [A-Za-z]* )
+ NmName=$1
+ shift
+ ;;
+ esac
+
+ test $# -gt 0 && NmNameSfx=" $*"
+ fi
+ echo ".B $NmName$NmNameSfx"
+}
+
+do_line() {
+ case "${line}" in
+ .Bl' '*enum* ) do_enum ;;
+ .Bl' '*tag* ) do_tag ;;
+ .Bl' '*bullet* ) do_bullet ;;
+ .Bd' '* ) do_block ;;
+ .Op' '* ) do_optional ;;
+ .Fl' '* ) do_flag ;;
+ .Ar' '* ) do_arg ;;
+ .Nm' '* ) do_NmName ;;
+ .Nm ) do_NmName ;;
+ * ) echo "$line" ;;
+ esac
+ return 0
+}
+
+
+
+easy_fixes='
+s/^\.Sh/.SH/
+s/^\.Ss/.SS/
+s/^\.Em/.I/
+s/^\.Pp/.PP/
+s/^.in *\\-/.in -/
+'
+
+readonly easy_fixes
+set -f
+
+{
+ while IFS='' read -r line
+ do
+ do_line
+ done
+} | sed "${easy_fixes}"
+
+exit 0
diff --git a/autoopts/tpl/mdoc2texi.pl b/autoopts/tpl/mdoc2texi.pl
new file mode 100755
index 0000000..859690e
--- /dev/null
+++ b/autoopts/tpl/mdoc2texi.pl
@@ -0,0 +1,345 @@
+#! /usr/bin/perl
+
+use strict;
+
+my ($optlist,$oldoptlist);
+my ($literal);
+my ($line);
+my ($count,$tableitemcount);
+my ($progName);
+my (@words, $retval,$columnline);
+
+$optlist = 0; ### 1 = bullet, 2 = enum, 3 = tag, 4 = item
+$oldoptlist = 0;
+
+while ($line = <STDIN>)
+{
+ if ($line !~ /^\./)
+ {
+ print $line;
+ print ".br\n"
+ if ($literal);
+ next;
+ }
+
+ next
+ if ($line =~ /^\.\\"/);
+
+ $line = ParseMacro($line);
+ print($line)
+ if (defined $line);
+}
+
+sub Handle_Bl
+{
+ if ($words[0] eq '-bullet')
+ {
+ if (!$optlist)
+ {
+ $optlist = 1; #bullet
+ $retval .= "\@itemize \@bullet\n" ;
+ print "$retval";
+ return 1;
+ }
+ else
+ {
+ $retval .= "\@itemize \@minus\n";
+ print $retval;
+ $oldoptlist = 1;
+ return 1;
+ }
+ }
+ if ($words[0] eq '-enum')
+ {
+ if (!$optlist)
+ {
+ $optlist = 2; #enum
+ $retval .= "\@enumerate\n" ;
+ print "$retval";
+ return 1;
+ }
+ else
+ {
+ $retval .= "\@enumerate\n";
+ print $retval;
+ $oldoptlist = 2;
+ return 1;
+ }
+ }
+ if ($words[0] eq '-tag')
+ {
+ $optlist = 3; #tag
+ $retval .= "\@table \@samp\n";
+ print "$retval";
+ return 1;
+ }
+ if ($words[0] eq '-column')
+ {
+ $optlist = 4; #column
+ $retval = "\@multitable \@columnfractions ";#\.20 \.20 \.20\n";
+ #print $retval;
+ $columnline = "\@headitem ";
+ #print $retval;
+ foreach(@words)
+ {
+ if (!/^"./ && !/-column/ && !/indent/ && !/-offset/)
+ {
+ $_ =~ s/\"//g;
+
+ $retval .= "\.20 ";
+ if (!$count)
+ {
+ $columnline .= $_;
+ }
+ else
+ {
+ $columnline .= " \@tab ".$_;
+ }
+ $count++;
+ }
+ }
+ print $retval."\n";
+ print $columnline;
+ return 1;
+ }
+
+ return 0;
+}
+
+sub Handle_It
+{
+ if ($optlist == 3)
+ {
+ $retval .= "\@item ".$words[0]."\n";
+ print $retval;
+ return 1;
+ }
+ elsif ($optlist == 4 )
+ {
+ if (!$tableitemcount)
+ {
+ $tableitemcount = 1;
+ return 1;
+ }
+ else
+ {
+ foreach(@words)
+ {
+ if (/^Li$/)
+ {
+ print "\n\@item ";
+ return 0;
+ }
+ elsif (/^Ta$/)
+ {
+ print "\n\@tab ";
+ return 0;
+ }
+ else
+ {
+ print $_;
+ return 0;
+ }
+ }
+ return 1;
+ }
+ }
+ else
+ {
+ print "\@item\n";
+ }
+ return 0;
+}
+
+sub Handle_El
+{
+ if ($oldoptlist)
+ {
+ if ($oldoptlist == 1)
+ {
+ $oldoptlist = 0;
+ $retval .= "\@end itemize\n";
+ print $retval;
+ }
+ elsif ($oldoptlist == 2)
+ {
+ $oldoptlist = 0;
+ $retval .= "\@end enumerate\n";
+ print $retval;
+ }
+ }
+ else
+ {
+ if ($optlist == 1)
+ {
+ $oldoptlist = 0;
+ $retval .= "\@end itemize\n";
+ print $retval;
+ }
+ elsif ($optlist == 2)
+ {
+ $oldoptlist = 0;
+ $retval .= "\@end enumerate\n";
+ print $retval;
+ }
+ elsif ($optlist = 4)
+ {
+ $count = 0;
+ $columnline = '';
+ $oldoptlist = 0;
+ $optlist = 0;
+ $tableitemcount = 0;
+ $retval .= "\n\@end multitable\n";
+ print $retval;
+ }
+ $optlist = 0;
+ }
+}
+
+sub Handle_Fl
+{
+ # .Cm is .Fl but no '-'.
+ # Usage: .Fl <argument> ...
+ #
+ # .Fl -
+ # .Fl cfv -cfv
+ # .Fl cfv . -cfv.
+ # .Cm cfv . cfv.
+ # .Fl s v t -s -v -t
+ # .Fl - , --,
+ # .Fl xyz ) , -xyz),
+ # .Fl | - |
+ #
+ my ($dash, $didOne);
+ $dash = "-"; # or empty if .Cm
+ $didOne = 0;
+
+ do {
+ if ($words[0] eq '' || $words[0] =~ /^[-\w]+$/)
+ {
+ print " " if $didOne;
+ print '@code{', $dash, $words[0], '}';
+ }
+ elsif ($words[0] eq '|')
+ {
+ print " " if $didOne;
+ print '@code{', $dash, '}', " $words[0]";
+ }
+ else
+ {
+ print "$words[0]";
+ }
+ shift @words;
+ $didOne = 1;
+ } while scalar(@words);
+ print " ";
+}
+
+sub Handle_Nm
+{
+ # Usage: .Nm [<argument>] ...
+ #
+ # .Nm groff_mdoc groff_mdoc
+ # .Nm \-mdoc -mdoc
+ # .Nm foo ) ) , foo)),
+ # .Nm : groff_mdoc:
+ #
+ if (!defined $progName)
+ {
+ if (defined $ENV{AG_DEF_PROG_NAME})
+ {
+ $progName = $ENV{AG_DEF_PROG_NAME};
+ }
+ else
+ {
+ $progName = "XXX Program Name";
+ }
+ }
+
+ if ($words[0] =~ /^[\\\w]/)
+ {
+ $progName = shift @words;
+ }
+ print '@code{', $progName, '}';
+
+ # Anything after this should be punctuation
+
+ while ($_ = shift @words)
+ {
+ print;
+ }
+ print "\n";
+}
+
+sub Handle_Xr
+{
+ # Usage: .Xr <man page name> [<section>] ...
+ # .Xr mdoc mdoc
+ # .Xr mdoc , mdoc,
+ # .Xr mdoc 7 mdoc(7)
+ # .Xr xinit 1x ; xinit(1x);
+ #
+ # Emitting things like @uref{/man.cgi/1/ls,,ls} would be OK,
+ # but we'd have to allow for changing /man.cgi/ (at least).
+ # I'm OK with:
+ # @code{mdoc}
+ # @code{mdoc},
+ # @code{mdoc(7)}
+ # @code{xinit(1x);
+ #
+ my ($xr_cmd, $xr_sec, $xr_punc);
+ if (@words == 1)
+ {
+ $xr_cmd = $words[0];
+ }
+ elsif (@words == 2)
+ {
+ $xr_cmd = shift @words;
+ if ($words[0] =~ /[[:punct:]]/)
+ {
+ $xr_punc = shift @words;
+ }
+ else
+ {
+ $xr_sec = shift @words;
+ }
+ }
+ elsif (@words == 3)
+ {
+ $xr_cmd = shift @words;
+ $xr_sec = shift @words;
+ $xr_punc = shift @words;
+ }
+ else
+ {
+ }
+
+ # HMS: do we really want 'defined' in the following tests?
+ print '@code{',"$xr_cmd" if (defined $xr_cmd);
+ print "($xr_sec)" if (defined $xr_sec);
+ print "}" if (defined $xr_cmd);
+ print "$xr_punc" if (defined $xr_punc);
+ print "\n";
+}
+
+sub ParseMacro #line
+{
+ my ($line) = @_;
+
+ @words = split(/\s+/, $line);
+ $retval = '';
+
+ # print('@words = ', scalar(@words), ': ', join(' ', @words), "\n");
+
+ while ($_ = shift @words)
+ {
+ if (/^\.Bl$/) { last if (Handle_Bl()); }
+ elsif ($optlist && /^\.It$/) { last if (Handle_It()); }
+ elsif (/^\.El$/) { Handle_El(); }
+ elsif (/^\.Fl$/) { Handle_Fl(); }
+ elsif (/^\.Nm/) { Handle_Nm(); }
+ elsif (/^\.Pp$/) { print "\n"; }
+ elsif (/^\.Xr/) { Handle_Xr(); }
+ else { print $_,"\n"; }
+ }
+}
diff --git a/autoopts/tpl/optcode.tlib b/autoopts/tpl/optcode.tlib
new file mode 100644
index 0000000..9f519ae
--- /dev/null
+++ b/autoopts/tpl/optcode.tlib
@@ -0,0 +1,819 @@
+[= autogen5 template
+
+# Time-stamp: "2012-08-11 08:31:28 bkorb"
+#
+## This file is part of AutoOpts, a companion to AutoGen.
+## AutoOpts is free software.
+## AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f 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 "-<flag>" on the usage line.
+;;; If the program has the "long-opts" attribute set, then we must
+;;; have "<option-name>" or "--<name>" on the line, depending on
+;;; whether or not there are flag options. If any options take
+;;; arguments, then append "[<val>]" to the flag description and
+;;; "[{=| }<val>]" 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 "[{=| }<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 "-<flag>"
+ (if (exist? "flag.arg-type") " [<val>]" "")
+ (if (exist? "long-opts") " | " "") )
+ (if (not (exist? "long-opts"))
+ (string-append "<option-name>" tmp-val) "" ) )
+
+ (if (exist? "long-opts")
+ (string-append "--<name>" 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 (exist? "version")
+ (string-append " - Ver. " (get "version"))
+ "" )
+ "\n" usage-line "\n"
+))
+
+=][= # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][=
+
+INCLUDE "optmain.tlib"
+
+=][=
+
+IF (or (= "shell-process" (get "main.main-type"))
+ (= "shell-parser" (get "main.main-type"))
+ (exist? "main.code")) =]
+#define [= (set! make-test-main #t) main-guard =] 1[=
+ENDIF
+=]
+#ifndef __doxygen__
+#define OPTION_CODE_COMPILE 1
+#include "[= (define lib-externs "") header-file=]"[=
+
+IF (== (get "main.main-type" "") "for-each")
+
+=]
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>[=
+
+ELSE
+
+=]
+#include <sys/types.h>
+
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>[=
+
+ (if (exist? "flag.arg-range")
+ (emit "\n#include <errno.h>"))
+
+ (if (and (exist? "resettable") (exist? "flag.open-file"))
+ (emit "
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>" )) =][=
+
+ENDIF
+
+=]
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+extern FILE * option_usage_fp;
+
+/* TRANSLATORS: choose the translation for option names wisely because you
+ cannot ever change your mind. */[=
+
+IF (not (exist? "copyright"))
+
+=]
+#define zCopyright NULL
+#define zLicenseDescrip NULL[=
+ELSE =][=
+ (define cright-owner (get "copyright.owner" (get "copyright.author")))
+ =][=
+ CASE (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))
+(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" ))
+
+ (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
+
+/*
+ * [= prog-name =] option static const strings
+ */[=
+ (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 (. make-test-main) =]
+#ifdef [=(. main-guard) =]
+# define VER_PROC optionVersionStderr
+#else
+# define VER_PROC optionPrintVersion
+#endif /* [=(. main-guard)=] */[=
+ ELSE =]
+#define VER_PROC optionPrintVersion[=
+ ENDIF make-test-main =][=
+
+ENDIF there is a version
+
+=]
+[= INVOKE emit-option-desc-table =]
+[= (. lib-externs) =]
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * Define the [= (. prog-name) =] Option Environment
+ */
+#define zPROGNAME ([= (string-table-add-ref opt-strs pname-up) =])
+#define zUsageTitle ([=
+ (define homerc-ct 0)
+ (define homerc-txt "")
+ (string-table-add-ref opt-strs usage-text) =])
+[=
+FOR homerc =][=
+ (set! tmp-text (get "homerc"))
+ (if (> (string-length tmp-text)) (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) \=]
+#define zRcName ([=
+ (set! tmp-text (if (exist? "rcfile") (get "rcfile")
+ (string-append "." pname-down "rc") ))
+ (string-table-add-ref opt-strs tmp-text) =])
+static char const * const apzHomeList[=
+ (sprintf "[%u] = {%s\n NULL };" (+ 1 homerc-ct) homerc-txt) =][=
+
+ELSE \=]
+#define zRcName NULL
+#define apzHomeList NULL[=
+ENDIF =]
+#define zBugsAddr ([=
+(out-push-new) \=]
+s/@[a-z]*{\([^{@}]*\)}/``\1''/g
+s=@<prog-name>@=[= 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 "\n"
+
+ (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"
+) ) =])
+#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 '#'-prefixed lines are comments.
+'stdin' may not be a terminal (tty).\n" )) )
+
+ (string-table-add-ref opt-strs tmp-text)
+ )
+ "NULL"
+) =])
+#define zDetail ([=
+
+(if (exist? "detail")
+ (begin
+ (patch-text "detail")
+ (string-table-add-ref opt-strs tmp-text)
+ )
+ "NULL"
+) =])
+#define zFullVersion ([=
+
+(if (exist? "version")
+ (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") =]
+static optArgBucket_t const original_[=(. pname-down)=]_defaults[ [=
+(. UP-prefix) =]OPTION_CT ] = {
+[= (shell (string-append
+ "sed '$s@},@} @' <<\\_EOF_" default-text "\n_EOF_\n")) =]
+};
+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 usage-text usage-type = full \=]
+[= INVOKE usage-text usage-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
+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") =][=
+ (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[= IF (not (exist? "allow-errors")) =]
+ + OPTPROC_ERRSTOP[= ENDIF=][=IF (exist? "flag.value") =]
+ + OPTPROC_SHORTOPT[= ENDIF=][=IF (exist? "long-opts") =]
+ + OPTPROC_LONGOPT[= ENDIF=][=IF (not (exist? "flag.min")) =]
+ + OPTPROC_NO_REQ_OPT[= ENDIF=][=IF (exist? "flag.disable") =]
+ + OPTPROC_NEGATIONS[= ENDIF=][=IF (>= number-opt-index 0) =]
+ + OPTPROC_NUM_OPT[= ENDIF=][=IF (exist? "environrc") =]
+ + OPTPROC_ENVIRON[= ENDIF=][=IF (not (exist? "argument")) =]
+ + OPTPROC_NO_ARGS[= ELIF (not (==* (get "argument") "[" )) =]
+ + OPTPROC_ARGS_REQ[= ENDIF=][=IF (exist? "reorder-args") =]
+ + OPTPROC_REORDER[= ENDIF=][=IF (exist? "gnu-usage") =]
+ + OPTPROC_GNUUSAGE[= ENDIF=][=IF (exist? "no-misuse-usage") =]
+ + OPTPROC_MISUSE[= ENDIF=][=IF (exist? "vendor-opt") =]
+ + OPTPROC_VENDOR_OPT[= ENDIF=] ),
+ 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 =][=
+
+INVOKE emit-nls-code
+
+=]
+#ifdef __cplusplus
+}
+#endif[= #
+
+// = = = = = = = = = = = = = = = = = = = = = = = = = = = = =][=
+
+DEFINE emit-nls-code
+
+=][= IF (. omit-nls-code) =][= RETURN =][= ENDIF
+
+=]
+#if ENABLE_NLS
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <autoopts/usage-txt.h>
+
+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.
+ *
+ * @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* pzRes;
+ if (pz == NULL)
+ return NULL;
+ pzRes = _(pz);
+ if (pzRes == pz)
+ return pzRes;
+ pzRes = strdup(pzRes);
+ if (pzRes == NULL) {
+ fputs(_("No memory for duping translated strings\n"), stderr);
+ exit([=(. nomem-exit-code)=]);
+ }
+ return pzRes;
+}
+
+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 pOpt = &[=(. 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_usage_text.field_ct != 0) {
+ /*
+ * Do the translations. The first pointer follows the field count
+ * field. The field count field is the size of a pointer.
+ */
+ tOptDesc * pOD = pOpt->pOptDesc;
+ char ** ppz = (char**)(void*)&(option_usage_text);
+ int ix = option_usage_text.field_ct;
+
+ do {
+ ppz++;
+ *ppz = AO_gettext(*ppz);
+ } while (--ix > 0);
+[=
+ FOR field IN pzCopyright pzCopyNotice pzFullVersion pzUsageTitle pzExplain
+ pzDetail pzPackager =]
+ coerce_it((void*)&(pOpt->[= field =]));[=
+ ENDFOR =][=
+
+ IF (exist? "full-usage") =]
+ coerce_it((void*)&(pOpt->pzFullUsage));[=
+ ENDIF =][=
+
+ IF (exist? "short-usage") =]
+ coerce_it((void*)&(pOpt->pzShortUsage));[=
+ ENDIF =]
+ option_usage_text.field_ct = 0;
+
+ for (ix = pOpt->optCt; ix > 0; ix--, pOD++)
+ coerce_it((void*)&(pOD->pzText));
+ }
+
+ if ((pOpt->fOptSet & OPTPROC_NXLAT_OPT_CFG) == 0) {
+ tOptDesc * pOD = pOpt->pOptDesc;
+ int ix;
+
+ for (ix = pOpt->optCt; ix > 0; ix--, pOD++) {[=
+
+ FOR field IN pz_Name pz_DisableName pz_DisablePfx =][=
+
+ (sprintf "\n coerce_it((void*)&(pOD->%1$s));"
+ (get "field")) =][=
+
+ ENDFOR =]
+ }
+ /* prevent re-translation */
+ [= (. pname)
+ =]Options.fOptSet |= OPTPROC_NXLAT_OPT_CFG | OPTPROC_NXLAT_OPT;
+ }
+}
+
+#endif /* ENABLE_NLS */
+[=
+
+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, 0,
+ /* 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, 0,
+ /* 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 },
+
+[=
+
+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, 0,
+ /* 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, 0,
+ /* 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, 0,
+ /* 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, 0,
+ /* 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") =], 0,
+ /* 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, 0, /* both directions */
+ /* 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..86e87bf
--- /dev/null
+++ b/autoopts/tpl/opthead.tlib
@@ -0,0 +1,601 @@
+[= autogen5 template -*- Mode: C -*-
+
+# Time-stamp: "2012-08-11 08:56:26 bkorb"
+#
+## This file is part of AutoOpts, a companion to AutoGen.
+## AutoOpts is free software.
+## AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f 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.
+ */
+[= (make-header-guard "autoopts") =][=
+% config-header "\n#include \"%s\"" =]
+#include <autoopts/options.h>[=
+(if (or (exist? "usage-message") (exist? "die-code"))
+ "\n#include <stdarg.h>") =]
+[= IF
+
+ (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 ",")
+ ) ) )
+
+ (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 =]
+/*
+ * Enumeration of each option:
+ */
+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;
+
+#define [=(. UP-prefix)=]OPTION_CT [= (. option-ct) =][=
+IF (exist? "version") =]
+#define [=(. pname-up)=]_VERSION [=(c-string (get "version"))=]
+#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")
+
+=]
+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) tmp-val
+
+=][=
+
+IF (> 1 (string-length UP-prefix))
+
+=]
+#define HAVE_OPT(n) (! UNUSED_OPT(& DESC(n)))
+#define OPT_ARG(n) (DESC(n).optArg.argString)
+#define STATE_OPT(n) (DESC(n).fOptState & OPTST_SET_MASK)
+#define COUNT_OPT(n) (DESC(n).optOccCt)
+#define ISSEL_OPT(n) (SELECTED_OPT(&DESC(n)))
+#define ISUNUSED_OPT(n) (UNUSED_OPT(& DESC(n)))
+#define ENABLED_OPT(n) (! DISABLED_OPT(& DESC(n)))
+#define STACKCT_OPT(n) (((tArgList*)(DESC(n).optCookie))->useCt)
+#define STACKLST_OPT(n) (((tArgList*)(DESC(n).optCookie))->apzArgs)
+#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 )[=
+
+ELSE we have a prefix:
+
+=][= (sprintf "
+#define HAVE_%1$sOPT(n) (! UNUSED_OPT(& %1$sDESC(n)))
+#define %1$sOPT_ARG(n) (%1$sDESC(n).optArg.argString)
+#define STATE_%1$sOPT(n) (%1$sDESC(n).fOptState & OPTST_SET_MASK)
+#define COUNT_%1$sOPT(n) (%1$sDESC(n).optOccCt)
+#define ISSEL_%1$sOPT(n) (SELECTED_OPT(&%1$sDESC(n)))
+#define ISUNUSED_%1$sOPT(n) (UNUSED_OPT(& %1$sDESC(n)))
+#define ENABLED_%1$sOPT(n) (! DISABLED_OPT(& %1$sDESC(n)))
+#define STACKCT_%1$sOPT(n) (((tArgList*)(%1$sDESC(n).optCookie))->useCt)
+#define STACKLST_%1$sOPT(n) (((tArgList*)(%1$sDESC(n).optCookie))->apzArgs)
+#define CLEAR_%1$sOPT(n) STMTS( \\
+ %1$sDESC(n).fOptState &= OPTST_PERSISTENT_MASK; \\
+ if ((%1$sDESC(n).fOptState & OPTST_INITENABLED) == 0) \\
+ %1$sDESC(n).fOptState |= OPTST_DISABLED; \\
+ %1$sDESC(n).optCookie = NULL )"
+
+ UP-prefix ) =][=
+
+ENDIF prefix/not =]
+
+/* * * * * *
+ *
+ * Enumeration of [= prog-name =] exit codes
+ */
+typedef enum {[=
+ #/*
+ ;; 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 need-ex-noinput (exist? "homerc"))
+ (define need-ex-software #t)
+
+ (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 (string-append
+ "\n " pname-up "_EXIT_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) "," "")
+ "\n " pname-up "_EXIT_FAILURE = 1" ))
+ )
+
+ (define nomem-exit-code
+ (if (exist? "nomem-fail-code")
+ (string-append pname-up "_EXIT_" (get-up-name "nomem-fail-code"))
+ fail-exit-code))
+
+ (define file-fail-exit-code
+ (if (exist? "file-fail-code")
+ (string-append pname-up "_EXIT_" (get-up-name "file-fail-code"))
+ fail-exit-code))
+
+ (if (and (exist? "exit-name") (> (string-length tmp-val) 1))
+ (set! tmp-val (string-append tmp-val ",")) )
+
+ tmp-val =][=
+
+ FOR exit-name "," =]
+ [=
+ (if (= (for-index) 66)
+ (set! need-ex-noinput #f)
+ (if (= (for-index) 70)
+ (set! need-ex-software #f) ))
+
+ pname-up =]_EXIT_[= (get-up-name "exit-name")
+ =] = [= (for-index) =][=
+ ENDFOR =][=
+ (if need-ex-noinput
+ (ag-fprintf 0 ",\n %s_EXIT_NO_CONFIG_INPUT = 66" pname-up))
+ (if need-ex-software
+ (ag-fprintf 0 ",\n %s_EXIT_LIBOPTS_FAILURE = 70" pname-up))
+=]
+} [= (. pname-down) =]_exit_code_t;[=
+
+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 on guard-option-names
+
+=]
+/* * * * * *
+ *
+ * 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)
+=]
+#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
+
+* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+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.
+
+=][=
+
+DEFINE set-std-value =]
+#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))
+ (string-append INDEX-pfx (get "val-UPNAME")) )
+ (sprintf "'%s'" (get "std-value"))
+ ) =][=
+
+ == "'" =]'\''[=
+ ~~ . =]'[=(get tmp-val)=]'[=
+ * =][=(error "value (flag) codes must be single characters") =][=
+ ESAC =][=
+ENDDEF set-std-value =][=
+
+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#define " VALUE-pfx "%1$-16s " INDEX-pfx "%1$s"))
+(define std-vals (lambda (std-nm)
+ (ag-fprintf 0 index-fmt std-nm) ))
+
+(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 =][=
+
+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"))
+
+=]
+/*
+ * Interface defines not associated with particular options
+ */
+#define ERRSKIP_[=
+
+ IF (> 1 (string-length UP-prefix))
+
+=][= (sprintf "OPTERR STMTS(%1$sOptions.fOptSet &= ~OPTPROC_ERRSTOP)
+#define ERRSTOP_OPTERR STMTS(%1$sOptions.fOptSet |= OPTPROC_ERRSTOP)
+#define RESTART_OPT(n) STMTS( \\
+ %1$sOptions.curOptIdx = (n); \\
+ %1$sOptions.pzCurOpt = NULL)
+#define START_OPT RESTART_OPT(1)
+#define USAGE(c) (*%1$sOptions.pUsageProc)(&%1$sOptions, c)"
+ pname ) =][=
+
+ ELSE we have a prefix
+
+=][= (sprintf "%1$sOPTERR STMTS(%2$sOptions.fOptSet &= ~OPTPROC_ERRSTOP)
+#define ERRSTOP_%1$sOPTERR STMTS(%2$sOptions.fOptSet |= OPTPROC_ERRSTOP)
+#define RESTART_%1$sOPT(n) STMTS( \\
+ %2$sOptions.curOptIdx = (n); \\
+ %2$sOptions.pzCurOpt = NULL )
+#define START_%1$sOPT RESTART_%1$sOPT(1)
+#define %1$sUSAGE(c) (*%2$sOptions.pUsageProc)(&%2$sOptions, c)"
+
+ UP-prefix pname ) =][=
+
+ ENDIF have/don't have prefix ' =][=
+
+ENDIF is not a library
+
+* * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+=][=
+(tpl-file-line extract-fmt)
+=][=
+
+IF (not (exist? "library"))
+
+=]
+#ifdef __cplusplus
+extern "C" {
+#endif
+[=INVOKE join-or-expand join-type = "export" =][=
+
+ IF (exist? "usage-message") =]
+extern void [=(. lc-prefix)=]vusage_message(char const * fmt, va_list ap);
+extern void [=(. lc-prefix)=]usage_message(char const * fmt, ...);
+[=ENDIF have usage-message =]
+
+/* * * * * *
+ *
+ * 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 <stdio.h>
+# ifndef HAVE_GETTEXT
+ extern char * gettext(char const *);
+# else
+# include <libintl.h>
+# endif
+
+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 */")) =][=
+
+IF (exist? "die-code") =]
+
+extern void [=(. lc-prefix)=]vdie( int exit_code, char const * fmt, va_list);
+extern void [=(. lc-prefix)=]die( int exit_code, char const * fmt, ...);
+extern void [=(. lc-prefix)
+=]fserr(int exit_code, char const * op, char const * fname);[=
+
+ENDIF die-code exists =]
+
+#ifdef __cplusplus
+}
+#endif[=
+
+ENDIF this is not a lib
+
+=]
+#endif /* [=(. header-guard)=] */[=
+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
+/*
+ * 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..41d6291
--- /dev/null
+++ b/autoopts/tpl/options.tpl
@@ -0,0 +1,57 @@
+[= Autogen5 Template -*- Mode: scheme -*-
+
+h
+c
+
+# Time-stamp: "2011-01-28 10:30:50 bkorb"
+
+# 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-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f COPYING.mbsd
+
+=][= (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 =]
+/* [= (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..9d72c15
--- /dev/null
+++ b/autoopts/tpl/optlib.tlib
@@ -0,0 +1,1260 @@
+[= AutoGen5 Template Library -*- Mode: scheme -*-
+
+# Time-stamp: "2012-08-11 08:14:10 bkorb"
+#
+# This file is part of AutoOpts, a companion to AutoGen.
+# AutoOpts is free software.
+# AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+#
+# 43b91e8ca915626ed3818ffb1b71248b COPYING.gplv3
+# 06a1a2e4760c90ea5e1dad8dfaac4d39 COPYING.lgplv3
+# 66a5cedaf62c4b2637025f049f9b826f 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)) )
+
+ ;;# 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=${AGexe%/autogen}/columns")
+
+# END-INSTALL-ONLY-CODE =][=
+
+(make-tmp-dir)
+(define get-opt-value (lambda (val)
+ (if (<= val 32) val (+ val 96)) ))
+
+(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 need-stacking (lambda()
+ (if (not (exist? "max"))
+ #f
+ (> (string->number (get "max")) 1)
+) ) )
+
+(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 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' conflicts with 'long-opts' and requires flag values")
+ (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'"))
+) )
+
+;; 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 main-guard (string-append "TEST_" pname-up "_OPTS" ))
+(define number-opt-index -1)
+(define default-opt-index -1)
+(define make-test-main (if (exist? "test-main") #t
+ (string? (getenv "TEST_MAIN")) ))
+
+(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")
+=][=
+
+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.
+
+ This all changes, however, if "make-test-main" is set. It is set if
+ either "test-main" is specified as a program/global attribute, or if
+ the TEST_MAIN environment variable is defined. This should be set
+ if either the program is intended to digest options for an incorporating
+ shell script, or else if the user wants a quick program to show off the
+ usage text and command line parsing. For that environment, all callbacks
+ are disabled except "optionStackArg" for stacked arguments and the
+ keyword set membership options.
+
+ =][=
+
+ 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 make-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" =]
+ */
+[=
+
+ENDDEF option-copyright
+
+# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+Emit usage text =][=
+
+DEFINE usage-text =]
+#define [=
+ (set! tmp-val (string-append (get "usage-type") "-usage"))
+ (define usage-text-name
+ (string->c-name! (string-append pname "_" tmp-val)) )
+ usage-text-name
+
+ =] ([=
+
+ CASE (set! tmp-val (get tmp-val "<<<NOT-FOUND>>>"))
+ tmp-val =][=
+
+ == "<<<NOT-FOUND>>>" =]NULL[=
+
+ == "" =][=
+
+ (out-push-new) =][=
+ INCLUDE "usage.tlib" =][=
+ (string-table-add-ref opt-strs (out-pop #t)) =][=
+
+ ~ "[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. =])
+[=
+
+ENDDEF usage-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)
+ =][=
+
+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-opt-value flag-index) =][=
+ == "'" =]'\''[=
+ == "\\" =]'\\'[=
+ ~~ "[ -~]" =]'[=value=]'[=
+
+ =* num =][=
+ (if (>= number-opt-index 0)
+ (error "only one number option is allowed") )
+ (set! number-opt-index flag-index)
+ (get-opt-value flag-index) =][=
+
+ * =][=(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 WHICH_[=(sprintf "%-18s" opt-name)
+ =] ([=(. descriptor)=].optActualValue)
+#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
+
+=]
+#define [= (. UP-name) =]_DESC ([=
+ (string-table-add-ref opt-strs
+ (string-append "This is an alias for '" (get "aliases") "'")) =])
+#define [= (. UP-name) =]_NAME NULL
+#define [= (. UP-name) =]_name ([=
+ (string-table-add-ref opt-strs (get "name")) =])
+#define [=(. UP-name)=]_FLAGS ([=
+ (get-up-name "aliases") =]_FLAGS | OPTST_ALIAS)[=
+
+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" (shellf
+"${CLexe} -I16 --fill --first='/* TRANSLATORS:' <<\\_EOF_
+%s
+_EOF_" (get "translators") ) " */" ) ) =]
+#define [= (. UP-name) =]_DESC ([=
+ (string-table-add-ref opt-strs (get-text "descrip")) =])
+#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) =]
+#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)) =])
+#define NOT_[= (. UP-name) =]_PFX ([=
+ (string-table-add-ref opt-strs (string-downcase! (get "disable"))) =])
+#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") ""
+ =]
+#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") =]
+#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"))=](void*)([=
+ 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") =]
+static int const a[=(. cap-name)=]MustList[] = {[=
+ FOR flags-must =]
+ [= (index-name "flags-must") =],[=
+ ENDFOR flags_must =] NO_EQUIVALENT };[=
+ ENDIF =][=
+
+
+ IF (exist? "flags-cant") =]
+static int const a[=(. cap-name)=]CantList[] = {[=
+ FOR flags-cant =]
+ [= (index-name "flags-cant") =],[=
+ ENDFOR flags-cant =] NO_EQUIVALENT };[=
+ ENDIF =]
+#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") =]
+#define [= (. UP-name) =]_DESC ([=
+ (string-table-add-ref opt-strs
+ (string-append (get-text "descrip") ":")) =])
+#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") =]
+#define [= (. UP-name) =]_DESC ([=
+ (set! tmp-text (get "omitted-usage"))
+ (if (> (string-length tmp-text) 1)
+ (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 ([=
+ (string-table-add-ref opt-strs
+ "Display extended usage information and exit")=])
+#define HELP_name ([=
+ (string-table-add-ref opt-strs "help")=])[=
+
+ IF (not (exist? "no-libopts"))
+
+=]
+#ifdef HAVE_WORKING_FORK
+#define MORE_HELP_DESC ([=
+ (string-table-add-ref opt-strs
+ "Extended usage information passed thru pager")=])
+#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 NULL
+#define MORE_HELP_name NULL
+#define MORE_HELP_FLAGS (OPTST_OMITTED | OPTST_NO_INIT)
+#endif[=
+
+ ENDIF (not (exist? "no-libopts")) =][=
+
+ IF (exist? "version")
+
+=]
+#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 ([=
+ (string-table-add-ref opt-strs "Output version information and exit")=])
+#define VER_name ([=
+ (string-table-add-ref opt-strs "version")=])[=
+
+ ENDIF (exist? "version") =][=
+
+ IF (exist? "resettable")
+
+=]
+#define RESET_DESC ([=
+ (string-table-add-ref opt-strs "Reset an option's state")=])
+#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 ([=
+ (string-table-add-ref opt-strs "Abbreviated usage to stdout")=])
+#define USAGE_name ([=
+ (string-table-add-ref opt-strs "usage")=])[=
+
+ ENDIF (exist? "usage-opt") =][=
+
+ IF (exist? "vendor-opt")
+
+=]
+#define VEND_DESC ([=
+ (string-table-add-ref opt-strs "vendor supported additional options")=])
+#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 ([=
+ (string-table-add-ref opt-strs "Save the option state to a config file")=])
+#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 ([=
+ (string-table-add-ref opt-strs "Load options from a config file")=])
+#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
+ ;; make-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
+
+optlib.tlib ends here \=]
diff --git a/autoopts/tpl/optmain.tlib b/autoopts/tpl/optmain.tlib
new file mode 100644
index 0000000..13b01de
--- /dev/null
+++ b/autoopts/tpl/optmain.tlib
@@ -0,0 +1,1255 @@
+[= AutoGen5 Template -*- Mode: text -*-
+
+# Time-stamp: "2012-08-11 08:13:56 bkorb"
+
+## This file is part of AutoOpts, a companion to AutoGen.
+## AutoOpts is free software.
+## AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f 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
+
+=][= (tpl-file-line extract-fmt) \=]
+
+#if defined([=(. main-guard)=]) /* TEST MAIN PROCEDURE: */[=
+
+ 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 argc argument count
+ * @param 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);[=
+
+ ELIF (exist? "main-text") =][=
+ IF (not (exist? "option-code")) =]
+ {
+ int ct = optionProcess(&[=(. pname)=]Options, argc, argv);
+ argc -= ct;
+ argv += ct;
+ }[=
+ ELSE =][=
+ (def-file-line "option-code" extract-fmt) =][=
+ option-code =][=
+ ENDIF =][=
+
+ (def-file-line "main-text" extract-fmt) =][=
+ main-text =][=
+
+ ELSE test-main is not optionParseShell and main-text not exist
+
+=]
+ (void)optionProcess(&[=(. pname)=]Options, argc, argv);
+ [= (. option-emitter-proc) =](&[=(. pname)=]Options);
+ res = ferror(stdout);
+ if (res != 0)
+ fputs("output error writing to stdout\n", stderr);[=
+ ENDIF=]
+ return res;
+}
+#endif /* defined [= (. 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)
+
+=]
+/**
+ * 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 pz_s source text pointer
+ * @returns pointer to the same text buffer, but after finding the
+ * first non-white space character.
+ */
+static char *
+trim_input_line(char * pz_s)
+{
+ char* pz_e = pz_s + strlen(pz_s);
+ while ((pz_e > pz_s) && isspace((unsigned int)pz_e[-1])) pz_e--;
+ *pz_e = '\0';
+ while ((unsigned int)isspace(*pz_s)) pz_s++;
+
+ switch (*pz_s) {
+ case '\0':
+ case '[= ?% comment-char "%s" "#" =]':
+ return NULL;
+ default:
+ return pz_s;
+ }
+}[=
+
+CASE handler-type =][=
+=* name =][= (set! handler-arg-type "char const* pz_fname")
+ (define handler-proc "validate_fname") =][=
+=* file =][=
+ (set! handler-arg-type "char const* pz_fname, FILE* entry_fp")
+ (define handler-proc "validate_fname") =][=
+*=* text =][=
+ (set! handler-arg-type
+ "char const* pz_fname, char* pz_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
+
+=][= (tpl-file-line extract-fmt) =][=
+
+IF (exist? "handler-type") =]
+/**
+ * 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 pz_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* pz_fname)
+{
+ static char const * pz_fs_err = NULL;[=
+
+ IF (*=* (get "handler-type") "text") =]
+ char* file_text;
+ size_t text_size;
+ int res;[=
+ ENDIF =]
+
+ if (pz_fs_err == NULL)
+ pz_fs_err = _("fs error %d (%s) %s-ing %s\n");
+
+ {
+ struct stat sb;
+ if (stat(pz_fname, &sb) < 0) {[=
+ IF (. emit-failing-printf) =]
+ fprintf(stderr, pz_fs_err, errno, strerror(errno), "stat",
+ pz_fname);[=
+ ENDIF =]
+ return [= (. file-fail-exit-code) =];
+ }[=
+
+ IF (*=* (get "handler-type") "text") =]
+
+ if (! S_ISREG(sb.st_mode)) {[=
+ IF (. emit-failing-printf) =]
+ fprintf(stderr, pz_fs_err, EINVAL, strerror(EINVAL),
+ "not regular file:", pz_fname);[=
+ ENDIF =]
+ return [= (. file-fail-exit-code) =];
+ }[=
+
+ IF (=* (get "handler-type") "some-text") =]
+
+ if (sb.st_size == 0) {[=
+ IF (. emit-failing-printf) =]
+ fprintf(stderr, pz_fs_err, EINVAL, strerror(EINVAL),
+ "empty file:", pz_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 =](pz_fname);[=
+
+=* file =][= (tpl-file-line extract-fmt) =]
+ {
+ int res;
+ FILE* fp = fopen(pz_fname, "[=
+ (shellf "echo '%s' | sed 's/.*-//'"
+ (get "handler-type")) =]");
+ if (fp == NULL) {
+ fprintf(stderr, pz_fs_err, errno, strerror(errno), "fopen",
+ pz_fname);
+ return [= (. file-fail-exit-code) =];
+ }
+ res = [= handler-proc =](pz_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, pz_fname);
+ exit([=(. nomem-exit-code)=]);
+ }
+
+ {
+ char* pz = file_text;
+ size_t sz = text_size;
+ int fd = open(pz_fname, O_RDONLY);
+ int try_ct = 0;
+
+ if (fd < 0) {
+ fprintf(stderr, pz_fs_err, errno, strerror(errno), "open",
+ pz_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, pz_fs_err, errno, strerror(errno), "read",
+ pz_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 =](pz_fname, file_text, text_size);
+ free(file_text);
+ return res;[=
+ESAC =]
+}[=
+
+ENDIF handler-type exists =][=
+
+(tpl-file-line extract-fmt)
+
+=]
+/**
+ * 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 argc argument count
+ * @param argv argument vector
+ * @returns program exit code
+ */
+int
+main(int argc, char** argv)
+{
+ int res = 0;
+ {
+ int ct = optionProcess(&[=(. pname)=]Options, argc, argv);
+ argc -= ct;
+ argv += ct;
+ }[=
+ (if (exist? "main-init") (string-append
+ "\n " (def-file-line "main-init" extract-fmt) "\n" (get "main-init")))
+
+ =][= (tpl-file-line extract-fmt) =]
+ /*
+ * Input list from command line
+ */
+ if (argc > 0) {
+ do {
+ res |= [= (. handler-proc) =](*(argv++));
+ } while (--argc > 0);
+ }
+
+ /*
+ * 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 {
+ int in_ct = 0;
+ size_t pg_size = getpagesize();
+ char* buf = malloc(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) {
+ res |= [= (. handler-proc) =](pz);
+ in_ct++;
+ }
+ }
+
+ if (in_ct == 0)
+ fputs(_("[=(. prog-name)
+ =] Warning: no input lines were read\n"), stderr);
+ free(buf);
+ }[=
+ (if (exist? "main-fini") (string-append
+ "\n " (def-file-line "main-fini" extract-fmt) "\n" (get "main-fini")))
+ \=]
+
+ return res;
+}[=
+
+ENDDEF for-each-main
+
+# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
+
+ 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 make-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 (. make-test-main) =][=
+ (set! extern-proc-list (string-append extern-proc-list
+ "optionVersionStderr\n")) =][=
+ INVOKE emit-testing-defines =][=
+ ENDIF make-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 make-test-main
+ (ag-fprintf 0 "\n#endif /* defined(%s) */" main-guard) )
+
+ undef-proc-names =][=
+
+ENDDEF decl-callbacks =][=
+
+# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # =][=
+
+DEFINE emit-testing-defines
+
+=]
+#if defined([=(tpl-file-line extract-fmt) 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
+
+=].
+ *
+ * @param pOptions the [=(. prog-name)=] options data structure
+ * @param 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, (void *)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([=(. fail-exit-code)=]);
+[=
+
+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 azNames[[= (. 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, azNames, [=
+ (. 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, azNames, [=(. tmp-ct)=]);[=
+
+ ELSE
+
+=]
+
+ pOptDesc->optArg.argEnum =
+ optionEnumerationVal(pOptions, pOptDesc, azNames, [=(. 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 azNames[%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, azNames, [= (. 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 make-test-main
+ (begin
+ (set! endif-test-main
+ (sprintf "\n#endif /* defined(%s) */" main-guard))
+ (sprintf "\n\n#if ! defined(%s)" main-guard)
+) ) =][=
+
+INVOKE callback-proc-header =][=
+
+IF (out-push-new (string-append tmp-dir "/flag-code"))
+ (exist? "flag-code") =][=
+ (def-file-line "flag-code" " /* extracted from %s, line %d */\n")
+ =][=
+ (join "\n" (stack "flag-code")) =][=
+
+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 pOptions the AutoOpts option description structure
+ * @param pOptDesc the descriptor for the "help" (usage) option.
+ * @noreturn
+ */
+static void
+doUsageOpt(tOptions * pOptions, tOptDesc * pOptDesc)
+{[=
+ IF (exist? "resettable") =]
+ if ((pOptDesc->fOptState & OPTST_RESET) != 0)
+ return;
+[=ENDIF=][=
+ IF (exist? "usage-opt") =]
+ int ex_code = (pOptDesc->optIndex == [= (. INDEX-pfx) =]HELP)
+ ? [=(. succ-exit-code)=] : AO_EXIT_REQ_USAGE;
+ [= (string-append usage-proc "(&" pname "Options, ex_code);") =]
+ /* NOTREACHED */[=
+
+ ELSE =]
+ [= (string-append usage-proc "(&" pname "Options, " succ-exit-code ");") =]
+ /* NOTREACHED */
+ (void)pOptDesc;[=
+ ENDIF =]
+ (void)pOptions;
+}[=
+
+INVOKE define-option-callbacks =][=
+
+IF (exist? "main") =][=
+ INVOKE build-main =][=
+
+ELIF (. make-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
+ */
+void
+[=(. lc-prefix)=]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, " fail-exit-code ");") =]
+ /* NOTREACHED */
+}
+
+/**
+ * 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
+ */
+void
+[=(. lc-prefix)=]usage_message(char const * fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ [=(. lc-prefix)=]vusage_message(fmt, ap);
+ /* NOTREACHED */
+ va_end(ap);
+}
+[=
+
+ENDIF have usage-message =][=
+
+IF (exist? "die-code")
+
+=]
+/**
+ * Print a fatal error message and die
+ *
+ * @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
+ */
+void
+[=(. lc-prefix)=]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);
+ /* NOTREACHED */
+}
+
+/**
+ * Print a fatal error message and die
+ *
+ * @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
+ */
+void
+[=(. lc-prefix)=]die(int exit_code, char const * fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ vdie(exit_code, fmt, ap);
+ /* NOTREACHED */
+ va_end(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
+ */
+void
+[=(. lc-prefix)=]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);
+ /* NOTREACHED */
+}
+[=
+
+ENDIF die-code =][=
+
+ENDDEF emit-option-callbacks
+
+=]
diff --git a/autoopts/tpl/rc-sample.tpl b/autoopts/tpl/rc-sample.tpl
new file mode 100644
index 0000000..f01d506
--- /dev/null
+++ b/autoopts/tpl/rc-sample.tpl
@@ -0,0 +1,126 @@
+[= AutoGen5 Template rc
+
+# Time-stamp: "2011-11-21 04:52:41 bkorb"
+
+## This file is part of AutoOpts, a companion to AutoGen.
+## AutoOpts is free software.
+## AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f 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..f04fd5b
--- /dev/null
+++ b/autoopts/tpl/stdoptions.def
@@ -0,0 +1,345 @@
+
+/* -*- Mode: Text -*-
+ *
+ * Time-stamp: "2013-03-10 07:50:01 bkorb"
+ *
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+ *
+ * 43b91e8ca915626ed3818ffb1b71248b COPYING.gplv3
+ * 06a1a2e4760c90ea5e1dad8dfaac4d39 COPYING.lgplv3
+ * 66a5cedaf62c4b2637025f049f9b826f 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
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * 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/strings.tpl b/autoopts/tpl/strings.tpl
new file mode 100644
index 0000000..725726e
--- /dev/null
+++ b/autoopts/tpl/strings.tpl
@@ -0,0 +1,174 @@
+[= AutoGen5 Template c -*- Mode: scheme -*-
+
+## Time-stamp: "2012-08-11 08:20:07 bkorb"
+## Author: Bruce Korb <bkorb@gnu.org>
+
+## Copyright (C) 2011-2012 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
+## <http://www.xfree86.org/3.3.6/COPYRIGHT2.html>
+##
+## 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 (shellf
+ "year=`sed -n '/Time-stamp[:]/ {
+ s/[^\"]*\"//
+ s/-.*//
+ p
+ q
+ }' %s`
+ test X$year = X2011 || year=2011-$year
+ echo $year" (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..0c20cb5
--- /dev/null
+++ b/autoopts/tpl/texi2man.sh
@@ -0,0 +1,76 @@
+#! /bin/sh
+
+## texi2man.sh -- script to convert texi-isms to man page isms
+##
+## Time-stamp: "2012-05-05 08:13:04 bkorb"
+##
+## This file is part of AutoOpts, a companion to AutoGen.
+## AutoOpts is free software.
+## AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f 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
+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/ -/ \\-/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..6c1325e
--- /dev/null
+++ b/autoopts/tpl/texi2mdoc.sh
@@ -0,0 +1,196 @@
+#! /bin/sh
+
+## texi2mdoc.sh -- script to convert texi-isms to mdoc-isms
+##
+## Time-stamp: "2012-05-13 15:45:06 bkorb"
+##
+## This file is part of AutoOpts, a companion to AutoGen.
+## AutoOpts is free software.
+## AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f 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() {
+ echo "$line" | sed 's/@item/.It/'
+}
+
+do_line() {
+ case "${line}" in
+ '@subheading'* ) echo "$line" | sed 's/@subheading/.SS /' ;;
+ '@*' ) echo .br ;;
+ '' ) echo .sp ;;
+ '@'[{}]* ) echo "${line}" | sed 's/@\([{}]\)/\1/g' ;;
+ '@'* )
+ typ=`echo "$line" | egrep '@[a-z]*\{'`
+ test ${#typ} -gt 0 && echo "$line" && return 0
+ typ=`echo "$line" | sed 's/@ *//;s/[^a-z].*//'`
+ eval do_${typ} || die "do_${typ} failed"
+ ;;
+
+ * )
+ echo "$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
+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..80006dc
--- /dev/null
+++ b/autoopts/tpl/tpl-config-tlib.in
@@ -0,0 +1,84 @@
+[= Autogen5 Template configuration -*- Mode: scheme -*- =]
+[=
+
+# Time-stamp: "2012-05-12 19:42:14 bkorb"
+
+# 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-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f 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-txt.tpl b/autoopts/tpl/usage-txt.tpl
new file mode 100644
index 0000000..fad1a0d
--- /dev/null
+++ b/autoopts/tpl/usage-txt.tpl
@@ -0,0 +1,199 @@
+[= AutoGen5 Template
+
+ h pot
+
+(define time-stamp "2012-02-18 10:10:47")
+
+## This file is part of AutoOpts, a companion to AutoGen.
+## AutoOpts is free software.
+## AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+##
+## 43b91e8ca915626ed3818ffb1b71248b COPYING.gplv3
+## 06a1a2e4760c90ea5e1dad8dfaac4d39 COPYING.lgplv3
+## 66a5cedaf62c4b2637025f049f9b826f COPYING.mbsd
+
+=][= CASE (suffix) =][=
+
+== h =][=
+
+(define ref-list "")
+(define cch-ct 0)
+(dne " * " "/* ") =]
+ *
+ * This file handles all the bookkeeping required for tracking all the little
+ * tiny strings used by the AutoOpts library. There are [= (count "utxt") =]
+ * 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.
+ *
+[= (license-full "lgpl" "AutoOpts" " * " "Bruce Korb" (shell "date +1992-%Y"))
+ =]
+ */
+[=
+(make-header-guard "autoopts")
+=]
+
+#undef cch_t
+#define cch_t char const
+
+/*
+ * One structure to hold all the pointers to all the stringlets.
+ */
+typedef struct {
+ int field_ct;[=
+FOR utxt =][=
+ (if (exist? "ut-type")
+ (emit (sprintf "\n %-9s utpz_%s;"
+ (string-append (get "ut-type") "*")
+ (get "ut-name") ))
+ (set! cch-ct (+ cch-ct 1)) ) =][=
+
+ENDFOR utxt =]
+ cch_t* apz_str[ [= (. cch-ct) =] ];
+} usage_text_t;
+
+/*
+ * Declare the global structure with all the pointers to translated
+ * strings. This is then used by the usage generation procedure.
+ */
+extern usage_text_t option_usage_text;
+
+#if defined(AUTOOPTS_INTERNAL) /* DEFINE ALL THE STRINGS = = = = = */
+/*
+ * Provide a mapping from a short name to fields in this structure.
+ */[=
+
+(string-table-new "usage_txt")
+(define str-ix 0)
+(define const-list "")
+(define typed-list "")
+(set! cch-ct 0) =][=
+
+FOR utxt =]
+#define z[= (sprintf "%-20s" (get "ut-name"))
+ =] (option_usage_text.[=
+
+ IF (exist? "ut-type") =]utpz_[= ut-name =][=
+ (set! typed-list (string-append typed-list "\n" (get "ut-name"))) =][=
+ ELSE
+ =][=
+ (ag-fprintf 0 "apz_str[%3d]" cch-ct)
+ (set! cch-ct (+ 1 cch-ct))
+ =][=
+ ENDIF =])[=
+ENDFOR =]
+
+ /*
+ * 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.
+ */
+[=
+FOR utxt =][=
+ (if (exist? "ut-type")
+ (sprintf "\n static %-7s eng_z%s[] = %s;"
+ (get "ut-type") (get "ut-name") (kr-string (get "ut-text"))
+ )
+
+ (begin
+ (set! str-ix (string-table-add "usage_txt" (get "ut-text")))
+ (set! const-list (string-append const-list
+ (sprintf "usage_txt +%4d\n" str-ix) ))
+ ) )
+ =][=
+ENDFOR utxt =][=
+
+(emit-string-table "usage_txt")
+
+=]
+
+ /*
+ * 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_usage_text = {
+ [= (count "utxt") =],
+[= (shell (string-append
+ "CLexe=${AGexe%/agen5/*}/columns/columns
+ test -x \"${CLexe}\" || {
+ CLexe=${AGexe%/autogen}/columns
+ test -x \"${CLexe}\" || die 'columns program is not findable'
+ }
+ ${CLexe} -W84 -I4 --spread=1 -f'eng_z%s,' <<_EOF_" typed-list
+ "\n_EOF_
+ echo ' {'
+ ${CLexe} -W84 -I6 --spread=1 -S, <<_EOF_\n" const-list
+ "_EOF_" )) =]
+ }
+ };
+
+#endif /* DO_TRANSLATIONS */
+#endif /* [= (. header-guard) =] */
+[=
+
+
+== pot
+
+
+\=]
+# Automated Option parsing usage text.
+# copyright (c) [=`date +1999-%Y`=] by Bruce Korb - all rights reserved
+# This file is distributed under the same license as the AutoOpts package.
+# Bruce Korb <bkorb@gnu.org> [=`date +%Y`=]
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: autogen [=`echo ${AG_VERSION}`=]\n"
+"Report-Msgid-Bugs-To: autogen-users@lists.sourceforge.net\n"
+"POT-Creation-Date: [=`date '+%Y-%m-%d %H:%M%z'`=]\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+[=
+
+FOR utxt
+ =][=
+ (set! ref-list (shellf
+ "list=`grep -n -w z%s *.c [agpo]*.h tpl/opt*.t* | \\
+ sed -n 's/\\([^:]*:[^:]*\\):.*/\\1/p'`
+ echo ${list}" (get "ut-name")))
+
+ (if (< (string-length ref-list) 2)
+ (error (sprintf "No references to z%s string" (get "ut-name"))) )
+
+ (sprintf "\n#: %s\nmsgid %s\n" ref-list (c-string (get "ut-text")))
+
+ =][=
+ENDFOR utxt
+
+=]
+[=
+
+ESAC
+
+# Local Variables:
+# Mode: text
+# time-stamp-format: "\"%:y-%02m-%02d %02H:%02M:%02S\""
+# time-stamp-pattern: "(define time-stamp "
+# time-stamp-end: ")"
+# End:
+
+\=]
diff --git a/autoopts/tpl/usage.tlib b/autoopts/tpl/usage.tlib
new file mode 100644
index 0000000..91bb239
--- /dev/null
+++ b/autoopts/tpl/usage.tlib
@@ -0,0 +1,207 @@
+[= AutoGen5 Template -*- Mode: shell-script -*-
+
+ help-text
+
+# This file is part of AutoGen.
+# AutoGen Copyright (c) 1992-2012 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/>.
+
+=][= INCLUDE "tpl-config.tlib" =][=
+
+ ;; This template is designed to emit help text from the current set
+ ;; of option definitions.
+ ;;
+ (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;
+[=
+
+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 = shell-process; };
+[=
+
+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) \=]
+# redirect stdout. We see this IFF there is a problem
+#
+redirect_log=${tmp_dir}/redirected.log
+exec 8>&1 9>&2 1> ${redirect_log} 2>&1
+redirect_die() {
+ exec 2>&9 1>&9 9>&- 8>&-
+ cat ${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:
+
+test -x "${AGexe}" || redirect_die "AGexe is invalid: ${AGexe}"
+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 [= config-header =]"
+ 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}"
+cd ${tmp_dir}
+${AGexe} -Toptions.tpl [= 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}
+exec 1>&8 2>&9 9>&- 8>&-
+
+${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" "?"))
+ ) ) =] || \
+ die "cannot obtain ${exe} help in ${tmp_dir}"[=
+
+(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..ebdc46a
--- /dev/null
+++ b/autoopts/usage.c
@@ -0,0 +1,1053 @@
+
+/*
+ * \file usage.c
+ *
+ * Time-stamp: "2012-03-31 19:19:26 bkorb"
+ *
+ * This module implements the default usage procedure for
+ * Automated Options. It may be overridden, of course.
+ *
+ * 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-2012 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 md5sums:
+ *
+ * 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+ * 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+ * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
+ */
+
+#define OPTPROC_L_N_S (OPTPROC_LONGOPT | OPTPROC_SHORTOPT)
+
+/* = = = START-STATIC-FORWARD = = = */
+static inline bool
+do_gnu_usage(tOptions * pOpts);
+
+static inline bool
+skip_misuse_usage(tOptions * pOpts);
+
+static void
+print_usage_details(tOptions * opts, int exit_code);
+
+static void
+prt_conflicts(tOptions * pOptions, tOptDesc * pOD);
+
+static void
+prt_one_vendor(tOptions * pOptions, tOptDesc * pOD,
+ arg_types_t * pAT, char const * usefmt);
+
+static void
+prt_vendor_opts(tOptions * pOpts, char const * pOptTitle);
+
+static void
+prt_extd_usage(tOptions * pOpts, tOptDesc * pOD,
+ char const * pOptTitle);
+
+static void
+prt_ini_list(char const * const * papz, bool * pInitIntro,
+ char const * pzRc, char const * pzPN);
+
+static void
+prt_preamble(tOptions * pOptions, tOptDesc * pOD, arg_types_t * pAT);
+
+static void
+prt_one_usage(tOptions * pOptions, tOptDesc * pOD, arg_types_t * pAT);
+
+static void
+prt_opt_usage(tOptions * pOpts, int ex_code, char const * pOptTitle);
+
+static void
+prt_prog_detail(tOptions* pOptions);
+
+static int
+setGnuOptFmts(tOptions* pOpts, tCC** ppT);
+
+static int
+setStdOptFmts(tOptions* pOpts, tCC** ppT);
+/* = = = END-STATIC-FORWARD = = = */
+
+/*
+ * 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 )
+
+LOCAL void
+set_usage_flags(tOptions * opts, char const * flg_txt)
+{
+ typedef struct {
+ size_t fnm_len;
+ uint32_t fnm_mask;
+ char const * fnm_name;
+ } ao_flag_names_t;
+
+# 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_
+
+# define _aof_(_n, _f) { sizeof(#_n)-1, _f, #_n },
+ static ao_flag_names_t const fn_table[AOUF_COUNT] = {
+ AOFLAG_TABLE
+ };
+# undef _aof_
+
+ unsigned int flg = (ao_flags_t)0;
+
+ if (flg_txt == NULL) {
+ flg_txt = getenv("AUTOOPTS_USAGE");
+ if (flg_txt == NULL) return;
+ }
+
+ flg_txt = SPN_WHITESPACE_CHARS(flg_txt);
+ if (*flg_txt == NUL)
+ return;
+
+ for (;;) {
+ int ix = 0;
+ ao_flag_names_t const * fnt = fn_table;
+
+ for (;;) {
+ if (strneqvcmp(flg_txt, fnt->fnm_name, fnt->fnm_len) == 0)
+ break;
+ if (++ix >= AOUF_COUNT)
+ return;
+ fnt++;
+ }
+
+ /*
+ * Make sure we have a full match. Look for whitespace,
+ * a comma, or a NUL byte.
+ */
+ if (! IS_END_LIST_ENTRY_CHAR(flg_txt[fnt->fnm_len]))
+ return;
+
+ flg |= 1 << ix;
+ flg_txt = SPN_WHITESPACE_CHARS(flg_txt + fnt->fnm_len);
+
+ if (*flg_txt == NUL)
+ break;
+
+ if (*flg_txt == ',') {
+ /*
+ * skip the comma and following white space
+ */
+ flg_txt = SPN_WHITESPACE_CHARS(flg_txt + 1);
+ if (*flg_txt == NUL)
+ break;
+ }
+ }
+
+ {
+ ao_flag_names_t const * fnm = fn_table;
+
+ while (flg != 0) {
+ if ((flg & 1) != 0) {
+ if ((fnm->fnm_mask & OPTPROC_LONGOPT) != 0)
+ opts->fOptSet &= fnm->fnm_mask;
+ else opts->fOptSet |= fnm->fnm_mask;
+ }
+ flg >>= 1;
+ 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) {
+ fputs(zOutputFail, stderr);
+ exit(EXIT_FAILURE);
+ }
+}
+
+static void
+print_usage_details(tOptions * opts, int exit_code)
+{
+ {
+ char const * pOptTitle = NULL;
+
+ /*
+ * Determine which header and which option formatting strings to use
+ */
+ if (do_gnu_usage(opts)) {
+ int flen = setGnuOptFmts(opts, &pOptTitle);
+ sprintf(line_fmt_buf, zFmtFmt, flen);
+ fputc(NL, option_usage_fp);
+ }
+ else {
+ int 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);
+ }
+
+ 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) {
+ fputs(zOutputFail, stderr);
+ exit(EXIT_FAILURE);
+ }
+}
+
+
+/*=export_func optionUsage
+ * private:
+ *
+ * what: Print usage text
+ * arg: + tOptions* + pOptions + 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".
+=*/
+void
+optionUsage(tOptions * pOptions, int usage_exit_code)
+{
+ int exit_code = (usage_exit_code == AO_EXIT_REQ_USAGE)
+ ? EXIT_SUCCESS : usage_exit_code;
+
+ displayEnum = false;
+
+ /*
+ * 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 = (pOptions->structVersion >= 30 * 4096)
+ ? pOptions->pzFullUsage : NULL;
+
+ if (option_usage_fp == NULL)
+ option_usage_fp = stdout;
+ } else {
+ pz = (pOptions->structVersion >= 30 * 4096)
+ ? pOptions->pzShortUsage : NULL;
+
+ if (option_usage_fp == NULL)
+ option_usage_fp = stderr;
+ }
+
+ if (pz != NULL) {
+ fputs(pz, option_usage_fp);
+ exit(exit_code);
+ }
+ }
+
+ fprintf(option_usage_fp, pOptions->pzUsageTitle, pOptions->pzProgName);
+ set_usage_flags(pOptions, NULL);
+
+ if ((exit_code == EXIT_SUCCESS) ||
+ (! skip_misuse_usage(pOptions)))
+
+ print_usage_details(pOptions, usage_exit_code);
+
+ exit(exit_code);
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * PER OPTION TYPE USAGE INFORMATION
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/**
+ * print option conflicts.
+ *
+ * @param pOptions the program option descriptor
+ * @param pOD the option descriptor
+ * @param pAT names of the option argument types
+ */
+static void
+prt_conflicts(tOptions * pOptions, tOptDesc * pOD)
+{
+
+ fputs(zTabHyp, option_usage_fp);
+
+ /*
+ * REQUIRED:
+ */
+ if (pOD->pOptMust != NULL) {
+ const int* pOptNo = pOD->pOptMust;
+
+ fputs(zReqThese, option_usage_fp);
+ for (;;) {
+ fprintf(option_usage_fp, zTabout,
+ pOptions->pOptDesc[*pOptNo].pz_Name);
+ if (*++pOptNo == NO_EQUIVALENT)
+ break;
+ }
+
+ if (pOD->pOptCant != NULL)
+ fputs(zTabHypAnd, option_usage_fp);
+ }
+
+ /*
+ * CONFLICTS:
+ */
+ if (pOD->pOptCant != NULL) {
+ const int* pOptNo = pOD->pOptCant;
+
+ fputs(zProhib, option_usage_fp);
+ for (;;) {
+ fprintf(option_usage_fp, zTabout,
+ pOptions->pOptDesc[*pOptNo].pz_Name);
+ if (*++pOptNo == NO_EQUIVALENT)
+ break;
+ }
+ }
+}
+
+/**
+ * Print the usage information for a single vendor option.
+ *
+ * @param pOpts the program option descriptor
+ * @param pOD the option descriptor
+ * @param pAT names of the option argument types
+ */
+static void
+prt_one_vendor(tOptions * pOptions, tOptDesc * pOD,
+ arg_types_t * pAT, char const * usefmt)
+{
+ prt_preamble(pOptions, pOD, pAT);
+
+ {
+ 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 (pOD->fOptState & OPTST_ARG_OPTIONAL) {
+ pzArgType = pAT->pzOpt;
+
+ } else switch (OPTST_GET_ARGTYPE(pOD->fOptState)) {
+ case OPARG_TYPE_NONE: pzArgType = pAT->pzNo; break;
+ case OPARG_TYPE_ENUMERATION: pzArgType = pAT->pzKey; break;
+ case OPARG_TYPE_FILE: pzArgType = pAT->pzFile; break;
+ case OPARG_TYPE_MEMBERSHIP: pzArgType = pAT->pzKeyL; break;
+ case OPARG_TYPE_BOOLEAN: pzArgType = pAT->pzBool; break;
+ case OPARG_TYPE_NUMERIC: pzArgType = pAT->pzNum; break;
+ case OPARG_TYPE_HIERARCHY: pzArgType = pAT->pzNest; break;
+ case OPARG_TYPE_STRING: pzArgType = pAT->pzStr; break;
+ case OPARG_TYPE_TIME: pzArgType = pAT->pzTime; break;
+ default: goto bogus_desc;
+ }
+
+ pzArgType = SPN_WHITESPACE_CHARS(pzArgType);
+ if (*pzArgType == NUL)
+ snprintf(z, sizeof(z), "%s", pOD->pz_Name);
+ else
+ snprintf(z, sizeof(z), "%s=%s", pOD->pz_Name, pzArgType);
+ fprintf(option_usage_fp, usefmt, z, pOD->pzText);
+
+ switch (OPTST_GET_ARGTYPE(pOD->fOptState)) {
+ case OPARG_TYPE_ENUMERATION:
+ case OPARG_TYPE_MEMBERSHIP:
+ displayEnum = (pOD->pOptProc != NULL) ? true : displayEnum;
+ }
+ }
+
+ return;
+
+bogus_desc:
+ fprintf(stderr, zInvalOptDesc, pOD->pz_Name);
+ exit(EX_SOFTWARE);
+}
+
+/**
+ * Print the long options processed with "-W". These options will be the
+ * ones that do *not* have flag characters.
+ *
+ * @param pOptions the program option descriptor
+ * @param pOD the option descriptor
+ */
+static void
+prt_vendor_opts(tOptions * pOpts, char const * pOptTitle)
+{
+ 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 = pOpts->presetOptCt;
+ tOptDesc * pOD = pOpts->pOptDesc;
+ size_t nmlen = 0;
+
+ fprintf(option_usage_fp, zTabout, zVendOptsAre);
+
+ do {
+ size_t l;
+ if ( ((pOD->fOptState & not_vended_mask) != 0)
+ || IS_GRAPHIC_CHAR(pOD->optValue))
+ continue;
+
+ l = strlen(pOD->pz_Name);
+ if (l > nmlen) nmlen = l;
+ } while (pOD++, (--ct > 0));
+
+ sprintf(vfmt, vfmtfmt, (unsigned int)nmlen + 4);
+ ct = pOpts->presetOptCt;
+ pOD = pOpts->pOptDesc;
+
+ do {
+ if ( ((pOD->fOptState & not_vended_mask) != 0)
+ || IS_GRAPHIC_CHAR(pOD->optValue))
+ continue;
+
+ prt_one_vendor(pOpts, pOD, &argTypes, vfmt);
+ prt_extd_usage(pOpts, pOD, pOptTitle);
+
+ } while (pOD++, (--ct > 0));
+}
+
+/**
+ * Print extended usage. Usage/help was requested.
+ *
+ * @param pOptions the program option descriptor
+ * @param pOD the option descriptor
+ * @param pAT names of the option argument types
+ */
+static void
+prt_extd_usage(tOptions * pOpts, tOptDesc * pOD,
+ char const * pOptTitle)
+{
+ if ( ((pOpts->fOptSet & OPTPROC_VENDOR_OPT) != 0)
+ && (pOD->optActualValue == VENDOR_OPTION_VALUE)) {
+ prt_vendor_opts(pOpts, pOptTitle);
+ return;
+ }
+
+ /*
+ * IF there are option conflicts or dependencies,
+ * THEN print them here.
+ */
+ if ( (pOD->pOptMust != NULL)
+ || (pOD->pOptCant != NULL) )
+ prt_conflicts(pOpts, pOD);
+
+ /*
+ * IF there is a disablement string
+ * THEN print the disablement info
+ */
+ if (pOD->pz_DisableName != NULL )
+ fprintf(option_usage_fp, zDis, pOD->pz_DisableName);
+
+ /*
+ * Check for argument types that have callbacks with magical properties
+ */
+ switch (OPTST_GET_ARGTYPE(pOD->fOptState)) {
+ case OPARG_TYPE_NUMERIC:
+ /*
+ * IF the numeric option has a special callback,
+ * THEN call it, requesting the range or other special info
+ */
+ if ( (pOD->pOptProc != NULL)
+ && (pOD->pOptProc != optionNumericVal) ) {
+ (*(pOD->pOptProc))(OPTPROC_EMIT_USAGE, pOD);
+ }
+ break;
+
+ case OPARG_TYPE_FILE:
+ (*(pOD->pOptProc))(OPTPROC_EMIT_USAGE, pOD);
+ break;
+ }
+
+ /*
+ * IF the option defaults to being enabled,
+ * THEN print that out
+ */
+ if (pOD->fOptState & OPTST_INITENABLED)
+ fputs(zEnab, 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 ( (pOD->optEquivIndex != NO_EQUIVALENT)
+ && (pOD->optEquivIndex != pOD->optActualIndex ) ) {
+ fprintf(option_usage_fp, zAlt,
+ pOpts->pOptDesc[ pOD->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 ( ((pOD->fOptState & OPTST_NO_INIT) != 0)
+ && ( (pOpts->papzHomeList != NULL)
+ || (pOpts->pzPROGNAME != NULL)
+ )
+ && (pOD->optIndex < pOpts->presetOptCt)
+ )
+
+ fputs(zNoPreset, option_usage_fp);
+
+ /*
+ * Print the appearance requirements.
+ */
+ if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_MEMBERSHIP)
+ fputs(zMembers, option_usage_fp);
+
+ else switch (pOD->optMinCt) {
+ case 1:
+ case 0:
+ switch (pOD->optMaxCt) {
+ case 0: fputs(zPreset, option_usage_fp); break;
+ case NOLIMIT: fputs(zNoLim, 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, pOD->optMaxCt); break;
+ }
+ break;
+
+ default:
+ /*
+ * More than one is required. Print the range.
+ */
+ fprintf(option_usage_fp, zMust, pOD->optMinCt, pOD->optMaxCt);
+ }
+
+ if ( NAMED_OPTS(pOpts)
+ && (pOpts->specOptIdx.default_opt == pOD->optIndex))
+ fputs(zDefaultOpt, 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.
+ */
+static void
+prt_ini_list(char const * const * papz, bool * pInitIntro,
+ char const * pzRc, char const * pzPN)
+{
+ char zPath[AG_PATH_MAX+1];
+
+ if (papz == NULL)
+ return;
+
+ fputs(zPresetIntro, option_usage_fp);
+ *pInitIntro = false;
+
+ for (;;) {
+ char const * pzPath = *(papz++);
+ char const * pzReal = zPath;
+
+ if (pzPath == NULL)
+ break;
+
+ /*
+ * Ignore any invalid paths
+ */
+ if (! optionMakePath(zPath, (int)sizeof(zPath), pzPath, pzPN))
+ pzReal = pzPath;
+
+ /*
+ * Expand paths that are relative to the executable or installation
+ * directories. Leave alone paths that use environment variables.
+ */
+ else if ((*pzPath == '$')
+ && ((pzPath[1] == '$') || (pzPath[1] == '@')))
+ pzPath = pzReal;
+
+ /*
+ * 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, pzPath);
+ if (*pzRc != NUL) {
+ struct stat sb;
+
+ /*
+ * IF the "homerc" file is a directory,
+ * then append the "rcfile" name.
+ */
+ if ((stat(pzReal, &sb) == 0) && S_ISDIR(sb.st_mode)) {
+ fputc(DIRCH, option_usage_fp);
+ fputs(pzRc, option_usage_fp);
+ }
+ }
+
+ fputc(NL, option_usage_fp);
+ }
+}
+
+
+static void
+prt_preamble(tOptions * pOptions, tOptDesc * pOD, arg_types_t * pAT)
+{
+ /*
+ * 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 ((pOptions->fOptSet & OPTPROC_SHORTOPT) == 0)
+ fputs(pAT->pzSpc, option_usage_fp);
+
+ else if (! IS_GRAPHIC_CHAR(pOD->optValue)) {
+ if ( (pOptions->fOptSet & (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT))
+ == (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT))
+ fputc(' ', option_usage_fp);
+ fputs(pAT->pzNoF, option_usage_fp);
+
+ } else {
+ fprintf(option_usage_fp, " -%c", pOD->optValue);
+ if ( (pOptions->fOptSet & (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT))
+ == (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT))
+ fputs(", ", option_usage_fp);
+ }
+}
+
+/**
+ * Print the usage information for a single option.
+ *
+ * @param pOpts the program option descriptor
+ * @param pOD the option descriptor
+ * @param pAT names of the option argument types
+ */
+static void
+prt_one_usage(tOptions * pOptions, tOptDesc * pOD, arg_types_t * pAT)
+{
+ prt_preamble(pOptions, pOD, pAT);
+
+ {
+ 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 (pOD->fOptState & OPTST_ARG_OPTIONAL) {
+ pzArgType = pAT->pzOpt;
+
+ } else switch (OPTST_GET_ARGTYPE(pOD->fOptState)) {
+ case OPARG_TYPE_NONE: pzArgType = pAT->pzNo; break;
+ case OPARG_TYPE_ENUMERATION: pzArgType = pAT->pzKey; break;
+ case OPARG_TYPE_FILE: pzArgType = pAT->pzFile; break;
+ case OPARG_TYPE_MEMBERSHIP: pzArgType = pAT->pzKeyL; break;
+ case OPARG_TYPE_BOOLEAN: pzArgType = pAT->pzBool; break;
+ case OPARG_TYPE_NUMERIC: pzArgType = pAT->pzNum; break;
+ case OPARG_TYPE_HIERARCHY: pzArgType = pAT->pzNest; break;
+ case OPARG_TYPE_STRING: pzArgType = pAT->pzStr; break;
+ case OPARG_TYPE_TIME: pzArgType = pAT->pzTime; break;
+ default: goto bogus_desc;
+ }
+
+ snprintf(z, sizeof(z), pAT->pzOptFmt, pzArgType, pOD->pz_Name,
+ (pOD->optMinCt != 0) ? pAT->pzReq : pAT->pzOpt);
+
+ fprintf(option_usage_fp, line_fmt_buf, z, pOD->pzText);
+
+ switch (OPTST_GET_ARGTYPE(pOD->fOptState)) {
+ case OPARG_TYPE_ENUMERATION:
+ case OPARG_TYPE_MEMBERSHIP:
+ displayEnum = (pOD->pOptProc != NULL) ? true : displayEnum;
+ }
+ }
+
+ return;
+
+bogus_desc:
+ fprintf(stderr, zInvalOptDesc, pOD->pz_Name);
+ exit(EX_SOFTWARE);
+}
+
+/*
+ * Print out the usage information for just the options.
+ */
+static void
+prt_opt_usage(tOptions * pOpts, int ex_code, char const * pOptTitle)
+{
+ int ct = pOpts->optCt;
+ int optNo = 0;
+ tOptDesc * pOD = pOpts->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 ((pOD->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 ( (pOD->fOptState == (OPTST_OMITTED | OPTST_NO_INIT))
+ && (pOD->pz_Name != NULL)
+ && (ex_code == EXIT_SUCCESS)) {
+
+ char const * why_pz =
+ (pOD->pzText == NULL) ? zDisabledWhy : pOD->pzText;
+ prt_preamble(pOpts, pOD, &argTypes);
+ fprintf(option_usage_fp, zDisabledOpt, pOD->pz_Name, why_pz);
+ }
+
+ continue;
+ }
+
+ if ((pOD->fOptState & OPTST_DOCUMENT) != 0) {
+ if (ex_code == EXIT_SUCCESS) {
+ fprintf(option_usage_fp, argTypes.pzBrk, pOD->pzText,
+ pOptTitle);
+ docCt++;
+ }
+
+ continue;
+ }
+
+ /* Skip name only options when we have a vendor option */
+ if ( ((pOpts->fOptSet & OPTPROC_VENDOR_OPT) != 0)
+ && (! IS_GRAPHIC_CHAR(pOD->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 (pOpts->presetOptCt == optNo) {
+ if ((pOD[-1].fOptState & OPTST_DOCUMENT) == 0)
+ fprintf(option_usage_fp, argTypes.pzBrk, zAuto, pOptTitle);
+
+ } else if ((ct == 1) &&
+ (pOpts->fOptSet & OPTPROC_VENDOR_OPT))
+ fprintf(option_usage_fp, argTypes.pzBrk, zVendIntro, pOptTitle);
+ }
+
+ prt_one_usage(pOpts, pOD, &argTypes);
+
+ /*
+ * IF we were invoked because of the --help option,
+ * THEN print all the extra info
+ */
+ if (ex_code == EXIT_SUCCESS)
+ prt_extd_usage(pOpts, pOD, pOptTitle);
+
+ } while (pOD++, optNo++, (--ct > 0));
+
+ fputc(NL, option_usage_fp);
+}
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * PROGRAM DETAILS
+ */
+static void
+prt_prog_detail(tOptions* pOptions)
+{
+ bool initIntro = true;
+
+ /*
+ * Display all the places we look for config files
+ */
+ prt_ini_list(pOptions->papzHomeList, &initIntro,
+ pOptions->pzRcName, pOptions->pzProgPath);
+
+ /*
+ * Let the user know about environment variable settings
+ */
+ if ((pOptions->fOptSet & OPTPROC_ENVIRON) != 0) {
+ if (initIntro)
+ fputs(zPresetIntro, option_usage_fp);
+
+ fprintf(option_usage_fp, zExamineFmt, pOptions->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 = pOptions->optCt;
+ int optNo = 0;
+ tOptDesc* pOD = pOptions->pOptDesc;
+
+ fputc(NL, option_usage_fp);
+ fflush(option_usage_fp);
+ do {
+ switch (OPTST_GET_ARGTYPE(pOD->fOptState)) {
+ case OPARG_TYPE_ENUMERATION:
+ case OPARG_TYPE_MEMBERSHIP:
+ (*(pOD->pOptProc))(OPTPROC_EMIT_USAGE, pOD);
+ }
+ } while (pOD++, optNo++, (--ct > 0));
+ }
+
+ /*
+ * If there is a detail string, now is the time for that.
+ */
+ if (pOptions->pzDetail != NULL)
+ fputs(pOptions->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* pOpts, tCC** ppT)
+{
+ static char const zOneSpace[] = " ";
+ int flen = 22;
+ *ppT = 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 (pOpts->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* pOpts, tCC** ppT)
+{
+ 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 (pOpts->fOptSet & (OPTPROC_NO_REQ_OPT | OPTPROC_SHORTOPT)) {
+ case (OPTPROC_NO_REQ_OPT | OPTPROC_SHORTOPT):
+ *ppT = zNoRq_ShrtTtl;
+ argTypes.pzOptFmt = zNrmOptFmt;
+ flen = 19;
+ break;
+
+ case OPTPROC_NO_REQ_OPT:
+ *ppT = zNoRq_NoShrtTtl;
+ argTypes.pzOptFmt = zNrmOptFmt;
+ flen = 19;
+ break;
+
+ case OPTPROC_SHORTOPT:
+ *ppT = zReq_ShrtTtl;
+ argTypes.pzOptFmt = zReqOptFmt;
+ flen = 24;
+ break;
+
+ case 0:
+ *ppT = 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/value-type.c b/autoopts/value-type.c
new file mode 100644
index 0000000..ff98c0a
--- /dev/null
+++ b/autoopts/value-type.c
@@ -0,0 +1,123 @@
+/* ANSI-C code produced by gperf version 3.0.4 */
+
+
+#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 value_type_hash
+// %define lookup-function-name find_value_type_name
+// %define word-array-name value_type_table
+// %define initializer-suffix ,VTP_COUNT_KWD
+#endif /* gperf build options: */
+
+#include "value-type.h"
+
+typedef struct {
+ char const * vtp_name;
+ value_type_enum_t vtp_id;
+} value_type_map_t;
+#include <string.h>
+
+/* maximum key range = 20, duplicates = 0 */
+
+#ifdef __GNUC__
+#else
+#ifdef __cplusplus
+#endif
+#endif
+inline static unsigned int
+value_type_hash (register const char *str, register unsigned int len)
+{
+ static const unsigned char asso_values[] =
+ {
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 10, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 5, 23, 23, 5, 0, 0, 23, 15, 23,
+ 23, 10, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23
+ };
+ return len + asso_values[(unsigned char)str[2]];
+}
+
+static const value_type_map_t value_type_table[] =
+ {
+ {"",VTP_COUNT_KWD}, {"",VTP_COUNT_KWD},
+ {"",VTP_COUNT_KWD},
+ {"set", VTP_KWD_SET},
+ {"",VTP_COUNT_KWD}, {"",VTP_COUNT_KWD},
+ {"nested", VTP_KWD_NESTED},
+ {"integer", VTP_KWD_INTEGER},
+ {"",VTP_COUNT_KWD},
+ {"bool", VTP_KWD_BOOL},
+ {"",VTP_COUNT_KWD},
+ {"string", VTP_KWD_STRING},
+ {"boolean", VTP_KWD_BOOLEAN},
+ {"",VTP_COUNT_KWD},
+ {"set-membership", VTP_KWD_SET_MEMBERSHIP},
+ {"",VTP_COUNT_KWD}, {"",VTP_COUNT_KWD},
+ {"keyword", VTP_KWD_KEYWORD},
+ {"",VTP_COUNT_KWD},
+ {"hierarchy", VTP_KWD_HIERARCHY},
+ {"",VTP_COUNT_KWD}, {"",VTP_COUNT_KWD},
+ {"invalid", VTP_KWD_INVALID}
+ };
+
+#ifdef __GNUC__
+#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
+__attribute__ ((__gnu_inline__))
+#endif
+#endif
+static inline const value_type_map_t *
+find_value_type_name (register const char *str, register unsigned int len)
+{
+ if (len <= 14 && len >= 3)
+ {
+ register int key = value_type_hash (str, len);
+
+ if (key <= 22 && key >= 0)
+ {
+ register const char *s = value_type_table[key].vtp_name;
+
+ if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0')
+ return &value_type_table[key];
+ }
+ }
+ return 0;
+}
+
+
+value_type_enum_t
+find_value_type_id(char const * str, unsigned int len)
+{
+ const value_type_map_t * p =
+ find_value_type_name(str, len);
+ return (p == 0) ? VTP_KWD_INVALID : p->vtp_id;
+}
diff --git a/autoopts/value-type.h b/autoopts/value-type.h
new file mode 100644
index 0000000..70ff91a
--- /dev/null
+++ b/autoopts/value-type.h
@@ -0,0 +1,25 @@
+/*
+ * Generated header for gperf generated source Sat Aug 11 09:41:14 PDT 2012
+ * This file enumerates the list of names and declares the
+ * procedure for mapping string names to the enum value.
+ */
+#ifndef AUTOOPTS_VALUE_TYPE_H_GUARD
+#define AUTOOPTS_VALUE_TYPE_H_GUARD 1
+
+typedef enum {
+ VTP_KWD_INVALID,
+ VTP_KWD_STRING,
+ VTP_KWD_INTEGER,
+ VTP_KWD_BOOLEAN,
+ VTP_KWD_BOOL,
+ VTP_KWD_KEYWORD,
+ VTP_KWD_SET,
+ VTP_KWD_SET_MEMBERSHIP,
+ VTP_KWD_NESTED,
+ VTP_KWD_HIERARCHY,
+ VTP_COUNT_KWD
+} value_type_enum_t;
+
+extern value_type_enum_t
+find_value_type_id(char const * str, unsigned int len);
+#endif /* AUTOOPTS_VALUE_TYPE_H_GUARD */
diff --git a/autoopts/version.c b/autoopts/version.c
new file mode 100644
index 0000000..e91d4ec
--- /dev/null
+++ b/autoopts/version.c
@@ -0,0 +1,214 @@
+
+/*
+ * Time-stamp: "2012-08-11 08:41:53 bkorb"
+ *
+ * This module implements the default usage procedure for
+ * Automated Options. It may be overridden, of course.
+ */
+
+/*
+ * This file is part of AutoOpts, a companion to AutoGen.
+ * AutoOpts is free software.
+ * AutoOpts is Copyright (c) 1992-2012 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 md5sums:
+ *
+ * 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
+ * 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
+ * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/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 zVersion[] =
+ STR(AO_CURRENT.AO_REVISION);
+
+ return zVersion;
+}
+
+/**
+ * Select among various ways to emit version information.
+ *
+ * @param opts the option descriptor
+ * @param fp the output stream
+ */
+static void
+emit_simple_ver(tOptions * opts, FILE * fp)
+{
+ /*
+ * Use the supplied string
+ */
+ if (opts->pzFullVersion != NULL)
+ fputs(opts->pzFullVersion, fp);
+
+ /*
+ * Extract the interesting part of the copyright string
+ */
+ else if (opts->pzCopyright != NULL) {
+ char const * pe = strchr(opts->pzCopyright, NL);
+ if (pe == NULL)
+ pe = opts->pzCopyright + strlen(opts->pzCopyright);
+ fwrite(opts->pzCopyright, 1, pe - opts->pzCopyright, fp);
+ }
+
+ /*
+ * Extract the interesting part of the usage title string
+ */
+ else {
+ char const * pe = strchr(opts->pzUsageTitle, NL);
+ if (pe == NULL)
+ pe = opts->pzUsageTitle + strlen(opts->pzUsageTitle);
+ fwrite(opts->pzUsageTitle, 1, pe - opts->pzUsageTitle, fp);
+ }
+ fputc(NL, fp);
+}
+
+static void
+emit_copy_ver(tOptions * opts, FILE * fp)
+{
+ if (opts->pzCopyright != NULL)
+ fputs(opts->pzCopyright, fp);
+
+ else if (opts->pzFullVersion != NULL)
+ fputs(opts->pzFullVersion, fp);
+
+ else {
+ char const * pe = strchr(opts->pzUsageTitle, NL);
+ if (pe == NULL)
+ pe = opts->pzUsageTitle + strlen(opts->pzUsageTitle);
+ fwrite(opts->pzUsageTitle, 1, pe - opts->pzCopyright, fp);
+ }
+
+ fputc(NL, fp);
+
+ if (HAS_pzPkgDataDir(opts) && (opts->pzPackager != NULL))
+ fputs(opts->pzPackager, fp);
+
+ else if (opts->pzBugAddr != NULL)
+ fprintf(fp, zPlsSendBugs, opts->pzBugAddr);
+}
+
+static void
+emit_copy_note(tOptions * opts, FILE * fp)
+{
+ if (opts->pzCopyright != NULL) {
+ fputs(opts->pzCopyright, fp);
+ fputc(NL, fp);
+ }
+
+ if (opts->pzCopyNotice != NULL) {
+ fputs(opts->pzCopyNotice, fp);
+ fputc(NL, fp);
+ }
+
+ fprintf(fp, zAO_Ver, optionVersion());
+
+ if (HAS_pzPkgDataDir(opts) && (opts->pzPackager != NULL))
+ fputs(opts->pzPackager, fp);
+
+ else if (opts->pzBugAddr != NULL)
+ fprintf(fp, zPlsSendBugs, opts->pzBugAddr);
+}
+
+static void
+print_ver(tOptions * opts, tOptDesc * od, FILE * fp)
+{
+ 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 {
+ 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_ver( opts, fp); break;
+ case 'n': case 'N': emit_copy_note( opts, fp); break;
+
+ default:
+ fprintf(stderr, zBadVerArg, ch);
+ exit(EXIT_FAILURE);
+ }
+
+ fflush(fp);
+ if (ferror(fp) != 0) {
+ fputs(zOutputFail, stderr);
+ exit(EXIT_FAILURE);
+ }
+ exit(EXIT_SUCCESS);
+}
+
+/*=export_func optionPrintVersion
+ * private:
+ *
+ * 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, stdout);
+}
+
+/*=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);
+}
+
+/*
+ * Local Variables:
+ * mode: C
+ * c-file-style: "stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * end of autoopts/version.c */
diff --git a/autoopts/xat-attribute.c b/autoopts/xat-attribute.c
new file mode 100644
index 0000000..db47531
--- /dev/null
+++ b/autoopts/xat-attribute.c
@@ -0,0 +1,114 @@
+/* ANSI-C code produced by gperf version 3.0.4 */
+
+
+#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 xat_attribute_hash
+// %define lookup-function-name find_xat_attribute_name
+// %define word-array-name xat_attribute_table
+// %define initializer-suffix ,XAT_COUNT_KWD
+#endif /* gperf build options: */
+
+#include "xat-attribute.h"
+
+typedef struct {
+ char const * xat_name;
+ xat_attribute_enum_t xat_id;
+} xat_attribute_map_t;
+#include <string.h>
+
+/* maximum key range = 9, duplicates = 0 */
+
+#ifdef __GNUC__
+#else
+#ifdef __cplusplus
+#endif
+#endif
+inline static unsigned int
+xat_attribute_hash (register const char *str, register unsigned int len)
+{
+ static const unsigned char asso_values[] =
+ {
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 0,
+ 13, 13, 13, 13, 13, 5, 13, 5, 13, 0,
+ 13, 13, 13, 13, 13, 13, 0, 0, 13, 0,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13
+ };
+ return len + asso_values[(unsigned char)str[0]];
+}
+
+static const xat_attribute_map_t xat_attribute_table[] =
+ {
+ {"",XAT_COUNT_KWD}, {"",XAT_COUNT_KWD},
+ {"",XAT_COUNT_KWD}, {"",XAT_COUNT_KWD},
+ {"type", XAT_KWD_TYPE},
+ {"words", XAT_KWD_WORDS},
+ {"cooked", XAT_KWD_COOKED},
+ {"members", XAT_KWD_MEMBERS},
+ {"uncooked", XAT_KWD_UNCOOKED},
+ {"keep", XAT_KWD_KEEP},
+ {"",XAT_COUNT_KWD}, {"",XAT_COUNT_KWD},
+ {"invalid", XAT_KWD_INVALID}
+ };
+
+#ifdef __GNUC__
+#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
+__attribute__ ((__gnu_inline__))
+#endif
+#endif
+static inline const xat_attribute_map_t *
+find_xat_attribute_name (register const char *str, register unsigned int len)
+{
+ if (len <= 8 && len >= 4)
+ {
+ register int key = xat_attribute_hash (str, len);
+
+ if (key <= 12 && key >= 0)
+ {
+ register const char *s = xat_attribute_table[key].xat_name;
+
+ if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0')
+ return &xat_attribute_table[key];
+ }
+ }
+ return 0;
+}
+
+
+xat_attribute_enum_t
+find_xat_attribute_id(char const * str, unsigned int len)
+{
+ const xat_attribute_map_t * p =
+ find_xat_attribute_name(str, len);
+ return (p == 0) ? XAT_KWD_INVALID : p->xat_id;
+}
diff --git a/autoopts/xat-attribute.h b/autoopts/xat-attribute.h
new file mode 100644
index 0000000..ac9b595
--- /dev/null
+++ b/autoopts/xat-attribute.h
@@ -0,0 +1,22 @@
+/*
+ * Generated header for gperf generated source Sat Aug 11 09:41:14 PDT 2012
+ * This file enumerates the list of names and declares the
+ * procedure for mapping string names to the enum value.
+ */
+#ifndef AUTOOPTS_XAT_ATTRIBUTE_H_GUARD
+#define AUTOOPTS_XAT_ATTRIBUTE_H_GUARD 1
+
+typedef enum {
+ XAT_KWD_INVALID,
+ XAT_KWD_TYPE,
+ XAT_KWD_WORDS,
+ XAT_KWD_MEMBERS,
+ XAT_KWD_COOKED,
+ XAT_KWD_UNCOOKED,
+ XAT_KWD_KEEP,
+ XAT_COUNT_KWD
+} xat_attribute_enum_t;
+
+extern xat_attribute_enum_t
+find_xat_attribute_id(char const * str, unsigned int len);
+#endif /* AUTOOPTS_XAT_ATTRIBUTE_H_GUARD */