summaryrefslogtreecommitdiff
path: root/autoopts/tpl/optlib.tlib
diff options
context:
space:
mode:
Diffstat (limited to 'autoopts/tpl/optlib.tlib')
-rw-r--r--autoopts/tpl/optlib.tlib1260
1 files changed, 1260 insertions, 0 deletions
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 \=]