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