summaryrefslogtreecommitdiff
path: root/doc/auto-opts.tpl
diff options
context:
space:
mode:
Diffstat (limited to 'doc/auto-opts.tpl')
-rw-r--r--doc/auto-opts.tpl473
1 files changed, 473 insertions, 0 deletions
diff --git a/doc/auto-opts.tpl b/doc/auto-opts.tpl
new file mode 100644
index 0000000..79db885
--- /dev/null
+++ b/doc/auto-opts.tpl
@@ -0,0 +1,473 @@
+[= -*- Mode: texinfo -*-
+
+ AutoGen5 Template
+
+# 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/>.
+
+=]
+@page
+@node AutoOpts
+@chapter Automated Option Processing
+@cindex autoopts
+
+AutoOpts [=
+(make-tmp-dir)
+(out-push-new)
+=]
+test ${#AGexe} -eq 0 -o ${#top_srcdir} -eq 0 -o ${top_builddir} -eq 0 && \
+ die "AGexe, top_srcdir and top_builddir must be set"
+ag_cmd="${AGexe} -L${top_srcdir}/autoopts/tpl"
+test "X${top_srcdir}" = "X${top_builddir}" || \
+ ag_cmd="${ag_cmd} -L${top_builddir}/autoopts/tpl"
+readonly ag_cmd
+
+run_ag() {
+ echo ${ag_cmd} "$@" >&2
+ ${ag_cmd} "$@"
+}
+
+eval "`egrep '^AO_[A-Z]*=' ${top_srcdir}/VERSION`" 2> /dev/null
+echo ${AO_CURRENT}.${AO_REVISION}
+[=
+
+(shell (out-pop #t))
+
+=] is bundled with AutoGen. It is a tool that virtually eliminates the
+hassle of processing options and keeping man pages, info docs and usage text
+up to date. This package allows you to specify several program attributes, up
+to a hundred option types and many option attributes. From this, it then
+produces all the code necessary to parse and handle the command line and
+configuration file options, and the documentation that should go with your
+program as well.
+[=
+
+INVOKE get-text tag = autoopts
+
+=]
+@noindent
+First, specify your program attributes and its options to AutoOpts,
+as with the following example.
+
+@example
+[=
+
+(out-push-new (string-append tmp-dir "/check.def" ))
+
+=]AutoGen Definitions options;
+prog-name = check;
+prog-title = "Checkout Automated Options";
+long-opts;
+gnu-usage; /* GNU style preferred to default */
+
+main = { main-type = shell-process; };
+
+flag = {
+ name = check-dirs;
+ value = L; /* flag style option character */
+ arg-type = string; /* option argument indication */
+ max = NOLIMIT; /* occurrence limit (none) */
+ stack-arg; /* save opt args in a stack */
+ descrip = "Checkout directory list";
+ doc = 'name of each directory that is to be "checked out".';
+};
+
+flag = {
+ name = show_defs;
+ descrip = "Show the definition tree";
+ disable = dont; /* mark as enable/disable type */
+ /* option. Disable as `dont-' */
+ doc = 'disable, if you do not want to see the tree.';
+};
+[= (texi-escape-encode (out-pop #t)) \=]
+@end example
+
+@noindent
+This program will produce a program that digests its options and
+writes the values as shell script code to stdout.
+Run the following short script to produce this program:[= #
+
+Developer note: the following only works when AutoGen has been installed.
+Since this may be being built on a system where it has not been installed,
+the code below ensures we are running out tools out of the build directory =]
+
+@example
+[=
+
+(out-push-new (string-append tmp-dir "/mk-check.sh" ))
+
+\=]
+base=check
+BASE=`echo $base | tr a-z- A-Z_`
+cflags="-DTEST_${BASE} `autoopts-config cflags`"
+ldflags="`autoopts-config ldflags`"
+autogen ${base}.def
+cc -o ${base} -g ${cflags} ${base}.c ${ldflags}
+./${base} --help
+[= (texi-escape-encode (out-pop #t)) \=]
+@end example
+
+@noindent
+Running those commands yields:
+
+@example
+[= (out-push-new) \=]
+cd ${tmp_dir}
+base=check
+exec 4>&2 5>&1 1> ${base}.err 2>&1
+
+ case "$-" in
+ *x* ) clear_x=: ;;
+ * ) clear_x='set +x' ;;
+ esac
+ set -x
+
+ test -f ${base}.def || die "cannot locate ${base}.def"
+ test ! -f ${base} || rm -f ${base}
+ echo "include = '#include \"compat/compat.h\"';" >> ${base}.def
+ f='@="@="'`echo ${INCLUDES} ${CFLAGS}`' @'
+ {
+ echo set -x
+ sed -e "s@^cc @${CC:-cc} -include ${top_builddir}/config.h @" \
+ -e '/^cflags="/s'"${f}" \
+ -e 's@^autogen @run_ag @' \
+ mk-${base}.sh
+ } > mk-${base}
+
+ . ./mk-${base}
+
+ $clear_x
+
+exec 1>&5 5>&- 2>&4 4>&-
+
+test -x ./${base} || {
+ cat mk-${base}
+ printf '\n\nFAILURE LOG:\n\n'
+ cat ${base}.err
+ die cannot create ${base} program
+} >&2
+
+./${base} --help | sed 's/\t/ /g'
+[=
+
+(texi-escape-encode (shell (out-pop #t)))
+
+=]
+@end example
+[=
+
+INVOKE get-text tag = autoopts-main
+
+=]
+Here is an example program that uses the following set of definitions:
+
+@example
+[=
+
+ (out-push-new (string-append tmp-dir "/default-test.def" ))
+
+=]AutoGen Definitions options;
+
+prog-name = default-test;
+prog-title = 'Default Option Example';
+homerc = '$$/../share/default-test', '$HOME', '.';
+environrc;
+long-opts;
+gnu-usage;
+usage-opt;
+version = '1.0';
+main = {
+ main-type = shell-process;
+};
+#define DEBUG_FLAG
+#define WARN_FLAG
+#define WARN_LEVEL
+#define VERBOSE_FLAG
+#define VERBOSE_ENUM
+#define DRY_RUN_FLAG
+#define OUTPUT_FLAG
+#define INPUT_FLAG
+#define DIRECTORY_FLAG
+#define INTERACTIVE_FLAG
+#include stdoptions.def
+[=
+
+ (texi-escape-encode (out-pop #t))
+
+=]@end example
+
+@noindent
+Running a few simple commands on that definition file:
+
+@example
+autogen default-test.def
+copts="-DTEST_DEFAULT_TEST_OPTS `autoopts-config cflags`"
+lopts="`autoopts-config ldflags`"
+cc -o default-test $@{copts@} default-test.c $@{lopts@}
+@end example
+
+@noindent
+Yields a program which, when run with @file{--help}, prints out:
+
+@example
+[= (out-push-new) \=]
+set -x
+log_file=${tmp_dir}/ao-doc-log
+exec 7>&2 ; exec 2>> ${log_file}
+TOPDIR=`cd ${top_builddir} >/dev/null ; pwd`
+OPTDIR=${TOPDIR}/autoopts
+
+{
+ cd ${tmp_dir}
+ chmod 666 *.def
+ echo 'config-header = "config.h";' >> default-test.def
+ HOME=${tmp_dir} run_ag default-test.def
+ test -f default-test.c || die 'NO default-test.c PROGRAM'
+
+ opts="-o default-test -DTEST_DEFAULT_TEST_OPTS ${INCLUDES}"
+ ${CC:-cc} ${CFLAGS} ${opts} default-test.c ${LIBS} || \
+ rm -f ./default-test
+
+ test -x ./default-test || {
+ exec 2>&7
+ fail_text=`cat $log_file`$'\n\nprogram:\n'`cat default-test.c`
+ die 'NO default-test EXECUTABLE
+ '"$fail_text"'
+ === END FAIL TEXT'
+ }
+} >&2
+
+HOME=${tmp_dir} ${tmp_dir}/default-test --help | \
+ sed 's, , ,g;s,\([@{}]\),@\1,g'
+
+exec 2>&7 7>&-
+[=
+ (shell (out-pop #t))
+=]
+@end example
+[=
+
+INVOKE get-text tag = autoopts-api
+
+=]
+[=`
+
+f=../autoopts/libopts.texi
+test -f $f || {
+ f=${top_srcdir}/autoopts/libopts.texi
+ test -f $f || die "Cannot locate libopts.texi in $f"
+}
+cat $f
+
+`=]
+[=
+
+INVOKE get-text tag = "autoopts-data"
+
+=]
+@noindent
+Doing so with getdefs' option definitions yields this sample-getdefsrc file.
+I tend to be wordy in my @code{doc} attributes:
+
+@example
+[= (texi-escape-encode (shell "
+ cd ${tmp_dir}
+ run_ag -Trc-sample.tpl ${top_srcdir}/getdefs/opts.def >/dev/null
+ test -f sample-getdefsrc || die did not create sample-getdefsrc
+ cat sample-getdefsrc
+" )) =]
+@end example
+[=
+
+INVOKE get-text tag = "ao-data1"
+
+=]
+@example[=
+(out-push-new (string-append tmp-dir "/hello.c"))
+
+\=]
+
+#include <config.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <pwd.h>
+#include <string.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <autoopts/options.h>
+int main(int argc, char ** argv) {
+ char const * greeting = "Hello";
+ char const * greeted = "World";
+ tOptionValue const * pOV = configFileLoad("hello.conf");
+
+ if (pOV != NULL) {
+ const tOptionValue* pGetV = optionGetValue(pOV, "greeting");
+
+ if ( (pGetV != NULL)
+ && (pGetV->valType == OPARG_TYPE_STRING))
+ greeting = strdup(pGetV->v.strVal);
+
+ pGetV = optionGetValue(pOV, "personalize");
+ if (pGetV != NULL) {
+ struct passwd * pwe = getpwuid(getuid());
+ if (pwe != NULL)
+ greeted = strdup(pwe->pw_gecos);
+ }
+
+ optionUnloadNested(pOV); /* deallocate config data */
+ }
+ printf("%s, %s!\n", greeting, greeted);
+ return 0;
+}
+[= (texi-escape-encode (out-pop #t)) \=]
+@end example
+
+@noindent
+With that text in a file named ``hello.c'', this short script:
+
+@example
+cc -o hello hello.c `autoopts-config cflags ldflags`
+./hello
+echo 'greeting Buzz off' > hello.conf
+./hello
+echo personalize > hello.conf
+./hello
+@end example
+
+@noindent
+will produce the following output:
+
+@example
+[= (texi-escape-encode (shell "
+cd ${tmp_dir}
+${CC:-cc} -o hello hello.c ${CFLAGS} ${LIBS} ${LDFLAGS} || \
+ die cannot compile hello
+./hello
+echo 'greeting Buzz off' > hello.conf
+./hello
+echo personalize > hello.conf
+./hello"
+)) =]
+@end example
+[=
+
+INVOKE get-text tag = "ao-data2"
+
+=]
+[=
+
+ (out-push-new)
+
+=]fn() {
+ cd ${top_builddir}/autoopts/test || return
+ VERBOSE=true
+ export VERBOSE
+ ${MAKE} check TESTS=errors.test > /dev/null 2>&1
+ if test ! -x testdir/errors
+ then
+ return
+ fi
+ cat <<-EOF
+
+ Here is the usage output example from AutoOpts error handling
+ tests. The option definition has argument reordering enabled:
+
+ @example
+EOF
+
+ ./testdir/errors -? | sed 's, , ,g;s,\([@{}]\),@\1,g'
+ cmd='errors operand1 -s first operand2 -X -- -s operand3'
+ cat <<-EOF
+ @end example
+
+ Using the invocation,
+ @example
+ test-${cmd}
+ @end example
+ you get the following output for your shell script to evaluate:
+
+ @example
+ `testdir/${cmd}`
+ @end example
+EOF
+}
+fn
+[=
+
+(shell (out-pop #t))
+
+=]
+@node script-parser
+@subsection Parsing with a Portable Script
+
+If you had used @code{test-main = optionParseShell} instead, then you can,
+at this point, merely run the program and it will write the parsing
+script to standard out. You may also provide this program with command
+line options to specify the shell script file to create or edit, and you
+may specify the shell program to use on the first shell script line.
+That program's usage text would look something like the following
+and the script parser itself would be very verbose:
+
+@example
+[= `
+
+log=${tmp_dir}/../genshellopt.log
+
+(
+ set -x
+ opts="-o genshellopt -DTEST_GETDEFS_OPTS ${INCLUDES}"
+ exec 3> ${tmp_dir}/genshellopt.def
+ cat ${top_srcdir}/getdefs/opts.def >&3
+ echo "test_main = 'optionParseShell';" >&3
+ echo 'config-header = "config.h";' >&3
+ exec 3>&-
+
+ cd ${tmp_dir}
+ HOME='' run_ag -t40 genshellopt.def
+ test $? -eq 0 || die "autogen failed to create genshellopt.c - See ${log}"
+
+ ${CC} ${CFLAGS} ${opts} genshellopt.c ${LIBS}
+ test $? -eq 0 || die "could not compile genshellopt.c - See ${log}"
+) > ${log} 2>&1
+
+test -x ${tmp_dir}/genshellopt || \
+ die "NO GENSHELLOPT PROGRAM - See ${log}"
+
+${tmp_dir}/genshellopt --help > ${tmp_dir}/genshellopt.hlp
+
+${tmp_dir}/genshellopt -o ${tmp_dir}/genshellopt.sh || \
+ die cannot create ${tmp_dir}/genshellopt.sh
+
+sedcmd='s,\t, ,g;s,\\([@{}]\\),@\\1,g'
+sed "${sedcmd}" ${tmp_dir}/genshellopt.hlp
+cat <<- \_EOF_
+ @end example
+
+ @noindent
+ Resulting in the following script:
+ @example
+ _EOF_
+
+sed "${sedcmd}" ${tmp_dir}/genshellopt.sh
+
+` =]
+@end example
+[=
+
+INVOKE get-text tag = autoinfo
+
+=]