1
2/*
3 *  usage.c  $Id: f611ee45aa9aa8dc102b8acf6b4bc568c60fa99f $
4 * Time-stamp:      "2009-10-02 23:18:50 bkorb"
5 *
6 *  This module implements the default usage procedure for
7 *  Automated Options.  It may be overridden, of course.
8 *
9 *  Sort options:
10    --start=END-[S]TATIC-FORWARD --patt='^/\*($|[^:])' \
11    --out=xx.c key='^[a-zA-Z0-9_]+\(' --trail='^/\*:' \
12    --spac=2 --input=usage.c
13 */
14
15/*
16 *  This file is part of AutoOpts, a companion to AutoGen.
17 *  AutoOpts is free software.
18 *  AutoOpts is copyright (c) 1992-2009 by Bruce Korb - all rights reserved
19 *
20 *  AutoOpts is available under any one of two licenses.  The license
21 *  in use must be one of these two and the choice is under the control
22 *  of the user of the license.
23 *
24 *   The GNU Lesser General Public License, version 3 or later
25 *      See the files "COPYING.lgplv3" and "COPYING.gplv3"
26 *
27 *   The Modified Berkeley Software Distribution License
28 *      See the file "COPYING.mbsd"
29 *
30 *  These files have the following md5sums:
31 *
32 *  43b91e8ca915626ed3818ffb1b71248b pkg/libopts/COPYING.gplv3
33 *  06a1a2e4760c90ea5e1dad8dfaac4d39 pkg/libopts/COPYING.lgplv3
34 *  66a5cedaf62c4b2637025f049f9b826f pkg/libopts/COPYING.mbsd
35 */
36
37#define OPTPROC_L_N_S  (OPTPROC_LONGOPT | OPTPROC_SHORTOPT)
38
39static arg_types_t argTypes;
40
41FILE* option_usage_fp = NULL;
42static char    zOptFmtLine[ 16 ];
43static ag_bool displayEnum;
44
45/* = = = START-STATIC-FORWARD = = = */
46/* static forward declarations maintained by mk-fwd */
47static ag_bool
48checkGNUUsage( tOptions* pOpts );
49
50static void
51printExtendedUsage(
52    tOptions*     pOptions,
53    tOptDesc*     pOD,
54    arg_types_t*  pAT );
55
56static void
57printInitList(
58    tCC* const* papz,
59    ag_bool*    pInitIntro,
60    tCC*        pzRc,
61    tCC*        pzPN );
62
63static void
64printOptPreamble(
65    tOptions*     pOptions,
66    tOptDesc*     pOD,
67    arg_types_t*  pAT );
68
69static void
70printOneUsage(
71    tOptions*     pOptions,
72    tOptDesc*     pOD,
73    arg_types_t*  pAT );
74
75static void
76printOptionUsage(
77    tOptions *  pOpts,
78    int         ex_code,
79    tCC *       pOptTitle );
80
81static void
82printProgramDetails( tOptions* pOptions );
83
84static int
85setGnuOptFmts( tOptions* pOpts, tCC** ppT );
86
87static int
88setStdOptFmts( tOptions* pOpts, tCC** ppT );
89/* = = = END-STATIC-FORWARD = = = */
90
91
92/*
93 *  Figure out if we should try to format usage text sort-of like
94 *  the way many GNU programs do.
95 */
96static ag_bool
97checkGNUUsage( tOptions* pOpts )
98{
99    char* pz = getenv( "AUTOOPTS_USAGE" );
100    if (pz == NULL)
101        ;
102
103    else if (streqvcmp( pz, "gnu" ) == 0)
104        pOpts->fOptSet |= OPTPROC_GNUUSAGE;
105
106    else if (streqvcmp( pz, "autoopts" ) == 0)
107        pOpts->fOptSet &= ~OPTPROC_GNUUSAGE;
108
109    return (pOpts->fOptSet & OPTPROC_GNUUSAGE) ? AG_TRUE : AG_FALSE;
110}
111
112
113/*=export_func  optionOnlyUsage
114 *
115 * what:  Print usage text for just the options
116 * arg:   + tOptions*   + pOpts    + program options descriptor +
117 * arg:   + int         + ex_code  + exit code for calling exit(3) +
118 *
119 * doc:
120 *  This routine will print only the usage for each option.
121 *  This function may be used when the emitted usage must incorporate
122 *  information not available to AutoOpts.
123=*/
124void
125optionOnlyUsage(
126    tOptions* pOpts,
127    int       ex_code )
128{
129    tCC* pOptTitle = NULL;
130
131    /*
132     *  Determine which header and which option formatting strings to use
133     */
134    if (checkGNUUsage(pOpts)) {
135        (void)setGnuOptFmts( pOpts, &pOptTitle );
136    }
137    else {
138        (void)setStdOptFmts( pOpts, &pOptTitle );
139    }
140
141    printOptionUsage( pOpts, ex_code, pOptTitle );
142}
143
144
145/*=export_func  optionUsage
146 * private:
147 *
148 * what:  Print usage text
149 * arg:   + tOptions* + pOptions + program options descriptor +
150 * arg:   + int       + exitCode + exit code for calling exit(3) +
151 *
152 * doc:
153 *  This routine will print usage in both GNU-standard and AutoOpts-expanded
154 *  formats.  The descriptor specifies the default, but AUTOOPTS_USAGE will
155 *  over-ride this, providing the value of it is set to either "gnu" or
156 *  "autoopts".  This routine will @strong{not} return.
157 *
158 *  If "exitCode" is "EX_USAGE" (normally 64), then output will to to stdout
159 *  and the actual exit code will be "EXIT_SUCCESS".
160=*/
161void
162optionUsage(
163    tOptions* pOptions,
164    int       usage_exit_code )
165{
166    int actual_exit_code =
167        (usage_exit_code == EX_USAGE) ? EXIT_SUCCESS : usage_exit_code;
168
169    displayEnum = AG_FALSE;
170
171    /*
172     *  Paged usage will preset option_usage_fp to an output file.
173     *  If it hasn't already been set, then set it to standard output
174     *  on successful exit (help was requested), otherwise error out.
175     *
176     *  Test the version before obtaining pzFullUsage or pzShortUsage.
177     *  These fields do not exist before revision 30.
178     */
179    {
180        char const * pz;
181
182        if (actual_exit_code == EXIT_SUCCESS) {
183            pz = (pOptions->structVersion >= 30 * 4096)
184                ? pOptions->pzFullUsage : NULL;
185
186            if (option_usage_fp == NULL)
187                option_usage_fp = stdout;
188        } else {
189            pz = (pOptions->structVersion >= 30 * 4096)
190                ? pOptions->pzShortUsage : NULL;
191
192            if (option_usage_fp == NULL)
193                option_usage_fp = stderr;
194        }
195
196        if (pz != NULL) {
197            fputs(pz, option_usage_fp);
198            exit(actual_exit_code);
199        }
200    }
201
202    fprintf( option_usage_fp, pOptions->pzUsageTitle, pOptions->pzProgName );
203
204    {
205        tCC* pOptTitle = NULL;
206
207        /*
208         *  Determine which header and which option formatting strings to use
209         */
210        if (checkGNUUsage(pOptions)) {
211            int flen = setGnuOptFmts( pOptions, &pOptTitle );
212            sprintf( zOptFmtLine, zFmtFmt, flen );
213            fputc( '\n', option_usage_fp );
214        }
215        else {
216            int flen = setStdOptFmts( pOptions, &pOptTitle );
217            sprintf( zOptFmtLine, zFmtFmt, flen );
218
219            /*
220             *  When we exit with EXIT_SUCCESS and the first option is a doc
221             *  option, we do *NOT* want to emit the column headers.
222             *  Otherwise, we do.
223             */
224            if (  (usage_exit_code != EXIT_SUCCESS)
225               || ((pOptions->pOptDesc->fOptState & OPTST_DOCUMENT) == 0) )
226
227                fputs( pOptTitle, option_usage_fp );
228        }
229
230        printOptionUsage( pOptions, usage_exit_code, pOptTitle );
231    }
232
233    /*
234     *  Describe the mechanics of denoting the options
235     */
236    switch (pOptions->fOptSet & OPTPROC_L_N_S) {
237    case OPTPROC_L_N_S:     fputs( zFlagOkay, option_usage_fp ); break;
238    case OPTPROC_SHORTOPT:  break;
239    case OPTPROC_LONGOPT:   fputs( zNoFlags,  option_usage_fp ); break;
240    case 0:                 fputs( zOptsOnly, option_usage_fp ); break;
241    }
242
243    if ((pOptions->fOptSet & OPTPROC_NUM_OPT) != 0) {
244        fputs( zNumberOpt, option_usage_fp );
245    }
246
247    if ((pOptions->fOptSet & OPTPROC_REORDER) != 0) {
248        fputs( zReorder, option_usage_fp );
249    }
250
251    if (pOptions->pzExplain != NULL)
252        fputs( pOptions->pzExplain, option_usage_fp );
253
254    /*
255     *  IF the user is asking for help (thus exiting with SUCCESS),
256     *  THEN see what additional information we can provide.
257     */
258    if (usage_exit_code == EXIT_SUCCESS)
259        printProgramDetails( pOptions );
260
261    if (pOptions->pzBugAddr != NULL)
262        fprintf( option_usage_fp, zPlsSendBugs, pOptions->pzBugAddr );
263    fflush( option_usage_fp );
264
265    exit( actual_exit_code );
266}
267
268
269/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
270 *
271 *   PER OPTION TYPE USAGE INFORMATION
272 */
273static void
274printExtendedUsage(
275    tOptions*     pOptions,
276    tOptDesc*     pOD,
277    arg_types_t*  pAT )
278{
279    /*
280     *  IF there are option conflicts or dependencies,
281     *  THEN print them here.
282     */
283    if (  (pOD->pOptMust != NULL)
284       || (pOD->pOptCant != NULL) ) {
285
286        fputs( zTabHyp, option_usage_fp );
287
288        /*
289         *  DEPENDENCIES:
290         */
291        if (pOD->pOptMust != NULL) {
292            const int* pOptNo = pOD->pOptMust;
293
294            fputs( zReqThese, option_usage_fp );
295            for (;;) {
296                fprintf( option_usage_fp, zTabout, pOptions->pOptDesc[
297                             *pOptNo ].pz_Name );
298                if (*++pOptNo == NO_EQUIVALENT)
299                    break;
300            }
301
302            if (pOD->pOptCant != NULL)
303                fputs( zTabHypAnd, option_usage_fp );
304        }
305
306        /*
307         *  CONFLICTS:
308         */
309        if (pOD->pOptCant != NULL) {
310            const int* pOptNo = pOD->pOptCant;
311
312            fputs( zProhib, option_usage_fp );
313            for (;;) {
314                fprintf( option_usage_fp, zTabout, pOptions->pOptDesc[
315                             *pOptNo ].pz_Name );
316                if (*++pOptNo == NO_EQUIVALENT)
317                    break;
318            }
319        }
320    }
321
322    /*
323     *  IF there is a disablement string
324     *  THEN print the disablement info
325     */
326    if (pOD->pz_DisableName != NULL )
327        fprintf( option_usage_fp, zDis, pOD->pz_DisableName );
328
329    /*
330     *  Check for argument types that have callbacks with magical properties
331     */
332    switch (OPTST_GET_ARGTYPE(pOD->fOptState)) {
333    case OPARG_TYPE_NUMERIC:
334        /*
335         *  IF the numeric option has a special callback,
336         *  THEN call it, requesting the range or other special info
337         */
338        if (  (pOD->pOptProc != NULL)
339           && (pOD->pOptProc != optionNumericVal) ) {
340            (*(pOD->pOptProc))(OPTPROC_EMIT_USAGE, pOD);
341        }
342        break;
343
344    case OPARG_TYPE_FILE:
345        (*(pOD->pOptProc))(OPTPROC_EMIT_USAGE, pOD);
346        break;
347    }
348
349    /*
350     *  IF the option defaults to being enabled,
351     *  THEN print that out
352     */
353    if (pOD->fOptState & OPTST_INITENABLED)
354        fputs( zEnab, option_usage_fp );
355
356    /*
357     *  IF  the option is in an equivalence class
358     *        AND not the designated lead
359     *  THEN print equivalence and leave it at that.
360     */
361    if (  (pOD->optEquivIndex != NO_EQUIVALENT)
362       && (pOD->optEquivIndex != pOD->optActualIndex )  )  {
363        fprintf( option_usage_fp, zAlt,
364                 pOptions->pOptDesc[ pOD->optEquivIndex ].pz_Name );
365        return;
366    }
367
368    /*
369     *  IF this particular option can NOT be preset
370     *    AND some form of presetting IS allowed,
371     *    AND it is not an auto-managed option (e.g. --help, et al.)
372     *  THEN advise that this option may not be preset.
373     */
374    if (  ((pOD->fOptState & OPTST_NO_INIT) != 0)
375       && (  (pOptions->papzHomeList != NULL)
376          || (pOptions->pzPROGNAME != NULL)
377          )
378       && (pOD->optIndex < pOptions->presetOptCt)
379       )
380
381        fputs( zNoPreset, option_usage_fp );
382
383    /*
384     *  Print the appearance requirements.
385     */
386    if (OPTST_GET_ARGTYPE(pOD->fOptState) == OPARG_TYPE_MEMBERSHIP)
387        fputs( zMembers, option_usage_fp );
388
389    else switch (pOD->optMinCt) {
390    case 1:
391    case 0:
392        switch (pOD->optMaxCt) {
393        case 0:       fputs( zPreset, option_usage_fp ); break;
394        case NOLIMIT: fputs( zNoLim, option_usage_fp );  break;
395        case 1:       break;
396            /*
397             * IF the max is more than one but limited, print "UP TO" message
398             */
399        default:      fprintf( option_usage_fp, zUpTo, pOD->optMaxCt );  break;
400        }
401        break;
402
403    default:
404        /*
405         *  More than one is required.  Print the range.
406         */
407        fprintf( option_usage_fp, zMust, pOD->optMinCt, pOD->optMaxCt );
408    }
409
410    if (  NAMED_OPTS( pOptions )
411       && (pOptions->specOptIdx.default_opt == pOD->optIndex))
412        fputs( zDefaultOpt, option_usage_fp );
413}
414
415
416/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
417 *
418 *   Figure out where all the initialization files might live.
419 *   This requires translating some environment variables and
420 *   testing to see if a name is a directory or a file.  It's
421 *   squishy, but important to tell users how to find these files.
422 */
423static void
424printInitList(
425    tCC* const* papz,
426    ag_bool*    pInitIntro,
427    tCC*        pzRc,
428    tCC*        pzPN )
429{
430    char zPath[ AG_PATH_MAX+1 ];
431
432    if (papz == NULL)
433        return;
434
435    fputs( zPresetIntro, option_usage_fp );
436    *pInitIntro = AG_FALSE;
437
438    for (;;) {
439        char const* pzPath = *(papz++);
440
441        if (pzPath == NULL)
442            break;
443
444        if (optionMakePath(zPath, (int)sizeof( zPath ), pzPath, pzPN))
445            pzPath = zPath;
446
447        /*
448         *  Print the name of the "homerc" file.  If the "rcfile" name is
449         *  not empty, we may or may not print that, too...
450         */
451        fprintf( option_usage_fp, zPathFmt, pzPath );
452        if (*pzRc != NUL) {
453            struct stat sb;
454
455            /*
456             *  IF the "homerc" file is a directory,
457             *  then append the "rcfile" name.
458             */
459            if (  (stat( pzPath, &sb ) == 0)
460              &&  S_ISDIR( sb.st_mode ) ) {
461                fputc( DIRCH, option_usage_fp );
462                fputs( pzRc, option_usage_fp );
463            }
464        }
465
466        fputc( '\n', option_usage_fp );
467    }
468}
469
470
471static void
472printOptPreamble(
473    tOptions*     pOptions,
474    tOptDesc*     pOD,
475    arg_types_t*  pAT )
476{
477    /*
478     *  Flag prefix: IF no flags at all, then omit it.  If not printable
479     *  (not allowed for this option), then blank, else print it.
480     *  Follow it with a comma if we are doing GNU usage and long
481     *  opts are to be printed too.
482     */
483    if ((pOptions->fOptSet & OPTPROC_SHORTOPT) == 0)
484        fputs( pAT->pzSpc, option_usage_fp );
485
486    else if (! IS_GRAPHIC_CHAR(pOD->optValue)) {
487        if (  (pOptions->fOptSet & (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT))
488           == (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT))
489            fputc( ' ', option_usage_fp );
490        fputs( pAT->pzNoF, option_usage_fp );
491
492    } else {
493        fprintf( option_usage_fp, "   -%c", pOD->optValue );
494        if (  (pOptions->fOptSet & (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT))
495           == (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT))
496            fputs( ", ", option_usage_fp );
497    }
498}
499
500/*
501 *  Print the usage information for a single option.
502 */
503static void
504printOneUsage(
505    tOptions*     pOptions,
506    tOptDesc*     pOD,
507    arg_types_t*  pAT )
508{
509    printOptPreamble(pOptions, pOD, pAT);
510
511    {
512        char  z[ 80 ];
513        tCC*  pzArgType;
514        /*
515         *  Determine the argument type string first on its usage, then,
516         *  when the option argument is required, base the type string on the
517         *  argument type.
518         */
519        if (pOD->fOptState & OPTST_ARG_OPTIONAL) {
520            pzArgType = pAT->pzOpt;
521
522        } else switch (OPTST_GET_ARGTYPE(pOD->fOptState)) {
523        case OPARG_TYPE_NONE:        pzArgType = pAT->pzNo;   break;
524        case OPARG_TYPE_ENUMERATION: pzArgType = pAT->pzKey;  break;
525        case OPARG_TYPE_FILE       : pzArgType = pAT->pzFile; break;
526        case OPARG_TYPE_MEMBERSHIP:  pzArgType = pAT->pzKeyL; break;
527        case OPARG_TYPE_BOOLEAN:     pzArgType = pAT->pzBool; break;
528        case OPARG_TYPE_NUMERIC:     pzArgType = pAT->pzNum;  break;
529        case OPARG_TYPE_HIERARCHY:   pzArgType = pAT->pzNest; break;
530        case OPARG_TYPE_STRING:      pzArgType = pAT->pzStr;  break;
531        case OPARG_TYPE_TIME:        pzArgType = pAT->pzTime; break;
532        default:                     goto bogus_desc;
533        }
534
535        snprintf( z, sizeof(z), pAT->pzOptFmt, pzArgType, pOD->pz_Name,
536                  (pOD->optMinCt != 0) ? pAT->pzReq : pAT->pzOpt );
537
538        fprintf( option_usage_fp, zOptFmtLine, z, pOD->pzText );
539
540        switch (OPTST_GET_ARGTYPE(pOD->fOptState)) {
541        case OPARG_TYPE_ENUMERATION:
542        case OPARG_TYPE_MEMBERSHIP:
543            displayEnum = (pOD->pOptProc != NULL) ? AG_TRUE : displayEnum;
544        }
545    }
546    return;
547
548 bogus_desc:
549    fprintf( stderr, zInvalOptDesc, pOD->pz_Name );
550    exit( EX_SOFTWARE );
551}
552
553
554/*
555 *  Print out the usage information for just the options.
556 */
557static void
558printOptionUsage(
559    tOptions *  pOpts,
560    int         ex_code,
561    tCC *       pOptTitle )
562{
563    int         ct     = pOpts->optCt;
564    int         optNo  = 0;
565    tOptDesc *  pOD    = pOpts->pOptDesc;
566    int         docCt  = 0;
567
568    do  {
569        if ((pOD->fOptState & OPTST_NO_USAGE_MASK) != 0) {
570
571            /*
572             * IF      this is a compiled-out option
573             *   *AND* usage was requested with "omitted-usage"
574             *   *AND* this is NOT abbreviated usage
575             * THEN display this option.
576             */
577            if (  (pOD->fOptState == (OPTST_OMITTED | OPTST_NO_INIT))
578               && (pOD->pz_Name != NULL)
579               && (ex_code == EXIT_SUCCESS))  {
580
581                char const * why_pz =
582                    (pOD->pzText == NULL) ? zDisabledWhy : pOD->pzText;
583                printOptPreamble(pOpts, pOD, &argTypes);
584                fprintf(option_usage_fp, zDisabledOpt, pOD->pz_Name, why_pz);
585            }
586
587            continue;
588        }
589
590        if ((pOD->fOptState & OPTST_DOCUMENT) != 0) {
591            if (ex_code == EXIT_SUCCESS) {
592                fprintf(option_usage_fp, argTypes.pzBrk, pOD->pzText,
593                        pOptTitle);
594                docCt++;
595            }
596
597            continue;
598        }
599
600        /*
601         *  IF       this is the first auto-opt maintained option
602         *    *AND*  we are doing a full help
603         *    *AND*  there are documentation options
604         *    *AND*  the last one was not a doc option,
605         *  THEN document that the remaining options are not user opts
606         */
607        if (  (pOpts->presetOptCt == optNo)
608           && (ex_code == EXIT_SUCCESS)
609           && (docCt > 0)
610           && ((pOD[-1].fOptState & OPTST_DOCUMENT) == 0) )
611            fprintf( option_usage_fp, argTypes.pzBrk, zAuto, pOptTitle );
612
613        printOneUsage(pOpts, pOD, &argTypes);
614
615        /*
616         *  IF we were invoked because of the --help option,
617         *  THEN print all the extra info
618         */
619        if (ex_code == EXIT_SUCCESS)
620            printExtendedUsage( pOpts, pOD, &argTypes );
621
622    }  while (pOD++, optNo++, (--ct > 0));
623
624    fputc( '\n', option_usage_fp );
625}
626
627
628/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
629 *
630 *   PROGRAM DETAILS
631 */
632static void
633printProgramDetails( tOptions* pOptions )
634{
635    ag_bool  initIntro = AG_TRUE;
636
637    /*
638     *  Display all the places we look for config files
639     */
640    printInitList( pOptions->papzHomeList, &initIntro,
641                   pOptions->pzRcName, pOptions->pzProgPath );
642
643    /*
644     *  Let the user know about environment variable settings
645     */
646    if ((pOptions->fOptSet & OPTPROC_ENVIRON) != 0) {
647        if (initIntro)
648            fputs( zPresetIntro, option_usage_fp );
649
650        fprintf( option_usage_fp, zExamineFmt, pOptions->pzPROGNAME );
651    }
652
653    /*
654     *  IF we found an enumeration,
655     *  THEN hunt for it again.  Call the handler proc with a NULL
656     *       option struct pointer.  That tells it to display the keywords.
657     */
658    if (displayEnum) {
659        int        ct     = pOptions->optCt;
660        int        optNo  = 0;
661        tOptDesc*  pOD    = pOptions->pOptDesc;
662
663        fputc( '\n', option_usage_fp );
664        fflush( option_usage_fp );
665        do  {
666            switch (OPTST_GET_ARGTYPE(pOD->fOptState)) {
667            case OPARG_TYPE_ENUMERATION:
668            case OPARG_TYPE_MEMBERSHIP:
669                (*(pOD->pOptProc))(OPTPROC_EMIT_USAGE, pOD);
670            }
671        }  while (pOD++, optNo++, (--ct > 0));
672    }
673
674    /*
675     *  If there is a detail string, now is the time for that.
676     */
677    if (pOptions->pzDetail != NULL)
678        fputs( pOptions->pzDetail, option_usage_fp );
679}
680
681
682/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
683 *
684 *   OPTION LINE FORMATTING SETUP
685 *
686 *  The "OptFmt" formats receive three arguments:
687 *  1.  the type of the option's argument
688 *  2.  the long name of the option
689 *  3.  "YES" or "no ", depending on whether or not the option must appear
690 *      on the command line.
691 *  These formats are used immediately after the option flag (if used) has
692 *  been printed.
693 *
694 *  Set up the formatting for GNU-style output
695 */
696static int
697setGnuOptFmts( tOptions* pOpts, tCC** ppT )
698{
699    int  flen = 22;
700    *ppT = zNoRq_ShrtTtl;
701
702    argTypes.pzStr  = zGnuStrArg;
703    argTypes.pzReq  = zOneSpace;
704    argTypes.pzNum  = zGnuNumArg;
705    argTypes.pzKey  = zGnuKeyArg;
706    argTypes.pzKeyL = zGnuKeyLArg;
707    argTypes.pzTime = zGnuTimeArg;
708    argTypes.pzFile = zGnuFileArg;
709    argTypes.pzBool = zGnuBoolArg;
710    argTypes.pzNest = zGnuNestArg;
711    argTypes.pzOpt  = zGnuOptArg;
712    argTypes.pzNo   = zOneSpace;
713    argTypes.pzBrk  = zGnuBreak;
714    argTypes.pzNoF  = zSixSpaces;
715    argTypes.pzSpc  = zThreeSpaces;
716
717    switch (pOpts->fOptSet & OPTPROC_L_N_S) {
718    case OPTPROC_L_N_S:    argTypes.pzOptFmt = zGnuOptFmt;     break;
719    case OPTPROC_LONGOPT:  argTypes.pzOptFmt = zGnuOptFmt;     break;
720    case 0:                argTypes.pzOptFmt = zGnuOptFmt + 2; break;
721    case OPTPROC_SHORTOPT:
722        argTypes.pzOptFmt = zShrtGnuOptFmt;
723        zGnuStrArg[0] = zGnuNumArg[0] = zGnuKeyArg[0] = zGnuBoolArg[0] = ' ';
724        argTypes.pzOpt = " [arg]";
725        flen = 8;
726        break;
727    }
728
729    return flen;
730}
731
732
733/*
734 *  Standard (AutoOpts normal) option line formatting
735 */
736static int
737setStdOptFmts( tOptions* pOpts, tCC** ppT )
738{
739    int  flen = 0;
740
741    argTypes.pzStr  = zStdStrArg;
742    argTypes.pzReq  = zStdReqArg;
743    argTypes.pzNum  = zStdNumArg;
744    argTypes.pzKey  = zStdKeyArg;
745    argTypes.pzKeyL = zStdKeyLArg;
746    argTypes.pzTime = zStdTimeArg;
747    argTypes.pzFile = zStdFileArg;
748    argTypes.pzBool = zStdBoolArg;
749    argTypes.pzNest = zStdNestArg;
750    argTypes.pzOpt  = zStdOptArg;
751    argTypes.pzNo   = zStdNoArg;
752    argTypes.pzBrk  = zStdBreak;
753    argTypes.pzNoF  = zFiveSpaces;
754    argTypes.pzSpc  = zTwoSpaces;
755
756    switch (pOpts->fOptSet & (OPTPROC_NO_REQ_OPT | OPTPROC_SHORTOPT)) {
757    case (OPTPROC_NO_REQ_OPT | OPTPROC_SHORTOPT):
758        *ppT = zNoRq_ShrtTtl;
759        argTypes.pzOptFmt = zNrmOptFmt;
760        flen = 19;
761        break;
762
763    case OPTPROC_NO_REQ_OPT:
764        *ppT = zNoRq_NoShrtTtl;
765        argTypes.pzOptFmt = zNrmOptFmt;
766        flen = 19;
767        break;
768
769    case OPTPROC_SHORTOPT:
770        *ppT = zReq_ShrtTtl;
771        argTypes.pzOptFmt = zReqOptFmt;
772        flen = 24;
773        break;
774
775    case 0:
776        *ppT = zReq_NoShrtTtl;
777        argTypes.pzOptFmt = zReqOptFmt;
778        flen = 24;
779    }
780
781    return flen;
782}
783
784
785/*:
786 * Local Variables:
787 * mode: C
788 * c-file-style: "stroustrup"
789 * indent-tabs-mode: nil
790 * End:
791 * end of autoopts/usage.c */
792