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