diff options
Diffstat (limited to 'autoopts/tpl')
34 files changed, 10332 insertions, 0 deletions
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>...<...>...</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 \=] |