diff options
Diffstat (limited to 'autoopts/tpl/optlib.tlib')
-rw-r--r-- | autoopts/tpl/optlib.tlib | 1260 |
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 \=] |