5 * Time-stamp: "2012-03-31 19:19:26 bkorb"
7 * This module implements the default usage procedure for
8 * Automated Options. It may be overridden, of course.
11 --start=END-[S]TATIC-FORWARD --patt='^/\*($|[^:])' \
12 --out=xx.c key='^[a-zA-Z0-9_]+\(' --trail='^/\*:' \
13 --spac=2 --input=usage.c
17 * This file is part of AutoOpts, a companion to AutoGen.
18 * AutoOpts is free software.
19 * AutoOpts is Copyright (c) 1992-2012 by Bruce Korb - all rights reserved
21 * AutoOpts is available under any one of two licenses. The license
22 * in use must be one of these two and the choice is under the control
23 * of the user of the license.
25 * The GNU Lesser General Public License, version 3 or later
26 * See the files "COPYING.lgplv3" and "COPYING.gplv3"
28 * The Modified Berkeley Software Distribution License
29 * See the file "COPYING.mbsd"
31 * These files have the following md5sums:
33 * 43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
34 * 06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
35 * 66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
38 #define OPTPROC_L_N_S (OPTPROC_LONGOPT | OPTPROC_SHORTOPT)
40 /* = = = START-STATIC-FORWARD = = = */
42 do_gnu_usage(tOptions
* pOpts
);
45 skip_misuse_usage(tOptions
* pOpts
);
48 print_usage_details(tOptions
* opts
, int exit_code
);
51 prt_conflicts(tOptions
* pOptions
, tOptDesc
* pOD
);
54 prt_one_vendor(tOptions
* pOptions
, tOptDesc
* pOD
,
55 arg_types_t
* pAT
, char const * usefmt
);
58 prt_vendor_opts(tOptions
* pOpts
, char const * pOptTitle
);
61 prt_extd_usage(tOptions
* pOpts
, tOptDesc
* pOD
,
62 char const * pOptTitle
);
65 prt_ini_list(char const * const * papz
, bool * pInitIntro
,
66 char const * pzRc
, char const * pzPN
);
69 prt_preamble(tOptions
* pOptions
, tOptDesc
* pOD
, arg_types_t
* pAT
);
72 prt_one_usage(tOptions
* pOptions
, tOptDesc
* pOD
, arg_types_t
* pAT
);
75 prt_opt_usage(tOptions
* pOpts
, int ex_code
, char const * pOptTitle
);
78 prt_prog_detail(tOptions
* pOptions
);
81 setGnuOptFmts(tOptions
* pOpts
, tCC
** ppT
);
84 setStdOptFmts(tOptions
* pOpts
, tCC
** ppT
);
85 /* = = = END-STATIC-FORWARD = = = */
88 * NB: no entry may be a prefix of another entry
90 #define AOFLAG_TABLE \
91 _aof_(gnu, OPTPROC_GNUUSAGE ) \
92 _aof_(autoopts, ~OPTPROC_GNUUSAGE) \
93 _aof_(no_misuse_usage, OPTPROC_MISUSE ) \
94 _aof_(misuse_usage, ~OPTPROC_MISUSE )
97 set_usage_flags(tOptions
* opts
, char const * flg_txt
)
102 char const * fnm_name
;
105 # define _aof_(_n, _f) AOUF_ ## _n ## _ID,
106 typedef enum { AOFLAG_TABLE AOUF_COUNT
} ao_flag_id_t
;
109 # define _aof_(_n, _f) AOUF_ ## _n = (1 << AOUF_ ## _n ## _ID),
110 typedef enum { AOFLAG_TABLE
} ao_flags_t
;
113 # define _aof_(_n, _f) { sizeof(#_n)-1, _f, #_n },
114 static ao_flag_names_t
const fn_table
[AOUF_COUNT
] = {
119 unsigned int flg
= (ao_flags_t
)0;
121 if (flg_txt
== NULL
) {
122 flg_txt
= getenv("AUTOOPTS_USAGE");
123 if (flg_txt
== NULL
) return;
126 flg_txt
= SPN_WHITESPACE_CHARS(flg_txt
);
132 ao_flag_names_t
const * fnt
= fn_table
;
135 if (strneqvcmp(flg_txt
, fnt
->fnm_name
, fnt
->fnm_len
) == 0)
137 if (++ix
>= AOUF_COUNT
)
143 * Make sure we have a full match. Look for whitespace,
144 * a comma, or a NUL byte.
146 if (! IS_END_LIST_ENTRY_CHAR(flg_txt
[fnt
->fnm_len
]))
150 flg_txt
= SPN_WHITESPACE_CHARS(flg_txt
+ fnt
->fnm_len
);
155 if (*flg_txt
== ',') {
157 * skip the comma and following white space
159 flg_txt
= SPN_WHITESPACE_CHARS(flg_txt
+ 1);
166 ao_flag_names_t
const * fnm
= fn_table
;
169 if ((flg
& 1) != 0) {
170 if ((fnm
->fnm_mask
& OPTPROC_LONGOPT
) != 0)
171 opts
->fOptSet
&= fnm
->fnm_mask
;
172 else opts
->fOptSet
|= fnm
->fnm_mask
;
181 * Figure out if we should try to format usage text sort-of like
182 * the way many GNU programs do.
185 do_gnu_usage(tOptions
* pOpts
)
187 return (pOpts
->fOptSet
& OPTPROC_GNUUSAGE
) ? true : false;
191 * Figure out if we should try to format usage text sort-of like
192 * the way many GNU programs do.
195 skip_misuse_usage(tOptions
* pOpts
)
197 return (pOpts
->fOptSet
& OPTPROC_MISUSE
) ? true : false;
201 /*=export_func optionOnlyUsage
203 * what: Print usage text for just the options
204 * arg: + tOptions* + pOpts + program options descriptor +
205 * arg: + int + ex_code + exit code for calling exit(3) +
208 * This routine will print only the usage for each option.
209 * This function may be used when the emitted usage must incorporate
210 * information not available to AutoOpts.
213 optionOnlyUsage(tOptions
* pOpts
, int ex_code
)
215 char const * pOptTitle
= NULL
;
217 set_usage_flags(pOpts
, NULL
);
218 if ((ex_code
!= EXIT_SUCCESS
) &&
219 skip_misuse_usage(pOpts
))
223 * Determine which header and which option formatting strings to use
225 if (do_gnu_usage(pOpts
))
226 (void)setGnuOptFmts(pOpts
, &pOptTitle
);
228 (void)setStdOptFmts(pOpts
, &pOptTitle
);
230 prt_opt_usage(pOpts
, ex_code
, pOptTitle
);
232 fflush(option_usage_fp
);
233 if (ferror(option_usage_fp
) != 0) {
234 fputs(zOutputFail
, stderr
);
240 print_usage_details(tOptions
* opts
, int exit_code
)
243 char const * pOptTitle
= NULL
;
246 * Determine which header and which option formatting strings to use
248 if (do_gnu_usage(opts
)) {
249 int flen
= setGnuOptFmts(opts
, &pOptTitle
);
250 sprintf(line_fmt_buf
, zFmtFmt
, flen
);
251 fputc(NL
, option_usage_fp
);
254 int flen
= setStdOptFmts(opts
, &pOptTitle
);
255 sprintf(line_fmt_buf
, zFmtFmt
, flen
);
258 * When we exit with EXIT_SUCCESS and the first option is a doc
259 * option, we do *NOT* want to emit the column headers.
262 if ( (exit_code
!= EXIT_SUCCESS
)
263 || ((opts
->pOptDesc
->fOptState
& OPTST_DOCUMENT
) == 0) )
265 fputs(pOptTitle
, option_usage_fp
);
268 prt_opt_usage(opts
, exit_code
, pOptTitle
);
272 * Describe the mechanics of denoting the options
274 switch (opts
->fOptSet
& OPTPROC_L_N_S
) {
275 case OPTPROC_L_N_S
: fputs(zFlagOkay
, option_usage_fp
); break;
276 case OPTPROC_SHORTOPT
: break;
277 case OPTPROC_LONGOPT
: fputs(zNoFlags
, option_usage_fp
); break;
278 case 0: fputs(zOptsOnly
, option_usage_fp
); break;
281 if ((opts
->fOptSet
& OPTPROC_NUM_OPT
) != 0)
282 fputs(zNumberOpt
, option_usage_fp
);
284 if ((opts
->fOptSet
& OPTPROC_REORDER
) != 0)
285 fputs(zReorder
, option_usage_fp
);
287 if (opts
->pzExplain
!= NULL
)
288 fputs(opts
->pzExplain
, option_usage_fp
);
291 * IF the user is asking for help (thus exiting with SUCCESS),
292 * THEN see what additional information we can provide.
294 if (exit_code
== EXIT_SUCCESS
)
295 prt_prog_detail(opts
);
298 * Give bug notification preference to the packager information
300 if (HAS_pzPkgDataDir(opts
) && (opts
->pzPackager
!= NULL
))
301 fputs(opts
->pzPackager
, option_usage_fp
);
303 else if (opts
->pzBugAddr
!= NULL
)
304 fprintf(option_usage_fp
, zPlsSendBugs
, opts
->pzBugAddr
);
306 fflush(option_usage_fp
);
308 if (ferror(option_usage_fp
) != 0) {
309 fputs(zOutputFail
, stderr
);
315 /*=export_func optionUsage
318 * what: Print usage text
319 * arg: + tOptions* + pOptions + program options descriptor +
320 * arg: + int + exitCode + exit code for calling exit(3) +
323 * This routine will print usage in both GNU-standard and AutoOpts-expanded
324 * formats. The descriptor specifies the default, but AUTOOPTS_USAGE will
325 * over-ride this, providing the value of it is set to either "gnu" or
326 * "autoopts". This routine will @strong{not} return.
328 * If "exitCode" is "AO_EXIT_REQ_USAGE" (normally 64), then output will to
329 * to stdout and the actual exit code will be "EXIT_SUCCESS".
332 optionUsage(tOptions
* pOptions
, int usage_exit_code
)
334 int exit_code
= (usage_exit_code
== AO_EXIT_REQ_USAGE
)
335 ? EXIT_SUCCESS
: usage_exit_code
;
340 * Paged usage will preset option_usage_fp to an output file.
341 * If it hasn't already been set, then set it to standard output
342 * on successful exit (help was requested), otherwise error out.
344 * Test the version before obtaining pzFullUsage or pzShortUsage.
345 * These fields do not exist before revision 30.
350 if (exit_code
== EXIT_SUCCESS
) {
351 pz
= (pOptions
->structVersion
>= 30 * 4096)
352 ? pOptions
->pzFullUsage
: NULL
;
354 if (option_usage_fp
== NULL
)
355 option_usage_fp
= stdout
;
357 pz
= (pOptions
->structVersion
>= 30 * 4096)
358 ? pOptions
->pzShortUsage
: NULL
;
360 if (option_usage_fp
== NULL
)
361 option_usage_fp
= stderr
;
365 fputs(pz
, option_usage_fp
);
370 fprintf(option_usage_fp
, pOptions
->pzUsageTitle
, pOptions
->pzProgName
);
371 set_usage_flags(pOptions
, NULL
);
373 if ((exit_code
== EXIT_SUCCESS
) ||
374 (! skip_misuse_usage(pOptions
)))
376 print_usage_details(pOptions
, usage_exit_code
);
381 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
382 * PER OPTION TYPE USAGE INFORMATION
383 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
385 * print option conflicts.
387 * @param pOptions the program option descriptor
388 * @param pOD the option descriptor
389 * @param pAT names of the option argument types
392 prt_conflicts(tOptions
* pOptions
, tOptDesc
* pOD
)
395 fputs(zTabHyp
, option_usage_fp
);
400 if (pOD
->pOptMust
!= NULL
) {
401 const int* pOptNo
= pOD
->pOptMust
;
403 fputs(zReqThese
, option_usage_fp
);
405 fprintf(option_usage_fp
, zTabout
,
406 pOptions
->pOptDesc
[*pOptNo
].pz_Name
);
407 if (*++pOptNo
== NO_EQUIVALENT
)
411 if (pOD
->pOptCant
!= NULL
)
412 fputs(zTabHypAnd
, option_usage_fp
);
418 if (pOD
->pOptCant
!= NULL
) {
419 const int* pOptNo
= pOD
->pOptCant
;
421 fputs(zProhib
, option_usage_fp
);
423 fprintf(option_usage_fp
, zTabout
,
424 pOptions
->pOptDesc
[*pOptNo
].pz_Name
);
425 if (*++pOptNo
== NO_EQUIVALENT
)
432 * Print the usage information for a single vendor option.
434 * @param pOpts the program option descriptor
435 * @param pOD the option descriptor
436 * @param pAT names of the option argument types
439 prt_one_vendor(tOptions
* pOptions
, tOptDesc
* pOD
,
440 arg_types_t
* pAT
, char const * usefmt
)
442 prt_preamble(pOptions
, pOD
, pAT
);
446 char const * pzArgType
;
449 * Determine the argument type string first on its usage, then,
450 * when the option argument is required, base the type string on the
453 if (pOD
->fOptState
& OPTST_ARG_OPTIONAL
) {
454 pzArgType
= pAT
->pzOpt
;
456 } else switch (OPTST_GET_ARGTYPE(pOD
->fOptState
)) {
457 case OPARG_TYPE_NONE
: pzArgType
= pAT
->pzNo
; break;
458 case OPARG_TYPE_ENUMERATION
: pzArgType
= pAT
->pzKey
; break;
459 case OPARG_TYPE_FILE
: pzArgType
= pAT
->pzFile
; break;
460 case OPARG_TYPE_MEMBERSHIP
: pzArgType
= pAT
->pzKeyL
; break;
461 case OPARG_TYPE_BOOLEAN
: pzArgType
= pAT
->pzBool
; break;
462 case OPARG_TYPE_NUMERIC
: pzArgType
= pAT
->pzNum
; break;
463 case OPARG_TYPE_HIERARCHY
: pzArgType
= pAT
->pzNest
; break;
464 case OPARG_TYPE_STRING
: pzArgType
= pAT
->pzStr
; break;
465 case OPARG_TYPE_TIME
: pzArgType
= pAT
->pzTime
; break;
466 default: goto bogus_desc
;
469 pzArgType
= SPN_WHITESPACE_CHARS(pzArgType
);
470 if (*pzArgType
== NUL
)
471 snprintf(z
, sizeof(z
), "%s", pOD
->pz_Name
);
473 snprintf(z
, sizeof(z
), "%s=%s", pOD
->pz_Name
, pzArgType
);
474 fprintf(option_usage_fp
, usefmt
, z
, pOD
->pzText
);
476 switch (OPTST_GET_ARGTYPE(pOD
->fOptState
)) {
477 case OPARG_TYPE_ENUMERATION
:
478 case OPARG_TYPE_MEMBERSHIP
:
479 displayEnum
= (pOD
->pOptProc
!= NULL
) ? true : displayEnum
;
486 fprintf(stderr
, zInvalOptDesc
, pOD
->pz_Name
);
491 * Print the long options processed with "-W". These options will be the
492 * ones that do *not* have flag characters.
494 * @param pOptions the program option descriptor
495 * @param pOD the option descriptor
498 prt_vendor_opts(tOptions
* pOpts
, char const * pOptTitle
)
500 static unsigned int const not_vended_mask
=
501 OPTST_NO_USAGE_MASK
| OPTST_DOCUMENT
;
503 static char const vfmtfmt
[] = "%%-%us %%s\n";
504 char vfmt
[sizeof(vfmtfmt
)];
507 * Only handle client specified options. The "vendor option" follows
508 * "presetOptCt", so we won't loop/recurse indefinitely.
510 int ct
= pOpts
->presetOptCt
;
511 tOptDesc
* pOD
= pOpts
->pOptDesc
;
514 fprintf(option_usage_fp
, zTabout
, zVendOptsAre
);
518 if ( ((pOD
->fOptState
& not_vended_mask
) != 0)
519 || IS_GRAPHIC_CHAR(pOD
->optValue
))
522 l
= strlen(pOD
->pz_Name
);
523 if (l
> nmlen
) nmlen
= l
;
524 } while (pOD
++, (--ct
> 0));
526 sprintf(vfmt
, vfmtfmt
, (unsigned int)nmlen
+ 4);
527 ct
= pOpts
->presetOptCt
;
528 pOD
= pOpts
->pOptDesc
;
531 if ( ((pOD
->fOptState
& not_vended_mask
) != 0)
532 || IS_GRAPHIC_CHAR(pOD
->optValue
))
535 prt_one_vendor(pOpts
, pOD
, &argTypes
, vfmt
);
536 prt_extd_usage(pOpts
, pOD
, pOptTitle
);
538 } while (pOD
++, (--ct
> 0));
542 * Print extended usage. Usage/help was requested.
544 * @param pOptions the program option descriptor
545 * @param pOD the option descriptor
546 * @param pAT names of the option argument types
549 prt_extd_usage(tOptions
* pOpts
, tOptDesc
* pOD
,
550 char const * pOptTitle
)
552 if ( ((pOpts
->fOptSet
& OPTPROC_VENDOR_OPT
) != 0)
553 && (pOD
->optActualValue
== VENDOR_OPTION_VALUE
)) {
554 prt_vendor_opts(pOpts
, pOptTitle
);
559 * IF there are option conflicts or dependencies,
560 * THEN print them here.
562 if ( (pOD
->pOptMust
!= NULL
)
563 || (pOD
->pOptCant
!= NULL
) )
564 prt_conflicts(pOpts
, pOD
);
567 * IF there is a disablement string
568 * THEN print the disablement info
570 if (pOD
->pz_DisableName
!= NULL
)
571 fprintf(option_usage_fp
, zDis
, pOD
->pz_DisableName
);
574 * Check for argument types that have callbacks with magical properties
576 switch (OPTST_GET_ARGTYPE(pOD
->fOptState
)) {
577 case OPARG_TYPE_NUMERIC
:
579 * IF the numeric option has a special callback,
580 * THEN call it, requesting the range or other special info
582 if ( (pOD
->pOptProc
!= NULL
)
583 && (pOD
->pOptProc
!= optionNumericVal
) ) {
584 (*(pOD
->pOptProc
))(OPTPROC_EMIT_USAGE
, pOD
);
588 case OPARG_TYPE_FILE
:
589 (*(pOD
->pOptProc
))(OPTPROC_EMIT_USAGE
, pOD
);
594 * IF the option defaults to being enabled,
595 * THEN print that out
597 if (pOD
->fOptState
& OPTST_INITENABLED
)
598 fputs(zEnab
, option_usage_fp
);
601 * IF the option is in an equivalence class
602 * AND not the designated lead
603 * THEN print equivalence and leave it at that.
605 if ( (pOD
->optEquivIndex
!= NO_EQUIVALENT
)
606 && (pOD
->optEquivIndex
!= pOD
->optActualIndex
) ) {
607 fprintf(option_usage_fp
, zAlt
,
608 pOpts
->pOptDesc
[ pOD
->optEquivIndex
].pz_Name
);
613 * IF this particular option can NOT be preset
614 * AND some form of presetting IS allowed,
615 * AND it is not an auto-managed option (e.g. --help, et al.)
616 * THEN advise that this option may not be preset.
618 if ( ((pOD
->fOptState
& OPTST_NO_INIT
) != 0)
619 && ( (pOpts
->papzHomeList
!= NULL
)
620 || (pOpts
->pzPROGNAME
!= NULL
)
622 && (pOD
->optIndex
< pOpts
->presetOptCt
)
625 fputs(zNoPreset
, option_usage_fp
);
628 * Print the appearance requirements.
630 if (OPTST_GET_ARGTYPE(pOD
->fOptState
) == OPARG_TYPE_MEMBERSHIP
)
631 fputs(zMembers
, option_usage_fp
);
633 else switch (pOD
->optMinCt
) {
636 switch (pOD
->optMaxCt
) {
637 case 0: fputs(zPreset
, option_usage_fp
); break;
638 case NOLIMIT
: fputs(zNoLim
, option_usage_fp
); break;
641 * IF the max is more than one but limited, print "UP TO" message
643 default: fprintf(option_usage_fp
, zUpTo
, pOD
->optMaxCt
); break;
649 * More than one is required. Print the range.
651 fprintf(option_usage_fp
, zMust
, pOD
->optMinCt
, pOD
->optMaxCt
);
654 if ( NAMED_OPTS(pOpts
)
655 && (pOpts
->specOptIdx
.default_opt
== pOD
->optIndex
))
656 fputs(zDefaultOpt
, option_usage_fp
);
659 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
661 * Figure out where all the initialization files might live.
662 * This requires translating some environment variables and
663 * testing to see if a name is a directory or a file. It's
664 * squishy, but important to tell users how to find these files.
667 prt_ini_list(char const * const * papz
, bool * pInitIntro
,
668 char const * pzRc
, char const * pzPN
)
670 char zPath
[AG_PATH_MAX
+1];
675 fputs(zPresetIntro
, option_usage_fp
);
679 char const * pzPath
= *(papz
++);
680 char const * pzReal
= zPath
;
686 * Ignore any invalid paths
688 if (! optionMakePath(zPath
, (int)sizeof(zPath
), pzPath
, pzPN
))
692 * Expand paths that are relative to the executable or installation
693 * directories. Leave alone paths that use environment variables.
695 else if ((*pzPath
== '$')
696 && ((pzPath
[1] == '$') || (pzPath
[1] == '@')))
700 * Print the name of the "homerc" file. If the "rcfile" name is
701 * not empty, we may or may not print that, too...
703 fprintf(option_usage_fp
, zPathFmt
, pzPath
);
708 * IF the "homerc" file is a directory,
709 * then append the "rcfile" name.
711 if ((stat(pzReal
, &sb
) == 0) && S_ISDIR(sb
.st_mode
)) {
712 fputc(DIRCH
, option_usage_fp
);
713 fputs(pzRc
, option_usage_fp
);
717 fputc(NL
, option_usage_fp
);
723 prt_preamble(tOptions
* pOptions
, tOptDesc
* pOD
, arg_types_t
* pAT
)
726 * Flag prefix: IF no flags at all, then omit it. If not printable
727 * (not allowed for this option), then blank, else print it.
728 * Follow it with a comma if we are doing GNU usage and long
729 * opts are to be printed too.
731 if ((pOptions
->fOptSet
& OPTPROC_SHORTOPT
) == 0)
732 fputs(pAT
->pzSpc
, option_usage_fp
);
734 else if (! IS_GRAPHIC_CHAR(pOD
->optValue
)) {
735 if ( (pOptions
->fOptSet
& (OPTPROC_GNUUSAGE
|OPTPROC_LONGOPT
))
736 == (OPTPROC_GNUUSAGE
|OPTPROC_LONGOPT
))
737 fputc(' ', option_usage_fp
);
738 fputs(pAT
->pzNoF
, option_usage_fp
);
741 fprintf(option_usage_fp
, " -%c", pOD
->optValue
);
742 if ( (pOptions
->fOptSet
& (OPTPROC_GNUUSAGE
|OPTPROC_LONGOPT
))
743 == (OPTPROC_GNUUSAGE
|OPTPROC_LONGOPT
))
744 fputs(", ", option_usage_fp
);
749 * Print the usage information for a single option.
751 * @param pOpts the program option descriptor
752 * @param pOD the option descriptor
753 * @param pAT names of the option argument types
756 prt_one_usage(tOptions
* pOptions
, tOptDesc
* pOD
, arg_types_t
* pAT
)
758 prt_preamble(pOptions
, pOD
, pAT
);
762 char const * pzArgType
;
765 * Determine the argument type string first on its usage, then,
766 * when the option argument is required, base the type string on the
769 if (pOD
->fOptState
& OPTST_ARG_OPTIONAL
) {
770 pzArgType
= pAT
->pzOpt
;
772 } else switch (OPTST_GET_ARGTYPE(pOD
->fOptState
)) {
773 case OPARG_TYPE_NONE
: pzArgType
= pAT
->pzNo
; break;
774 case OPARG_TYPE_ENUMERATION
: pzArgType
= pAT
->pzKey
; break;
775 case OPARG_TYPE_FILE
: pzArgType
= pAT
->pzFile
; break;
776 case OPARG_TYPE_MEMBERSHIP
: pzArgType
= pAT
->pzKeyL
; break;
777 case OPARG_TYPE_BOOLEAN
: pzArgType
= pAT
->pzBool
; break;
778 case OPARG_TYPE_NUMERIC
: pzArgType
= pAT
->pzNum
; break;
779 case OPARG_TYPE_HIERARCHY
: pzArgType
= pAT
->pzNest
; break;
780 case OPARG_TYPE_STRING
: pzArgType
= pAT
->pzStr
; break;
781 case OPARG_TYPE_TIME
: pzArgType
= pAT
->pzTime
; break;
782 default: goto bogus_desc
;
785 snprintf(z
, sizeof(z
), pAT
->pzOptFmt
, pzArgType
, pOD
->pz_Name
,
786 (pOD
->optMinCt
!= 0) ? pAT
->pzReq
: pAT
->pzOpt
);
788 fprintf(option_usage_fp
, line_fmt_buf
, z
, pOD
->pzText
);
790 switch (OPTST_GET_ARGTYPE(pOD
->fOptState
)) {
791 case OPARG_TYPE_ENUMERATION
:
792 case OPARG_TYPE_MEMBERSHIP
:
793 displayEnum
= (pOD
->pOptProc
!= NULL
) ? true : displayEnum
;
800 fprintf(stderr
, zInvalOptDesc
, pOD
->pz_Name
);
805 * Print out the usage information for just the options.
808 prt_opt_usage(tOptions
* pOpts
, int ex_code
, char const * pOptTitle
)
810 int ct
= pOpts
->optCt
;
812 tOptDesc
* pOD
= pOpts
->pOptDesc
;
817 * no usage --> disallowed on command line (OPTST_NO_COMMAND), or
818 * deprecated -- strongly discouraged (OPTST_DEPRECATED), or
819 * compiled out of current object code (OPTST_OMITTED)
821 if ((pOD
->fOptState
& OPTST_NO_USAGE_MASK
) != 0) {
824 * IF this is a compiled-out option
825 * *AND* usage was requested with "omitted-usage"
826 * *AND* this is NOT abbreviated usage
827 * THEN display this option.
829 if ( (pOD
->fOptState
== (OPTST_OMITTED
| OPTST_NO_INIT
))
830 && (pOD
->pz_Name
!= NULL
)
831 && (ex_code
== EXIT_SUCCESS
)) {
833 char const * why_pz
=
834 (pOD
->pzText
== NULL
) ? zDisabledWhy
: pOD
->pzText
;
835 prt_preamble(pOpts
, pOD
, &argTypes
);
836 fprintf(option_usage_fp
, zDisabledOpt
, pOD
->pz_Name
, why_pz
);
842 if ((pOD
->fOptState
& OPTST_DOCUMENT
) != 0) {
843 if (ex_code
== EXIT_SUCCESS
) {
844 fprintf(option_usage_fp
, argTypes
.pzBrk
, pOD
->pzText
,
852 /* Skip name only options when we have a vendor option */
853 if ( ((pOpts
->fOptSet
& OPTPROC_VENDOR_OPT
) != 0)
854 && (! IS_GRAPHIC_CHAR(pOD
->optValue
)))
858 * IF this is the first auto-opt maintained option
859 * *AND* we are doing a full help
860 * *AND* there are documentation options
861 * *AND* the last one was not a doc option,
862 * THEN document that the remaining options are not user opts
864 if ((docCt
> 0) && (ex_code
== EXIT_SUCCESS
)) {
865 if (pOpts
->presetOptCt
== optNo
) {
866 if ((pOD
[-1].fOptState
& OPTST_DOCUMENT
) == 0)
867 fprintf(option_usage_fp
, argTypes
.pzBrk
, zAuto
, pOptTitle
);
869 } else if ((ct
== 1) &&
870 (pOpts
->fOptSet
& OPTPROC_VENDOR_OPT
))
871 fprintf(option_usage_fp
, argTypes
.pzBrk
, zVendIntro
, pOptTitle
);
874 prt_one_usage(pOpts
, pOD
, &argTypes
);
877 * IF we were invoked because of the --help option,
878 * THEN print all the extra info
880 if (ex_code
== EXIT_SUCCESS
)
881 prt_extd_usage(pOpts
, pOD
, pOptTitle
);
883 } while (pOD
++, optNo
++, (--ct
> 0));
885 fputc(NL
, option_usage_fp
);
889 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
894 prt_prog_detail(tOptions
* pOptions
)
896 bool initIntro
= true;
899 * Display all the places we look for config files
901 prt_ini_list(pOptions
->papzHomeList
, &initIntro
,
902 pOptions
->pzRcName
, pOptions
->pzProgPath
);
905 * Let the user know about environment variable settings
907 if ((pOptions
->fOptSet
& OPTPROC_ENVIRON
) != 0) {
909 fputs(zPresetIntro
, option_usage_fp
);
911 fprintf(option_usage_fp
, zExamineFmt
, pOptions
->pzPROGNAME
);
915 * IF we found an enumeration,
916 * THEN hunt for it again. Call the handler proc with a NULL
917 * option struct pointer. That tells it to display the keywords.
920 int ct
= pOptions
->optCt
;
922 tOptDesc
* pOD
= pOptions
->pOptDesc
;
924 fputc(NL
, option_usage_fp
);
925 fflush(option_usage_fp
);
927 switch (OPTST_GET_ARGTYPE(pOD
->fOptState
)) {
928 case OPARG_TYPE_ENUMERATION
:
929 case OPARG_TYPE_MEMBERSHIP
:
930 (*(pOD
->pOptProc
))(OPTPROC_EMIT_USAGE
, pOD
);
932 } while (pOD
++, optNo
++, (--ct
> 0));
936 * If there is a detail string, now is the time for that.
938 if (pOptions
->pzDetail
!= NULL
)
939 fputs(pOptions
->pzDetail
, option_usage_fp
);
943 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
945 * OPTION LINE FORMATTING SETUP
947 * The "OptFmt" formats receive three arguments:
948 * 1. the type of the option's argument
949 * 2. the long name of the option
950 * 3. "YES" or "no ", depending on whether or not the option must appear
951 * on the command line.
952 * These formats are used immediately after the option flag (if used) has
955 * Set up the formatting for GNU-style output
958 setGnuOptFmts(tOptions
* pOpts
, tCC
** ppT
)
960 static char const zOneSpace
[] = " ";
962 *ppT
= zNoRq_ShrtTtl
;
964 argTypes
.pzStr
= zGnuStrArg
;
965 argTypes
.pzReq
= zOneSpace
;
966 argTypes
.pzNum
= zGnuNumArg
;
967 argTypes
.pzKey
= zGnuKeyArg
;
968 argTypes
.pzKeyL
= zGnuKeyLArg
;
969 argTypes
.pzTime
= zGnuTimeArg
;
970 argTypes
.pzFile
= zGnuFileArg
;
971 argTypes
.pzBool
= zGnuBoolArg
;
972 argTypes
.pzNest
= zGnuNestArg
;
973 argTypes
.pzOpt
= zGnuOptArg
;
974 argTypes
.pzNo
= zOneSpace
;
975 argTypes
.pzBrk
= zGnuBreak
;
976 argTypes
.pzNoF
= zSixSpaces
;
977 argTypes
.pzSpc
= zThreeSpaces
;
979 switch (pOpts
->fOptSet
& OPTPROC_L_N_S
) {
980 case OPTPROC_L_N_S
: argTypes
.pzOptFmt
= zGnuOptFmt
; break;
981 case OPTPROC_LONGOPT
: argTypes
.pzOptFmt
= zGnuOptFmt
; break;
982 case 0: argTypes
.pzOptFmt
= zGnuOptFmt
+ 2; break;
983 case OPTPROC_SHORTOPT
:
984 argTypes
.pzOptFmt
= zShrtGnuOptFmt
;
985 zGnuStrArg
[0] = zGnuNumArg
[0] = zGnuKeyArg
[0] = zGnuBoolArg
[0] = ' ';
986 argTypes
.pzOpt
= " [arg]";
996 * Standard (AutoOpts normal) option line formatting
999 setStdOptFmts(tOptions
* pOpts
, tCC
** ppT
)
1003 argTypes
.pzStr
= zStdStrArg
;
1004 argTypes
.pzReq
= zStdReqArg
;
1005 argTypes
.pzNum
= zStdNumArg
;
1006 argTypes
.pzKey
= zStdKeyArg
;
1007 argTypes
.pzKeyL
= zStdKeyLArg
;
1008 argTypes
.pzTime
= zStdTimeArg
;
1009 argTypes
.pzFile
= zStdFileArg
;
1010 argTypes
.pzBool
= zStdBoolArg
;
1011 argTypes
.pzNest
= zStdNestArg
;
1012 argTypes
.pzOpt
= zStdOptArg
;
1013 argTypes
.pzNo
= zStdNoArg
;
1014 argTypes
.pzBrk
= zStdBreak
;
1015 argTypes
.pzNoF
= zFiveSpaces
;
1016 argTypes
.pzSpc
= zTwoSpaces
;
1018 switch (pOpts
->fOptSet
& (OPTPROC_NO_REQ_OPT
| OPTPROC_SHORTOPT
)) {
1019 case (OPTPROC_NO_REQ_OPT
| OPTPROC_SHORTOPT
):
1020 *ppT
= zNoRq_ShrtTtl
;
1021 argTypes
.pzOptFmt
= zNrmOptFmt
;
1025 case OPTPROC_NO_REQ_OPT
:
1026 *ppT
= zNoRq_NoShrtTtl
;
1027 argTypes
.pzOptFmt
= zNrmOptFmt
;
1031 case OPTPROC_SHORTOPT
:
1032 *ppT
= zReq_ShrtTtl
;
1033 argTypes
.pzOptFmt
= zReqOptFmt
;
1038 *ppT
= zReq_NoShrtTtl
;
1039 argTypes
.pzOptFmt
= zReqOptFmt
;
1050 * c-file-style: "stroustrup"
1051 * indent-tabs-mode: nil
1053 * end of autoopts/usage.c */