Coverage Report

Created: 2023-05-19 06:16

/src/ntp-dev/sntp/libopts/usage.c
Line
Count
Source (jump to first uncovered line)
1
2
/*
3
 * \file usage.c
4
 *
5
 *  This module implements the default usage procedure for
6
 *  Automated Options.  It may be overridden, of course.
7
 *
8
 * @addtogroup autoopts
9
 * @{
10
 */
11
/*
12
 *  Sort options:
13
    --start=END-[S]TATIC-FORWARD --patt='^/\*($|[^:])' \
14
    --out=xx.c key='^[a-zA-Z0-9_]+\(' --trail='^/\*:' \
15
    --spac=2 --input=usage.c
16
 */
17
18
/*
19
 *  This file is part of AutoOpts, a companion to AutoGen.
20
 *  AutoOpts is free software.
21
 *  AutoOpts is Copyright (C) 1992-2015 by Bruce Korb - all rights reserved
22
 *
23
 *  AutoOpts is available under any one of two licenses.  The license
24
 *  in use must be one of these two and the choice is under the control
25
 *  of the user of the license.
26
 *
27
 *   The GNU Lesser General Public License, version 3 or later
28
 *      See the files "COPYING.lgplv3" and "COPYING.gplv3"
29
 *
30
 *   The Modified Berkeley Software Distribution License
31
 *      See the file "COPYING.mbsd"
32
 *
33
 *  These files have the following sha256 sums:
34
 *
35
 *  8584710e9b04216a394078dc156b781d0b47e1729104d666658aecef8ee32e95  COPYING.gplv3
36
 *  4379e7444a0e2ce2b12dd6f5a52a27a4d02d39d247901d3285c88cf0d37f477b  COPYING.lgplv3
37
 *  13aa749a5b0a454917a944ed8fffc530b784f5ead522b1aacaf4ec8aa55a6239  COPYING.mbsd
38
 */
39
40
/* = = = START-STATIC-FORWARD = = = */
41
static unsigned int
42
parse_usage_flags(ao_flag_names_t const * fnt, char const * txt);
43
44
static inline bool
45
do_gnu_usage(tOptions * pOpts);
46
47
static inline bool
48
skip_misuse_usage(tOptions * pOpts);
49
50
static void
51
print_offer_usage(tOptions * opts);
52
53
static void
54
print_usage_details(tOptions * opts, int exit_code);
55
56
static void
57
print_one_paragraph(char const * text, bool plain, FILE * fp);
58
59
static void
60
prt_conflicts(tOptions * opts, tOptDesc * od);
61
62
static void
63
prt_one_vendor(tOptions *    opts,  tOptDesc *   od,
64
               arg_types_t * argtp, char const * usefmt);
65
66
static void
67
prt_vendor_opts(tOptions * opts, char const * title);
68
69
static void
70
prt_extd_usage(tOptions * opts, tOptDesc * od, char const * title);
71
72
static void
73
prt_ini_list(char const * const * papz, char const * ini_file,
74
             char const * path_nm);
75
76
static void
77
prt_preamble(tOptions * opts, tOptDesc * od, arg_types_t * at);
78
79
static void
80
prt_one_usage(tOptions * opts, tOptDesc * od, arg_types_t * at);
81
82
static void
83
prt_opt_usage(tOptions * opts, int ex_code, char const * title);
84
85
static void
86
prt_prog_detail(tOptions * opts);
87
88
static int
89
setGnuOptFmts(tOptions * opts, char const ** ptxt);
90
91
static int
92
setStdOptFmts(tOptions * opts, char const ** ptxt);
93
/* = = = END-STATIC-FORWARD = = = */
94
95
/**
96
 * Parse the option usage flags string.  Any parsing problems yield
97
 * a zero (no flags set) result.  This function is internal to
98
 * set_usage_flags().
99
 *
100
 * @param[in] fnt   Flag Name Table - maps a name to a mask
101
 * @param[in] txt   the text to process.  If NULL, then
102
 *                  getenv("AUTOOPTS_USAGE") is used.
103
 * @returns a bit mask indicating which \a fnt entries were found.
104
 */
105
static unsigned int
106
parse_usage_flags(ao_flag_names_t const * fnt, char const * txt)
107
0
{
108
0
    unsigned int res = 0;
109
110
    /*
111
     * The text may be passed in.  If not, use the environment variable.
112
     */
113
0
    if (txt == NULL) {
114
0
        txt = getenv("AUTOOPTS_USAGE");
115
0
        if (txt == NULL)
116
0
            return 0;
117
0
    }
118
119
0
    txt = SPN_WHITESPACE_CHARS(txt);
120
0
    if (*txt == NUL)
121
0
        return 0;
122
123
    /*
124
     * search the string for table entries.  We must understand everything
125
     * we see in the string, or we give up on it.
126
     */
127
0
    for (;;) {
128
0
        int ix = 0;
129
130
0
        for (;;) {
131
0
            if (strneqvcmp(txt, fnt[ix].fnm_name, (int)fnt[ix].fnm_len) == 0)
132
0
                break;
133
0
            if (++ix >= AOUF_COUNT)
134
0
                return 0;
135
0
        }
136
137
        /*
138
         *  Make sure we have a full match.  Look for whitespace,
139
         *  a comma, or a NUL byte.
140
         */
141
0
        if (! IS_END_LIST_ENTRY_CHAR(txt[fnt[ix].fnm_len]))
142
0
            return 0;
143
144
0
        res |= 1U << ix;
145
0
        txt = SPN_WHITESPACE_CHARS(txt + fnt[ix].fnm_len);
146
147
0
        switch (*txt) {
148
0
        case NUL:
149
0
            return res;
150
151
0
        case ',':
152
0
            txt = SPN_WHITESPACE_CHARS(txt + 1);
153
            /* Something must follow the comma */
154
155
0
        default:
156
0
            continue;
157
0
        }
158
0
    }
159
0
}
160
161
/**
162
 * Set option usage flags.  Any parsing problems yield no changes to options.
163
 * Three different bits may be fiddled: \a OPTPROC_GNUUSAGE, \a OPTPROC_MISUSE
164
 * and \a OPTPROC_COMPUTE.
165
 *
166
 * @param[in] flg_txt   text to parse.  If NULL, then the AUTOOPTS_USAGE
167
 *                      environment variable is parsed.
168
 * @param[in,out] opts  the program option descriptor
169
 */
170
LOCAL void
171
set_usage_flags(tOptions * opts, char const * flg_txt)
172
0
{
173
0
#   define _aof_(_n, _f)   { sizeof(#_n)-1, _f, #_n },
174
0
    static ao_flag_names_t const fn_table[AOUF_COUNT] = {
175
0
        AOFLAG_TABLE
176
0
    };
177
0
#   undef  _aof_
178
179
    /*
180
     * the flag word holds a bit for each selected table entry.
181
     */
182
0
    unsigned int flg = parse_usage_flags(fn_table, flg_txt);
183
0
    if (flg == 0) return;
184
185
    /*
186
     * Ensure we do not have conflicting selections
187
     */
188
0
    {
189
0
        static unsigned int const form_mask =
190
0
            AOUF_gnu | AOUF_autoopts;
191
0
        static unsigned int const misuse_mask =
192
0
            AOUF_no_misuse_usage | AOUF_misuse_usage;
193
0
        if (  ((flg & form_mask)   == form_mask)
194
0
           || ((flg & misuse_mask) == misuse_mask) )
195
0
            return;
196
0
    }
197
198
    /*
199
     * Now fiddle the fOptSet bits, based on settings.
200
     * The OPTPROC_LONGOPT bit is immutable, thus if it is set,
201
     * then fnm points to a mask off mask.
202
     */
203
0
    {
204
0
        ao_flag_names_t const * fnm = fn_table;
205
0
        for (;;) {
206
0
            if ((flg & 1) != 0) {
207
0
                if ((fnm->fnm_mask & OPTPROC_LONGOPT) != 0)
208
0
                     opts->fOptSet &= fnm->fnm_mask;
209
0
                else opts->fOptSet |= fnm->fnm_mask;
210
0
            }
211
0
            flg >>= 1;
212
0
            if (flg == 0)
213
0
                break;
214
0
            fnm++;
215
0
        }
216
0
    }
217
0
}
218
219
/*
220
 *  Figure out if we should try to format usage text sort-of like
221
 *  the way many GNU programs do.
222
 */
223
static inline bool
224
do_gnu_usage(tOptions * pOpts)
225
0
{
226
0
    return (pOpts->fOptSet & OPTPROC_GNUUSAGE) ? true : false;
227
0
}
228
229
/*
230
 *  Figure out if we should try to format usage text sort-of like
231
 *  the way many GNU programs do.
232
 */
233
static inline bool
234
skip_misuse_usage(tOptions * pOpts)
235
0
{
236
0
    return (pOpts->fOptSet & OPTPROC_MISUSE) ? true : false;
237
0
}
238
239
240
/*=export_func  optionOnlyUsage
241
 *
242
 * what:  Print usage text for just the options
243
 * arg:   + tOptions *  + pOpts    + program options descriptor +
244
 * arg:   + int         + ex_code  + exit code for calling exit(3) +
245
 *
246
 * doc:
247
 *  This routine will print only the usage for each option.
248
 *  This function may be used when the emitted usage must incorporate
249
 *  information not available to AutoOpts.
250
=*/
251
void
252
optionOnlyUsage(tOptions * pOpts, int ex_code)
253
0
{
254
0
    char const * pOptTitle = NULL;
255
256
0
    set_usage_flags(pOpts, NULL);
257
0
    if ((ex_code != EXIT_SUCCESS) &&
258
0
        skip_misuse_usage(pOpts))
259
0
        return;
260
261
    /*
262
     *  Determine which header and which option formatting strings to use
263
     */
264
0
    if (do_gnu_usage(pOpts))
265
0
        (void)setGnuOptFmts(pOpts, &pOptTitle);
266
0
    else
267
0
        (void)setStdOptFmts(pOpts, &pOptTitle);
268
269
0
    prt_opt_usage(pOpts, ex_code, pOptTitle);
270
271
0
    fflush(option_usage_fp);
272
0
    if (ferror(option_usage_fp) != 0)
273
0
        fserr_exit(pOpts->pzProgName, zwriting, (option_usage_fp == stderr)
274
0
                   ? zstderr_name : zstdout_name);
275
0
}
276
277
/**
278
 * Print a message suggesting how to get help.
279
 *
280
 * @param[in] opts      the program options
281
 */
282
static void
283
print_offer_usage(tOptions * opts)
284
0
{
285
0
    char help[24];
286
287
0
    if (HAS_opt_usage_t(opts)) {
288
0
        int ix = opts->presetOptCt;
289
0
        tOptDesc * od = opts->pOptDesc + ix;
290
0
        while (od->optUsage != AOUSE_HELP) {
291
0
            if (++ix >= opts->optCt)
292
0
                ao_bug(zmissing_help_msg);
293
0
            od++;
294
0
        }
295
0
        switch (opts->fOptSet & (OPTPROC_LONGOPT | OPTPROC_SHORTOPT)) {
296
0
        case OPTPROC_SHORTOPT:
297
0
            help[0] = '-';
298
0
            help[1] = od->optValue;
299
0
            help[2] = NUL;
300
0
            break;
301
302
0
        case OPTPROC_LONGOPT:
303
0
        case (OPTPROC_LONGOPT | OPTPROC_SHORTOPT):
304
0
            help[0] = help[1] = '-';
305
0
            strncpy(help + 2, od->pz_Name, 20);
306
0
            break;
307
        
308
0
        case 0:
309
0
            strncpy(help, od->pz_Name, 20);
310
0
            break;
311
0
        }
312
313
0
    } else {
314
0
        switch (opts->fOptSet & (OPTPROC_LONGOPT | OPTPROC_SHORTOPT)) {
315
0
        case OPTPROC_SHORTOPT:
316
0
            strcpy(help, "-h");
317
0
            break;
318
319
0
        case OPTPROC_LONGOPT:
320
0
        case (OPTPROC_LONGOPT | OPTPROC_SHORTOPT):
321
0
            strcpy(help, "--help");
322
0
            break;
323
        
324
0
        case 0:
325
0
            strcpy(help, "help");
326
0
            break;
327
0
        }
328
0
    }
329
330
0
    fprintf(option_usage_fp, zoffer_usage_fmt, opts->pzProgName, help);
331
0
}
332
333
/**
334
 * Print information about each option.
335
 *
336
 * @param[in] opts      the program options
337
 * @param[in] exit_code whether or not there was a usage error reported.
338
 *                      used to select full usage versus abbreviated.
339
 */
340
static void
341
print_usage_details(tOptions * opts, int exit_code)
342
0
{
343
0
    {
344
0
        char const * pOptTitle = NULL;
345
0
        int flen;
346
347
        /*
348
         *  Determine which header and which option formatting strings to use
349
         */
350
0
        if (do_gnu_usage(opts)) {
351
0
            flen = setGnuOptFmts(opts, &pOptTitle);
352
0
            sprintf(line_fmt_buf, zFmtFmt, flen);
353
0
            fputc(NL, option_usage_fp);
354
0
        }
355
0
        else {
356
0
            flen = setStdOptFmts(opts, &pOptTitle);
357
0
            sprintf(line_fmt_buf, zFmtFmt, flen);
358
359
            /*
360
             *  When we exit with EXIT_SUCCESS and the first option is a doc
361
             *  option, we do *NOT* want to emit the column headers.
362
             *  Otherwise, we do.
363
             */
364
0
            if (  (exit_code != EXIT_SUCCESS)
365
0
               || ((opts->pOptDesc->fOptState & OPTST_DOCUMENT) == 0) )
366
367
0
                fputs(pOptTitle, option_usage_fp);
368
0
        }
369
370
0
        flen = 4 - ((flen + 15) / 8);
371
0
        if (flen > 0)
372
0
            tab_skip_ct = flen;
373
0
        prt_opt_usage(opts, exit_code, pOptTitle);
374
0
    }
375
376
    /*
377
     *  Describe the mechanics of denoting the options
378
     */
379
0
    switch (opts->fOptSet & OPTPROC_L_N_S) {
380
0
    case OPTPROC_L_N_S:     fputs(zFlagOkay, option_usage_fp); break;
381
0
    case OPTPROC_SHORTOPT:  break;
382
0
    case OPTPROC_LONGOPT:   fputs(zNoFlags,  option_usage_fp); break;
383
0
    case 0:                 fputs(zOptsOnly, option_usage_fp); break;
384
0
    }
385
386
0
    if ((opts->fOptSet & OPTPROC_NUM_OPT) != 0)
387
0
        fputs(zNumberOpt, option_usage_fp);
388
389
0
    if ((opts->fOptSet & OPTPROC_REORDER) != 0)
390
0
        fputs(zReorder, option_usage_fp);
391
392
0
    if (opts->pzExplain != NULL)
393
0
        fputs(opts->pzExplain, option_usage_fp);
394
395
    /*
396
     *  IF the user is asking for help (thus exiting with SUCCESS),
397
     *  THEN see what additional information we can provide.
398
     */
399
0
    if (exit_code == EXIT_SUCCESS)
400
0
        prt_prog_detail(opts);
401
402
    /*
403
     * Give bug notification preference to the packager information
404
     */
405
0
    if (HAS_pzPkgDataDir(opts) && (opts->pzPackager != NULL))
406
0
        fputs(opts->pzPackager, option_usage_fp);
407
408
0
    else if (opts->pzBugAddr != NULL)
409
0
        fprintf(option_usage_fp, zPlsSendBugs, opts->pzBugAddr);
410
411
0
    fflush(option_usage_fp);
412
413
0
    if (ferror(option_usage_fp) != 0)
414
0
        fserr_exit(opts->pzProgName, zwriting, (option_usage_fp == stderr)
415
0
                   ? zstderr_name : zstdout_name);
416
0
}
417
418
static void
419
print_one_paragraph(char const * text, bool plain, FILE * fp)
420
0
{
421
0
    if (plain) {
422
#ifdef ENABLE_NLS
423
#ifdef HAVE_LIBINTL_H
424
#ifdef DEBUG_ENABLED
425
#undef gettext
426
#endif
427
        char * buf = dgettext("libopts", text);
428
        if (buf == text)
429
            text = gettext(text);
430
#endif /* HAVE_LIBINTL_H */
431
#endif /* ENABLE_NLS */
432
0
        fputs(text, fp);
433
0
    }
434
435
0
    else {
436
0
        char const * t = optionQuoteString(text, LINE_SPLICE);
437
0
        fprintf(fp, PUTS_FMT, t);
438
0
        AGFREE(t);
439
0
    }
440
0
}
441
 
442
/*=export_func  optionPrintParagraphs
443
 * private:
444
 *
445
 * what:  Print a paragraph of usage text
446
 * arg:   + char const * + text  + a block of text that has bee i18n-ed +
447
 * arg:   + bool         + plain + false -> wrap text in fputs()        +
448
 * arg:   + FILE *       + fp    + the stream file pointer for output   +
449
 *
450
 * doc:
451
 *  This procedure is called in two contexts: when a full or short usage text
452
 *  has been provided for display, and when autogen is assembling a list of
453
 *  translatable texts in the optmain.tlib template.  In the former case, \a
454
 *  plain is set to \a true, otherwise \a false.
455
 *
456
 *  Anything less than 256 characters in size is printed as a single unit.
457
 *  Otherwise, paragraphs are detected.  A paragraph break is defined as just
458
 *  before a non-empty line preceded by two newlines or a line that starts
459
 *  with at least one space character but fewer than 8 space characters.
460
 *  Lines indented with tabs or more than 7 spaces are considered continuation
461
 *  lines.
462
 *
463
 *  If 'plain' is true, we are emitting text for a user to see.  So, if it is
464
 *  true and NLS is not enabled, then just write the whole thing at once.
465
=*/
466
void
467
optionPrintParagraphs(char const * text, bool plain, FILE * fp)
468
0
{
469
0
    size_t len = strlen(text);
470
0
    char * buf;
471
0
#ifndef ENABLE_NLS
472
0
    if (plain || (len < 256))
473
#else
474
    if (len < 256)
475
#endif
476
0
    {
477
0
        print_one_paragraph(text, plain, fp);
478
0
        return;
479
0
    }
480
481
0
    AGDUPSTR(buf, text, "ppara");
482
0
    text = buf;
483
484
0
    for (;;) {
485
0
        char * scan;
486
487
0
        if (len < 256) {
488
0
        done:
489
0
            print_one_paragraph(buf, plain, fp);
490
0
            break;
491
0
        }
492
0
        scan = buf;
493
494
0
    try_longer:
495
0
        scan = strchr(scan, NL);
496
0
        if (scan == NULL)
497
0
            goto done;
498
499
0
        if ((scan - buf) < 40) {
500
0
            scan++;
501
0
            goto try_longer;
502
0
        }
503
504
0
        scan++;
505
0
        if ((! isspace((int)*scan)) || (*scan == HT))
506
            /*
507
             * line starts with tab or non-whitespace --> continuation
508
             */
509
0
            goto try_longer;
510
511
0
        if (*scan == NL) {
512
            /*
513
             * Double newline -> paragraph break
514
             * Include all newlines in current paragraph.
515
             */
516
0
            while (*++scan == NL)  /*continue*/;
517
518
0
        } else {
519
0
            char * p = scan;
520
0
            int   sp_ct = 0;
521
522
0
            while (*p == ' ') {
523
0
                if (++sp_ct >= 8) {
524
                    /*
525
                     * Too many spaces --> continuation line
526
                     */
527
0
                    scan = p;
528
0
                    goto try_longer;
529
0
                }
530
0
                p++;
531
0
            }
532
0
        }
533
534
        /*
535
         * "scan" points to the first character of a paragraph or the
536
         * terminating NUL byte.
537
         */
538
0
        {
539
0
            char svch = *scan;
540
0
            *scan = NUL;
541
0
            print_one_paragraph(buf, plain, fp);
542
0
            len -= scan - buf;
543
0
            if (len <= 0)
544
0
                break;
545
0
            *scan = svch;
546
0
            buf = scan;
547
0
        }
548
0
    }
549
0
    AGFREE(text);
550
0
}
551
552
/*=export_func  optionUsage
553
 * private:
554
 *
555
 * what:  Print usage text
556
 * arg:   + tOptions * + opts + program options descriptor +
557
 * arg:   + int        + exitCode + exit code for calling exit(3) +
558
 *
559
 * doc:
560
 *  This routine will print usage in both GNU-standard and AutoOpts-expanded
561
 *  formats.  The descriptor specifies the default, but AUTOOPTS_USAGE will
562
 *  over-ride this, providing the value of it is set to either "gnu" or
563
 *  "autoopts".  This routine will @strong{not} return.
564
 *
565
 *  If "exitCode" is "AO_EXIT_REQ_USAGE" (normally 64), then output will to
566
 *  to stdout and the actual exit code will be "EXIT_SUCCESS".
567
=*/
568
void
569
optionUsage(tOptions * opts, int usage_exit_code)
570
0
{
571
0
    int exit_code = (usage_exit_code == AO_EXIT_REQ_USAGE)
572
0
        ? EXIT_SUCCESS : usage_exit_code;
573
574
0
    displayEnum = false;
575
0
    set_usage_flags(opts, NULL);
576
577
    /*
578
     *  Paged usage will preset option_usage_fp to an output file.
579
     *  If it hasn't already been set, then set it to standard output
580
     *  on successful exit (help was requested), otherwise error out.
581
     *
582
     *  Test the version before obtaining pzFullUsage or pzShortUsage.
583
     *  These fields do not exist before revision 30.
584
     */
585
0
    {
586
0
        char const * pz;
587
588
0
        if (exit_code == EXIT_SUCCESS) {
589
0
            pz = (opts->structVersion >= 30 * 4096)
590
0
                ? opts->pzFullUsage : NULL;
591
592
0
            if (option_usage_fp == NULL)
593
0
                option_usage_fp = print_exit ? stderr : stdout;
594
595
0
        } else {
596
0
            pz = (opts->structVersion >= 30 * 4096)
597
0
                ? opts->pzShortUsage : NULL;
598
599
0
            if (option_usage_fp == NULL)
600
0
                option_usage_fp = stderr;
601
0
        }
602
603
0
        if (((opts->fOptSet & OPTPROC_COMPUTE) == 0) && (pz != NULL)) {
604
0
            if ((opts->fOptSet & OPTPROC_TRANSLATE) != 0)
605
0
                optionPrintParagraphs(pz, true, option_usage_fp);
606
0
            else
607
0
                fputs(pz, option_usage_fp);
608
0
            goto flush_and_exit;
609
0
        }
610
0
    }
611
612
0
    fprintf(option_usage_fp, opts->pzUsageTitle, opts->pzProgName);
613
614
0
    if ((exit_code == EXIT_SUCCESS) ||
615
0
        (! skip_misuse_usage(opts)))
616
617
0
        print_usage_details(opts, usage_exit_code);
618
0
    else
619
0
        print_offer_usage(opts);
620
    
621
0
 flush_and_exit:
622
0
    fflush(option_usage_fp);
623
0
    if (ferror(option_usage_fp) != 0)
624
0
        fserr_exit(opts->pzProgName, zwriting, (option_usage_fp == stdout)
625
0
                   ? zstdout_name : zstderr_name);
626
627
0
    option_exits(exit_code);
628
0
}
629
630
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
631
 *   PER OPTION TYPE USAGE INFORMATION
632
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
633
/**
634
 * print option conflicts.
635
 *
636
 * @param opts the program option descriptor
637
 * @param od   the option descriptor
638
 */
639
static void
640
prt_conflicts(tOptions * opts, tOptDesc * od)
641
0
{
642
0
    const int * opt_no;
643
0
    fputs(zTabHyp + tab_skip_ct, option_usage_fp);
644
645
    /*
646
     *  REQUIRED:
647
     */
648
0
    if (od->pOptMust != NULL) {
649
0
        opt_no = od->pOptMust;
650
651
0
        if (opt_no[1] == NO_EQUIVALENT) {
652
0
            fprintf(option_usage_fp, zReqOne,
653
0
                    opts->pOptDesc[*opt_no].pz_Name);
654
0
        } else {
655
0
            fputs(zReqThese, option_usage_fp);
656
0
            for (;;) {
657
0
                fprintf(option_usage_fp, zTabout + tab_skip_ct,
658
0
                        opts->pOptDesc[*opt_no].pz_Name);
659
0
                if (*++opt_no == NO_EQUIVALENT)
660
0
                    break;
661
0
            }
662
0
        }
663
664
0
        if (od->pOptCant != NULL)
665
0
            fputs(zTabHypAnd + tab_skip_ct, option_usage_fp);
666
0
    }
667
668
    /*
669
     *  CONFLICTS:
670
     */
671
0
    if (od->pOptCant == NULL)
672
0
        return;
673
674
0
    opt_no = od->pOptCant;
675
676
0
    if (opt_no[1] == NO_EQUIVALENT) {
677
0
        fprintf(option_usage_fp, zProhibOne,
678
0
                opts->pOptDesc[*opt_no].pz_Name);
679
0
        return;
680
0
    }
681
682
0
    fputs(zProhib, option_usage_fp);
683
0
    for (;;) {
684
0
        fprintf(option_usage_fp, zTabout + tab_skip_ct,
685
0
                opts->pOptDesc[*opt_no].pz_Name);
686
0
        if (*++opt_no == NO_EQUIVALENT)
687
0
            break;
688
0
    }
689
0
}
690
691
/**
692
 *  Print the usage information for a single vendor option.
693
 *
694
 * @param[in] opts    the program option descriptor
695
 * @param[in] od      the option descriptor
696
 * @param[in] argtp   names of the option argument types
697
 * @param[in] usefmt  format for primary usage line
698
 */
699
static void
700
prt_one_vendor(tOptions *    opts,  tOptDesc *   od,
701
               arg_types_t * argtp, char const * usefmt)
702
0
{
703
0
    prt_preamble(opts, od, argtp);
704
705
0
    {
706
0
        char z[ 80 ];
707
0
        char const *  pzArgType;
708
709
        /*
710
         *  Determine the argument type string first on its usage, then,
711
         *  when the option argument is required, base the type string on the
712
         *  argument type.
713
         */
714
0
        if (od->fOptState & OPTST_ARG_OPTIONAL) {
715
0
            pzArgType = argtp->pzOpt;
716
717
0
        } else switch (OPTST_GET_ARGTYPE(od->fOptState)) {
718
0
        case OPARG_TYPE_NONE:        pzArgType = argtp->pzNo;   break;
719
0
        case OPARG_TYPE_ENUMERATION: pzArgType = argtp->pzKey;  break;
720
0
        case OPARG_TYPE_FILE:        pzArgType = argtp->pzFile; break;
721
0
        case OPARG_TYPE_MEMBERSHIP:  pzArgType = argtp->pzKeyL; break;
722
0
        case OPARG_TYPE_BOOLEAN:     pzArgType = argtp->pzBool; break;
723
0
        case OPARG_TYPE_NUMERIC:     pzArgType = argtp->pzNum;  break;
724
0
        case OPARG_TYPE_HIERARCHY:   pzArgType = argtp->pzNest; break;
725
0
        case OPARG_TYPE_STRING:      pzArgType = argtp->pzStr;  break;
726
0
        case OPARG_TYPE_TIME:        pzArgType = argtp->pzTime; break;
727
0
        default:                     goto bogus_desc;
728
0
        }
729
730
0
        pzArgType = SPN_WHITESPACE_CHARS(pzArgType);
731
0
        if (*pzArgType == NUL)
732
0
            snprintf(z, sizeof(z), "%s", od->pz_Name);
733
0
        else
734
0
            snprintf(z, sizeof(z), "%s=%s", od->pz_Name, pzArgType);
735
0
        fprintf(option_usage_fp, usefmt, z, od->pzText);
736
737
0
        switch (OPTST_GET_ARGTYPE(od->fOptState)) {
738
0
        case OPARG_TYPE_ENUMERATION:
739
0
        case OPARG_TYPE_MEMBERSHIP:
740
0
            displayEnum = (od->pOptProc != NULL) ? true : displayEnum;
741
0
        }
742
0
    }
743
744
0
    return;
745
746
0
 bogus_desc:
747
0
    fprintf(stderr, zbad_od, opts->pzProgName, od->pz_Name);
748
0
    ao_bug(zbad_arg_type_msg);
749
0
}
750
751
/**
752
 * Print the long options processed with "-W".  These options will be the
753
 * ones that do *not* have flag characters.
754
 *
755
 * @param opts  the program option descriptor
756
 * @param title the title for the options
757
 */
758
static void
759
prt_vendor_opts(tOptions * opts, char const * title)
760
0
{
761
0
    static unsigned int const not_vended_mask =
762
0
        OPTST_NO_USAGE_MASK | OPTST_DOCUMENT;
763
764
0
    static char const vfmtfmt[] = "%%-%us %%s\n";
765
0
    char vfmt[sizeof(vfmtfmt)];
766
767
    /*
768
     *  Only handle client specified options.  The "vendor option" follows
769
     *  "presetOptCt", so we won't loop/recurse indefinitely.
770
     */
771
0
    int          ct     = opts->presetOptCt;
772
0
    tOptDesc *   od     = opts->pOptDesc;
773
0
    fprintf(option_usage_fp, zTabout + tab_skip_ct, zVendOptsAre);
774
775
0
    {
776
0
        size_t   nmlen  = 0;
777
0
        do  {
778
0
            size_t l;
779
0
            if (  ((od->fOptState & not_vended_mask) != 0)
780
0
               || IS_GRAPHIC_CHAR(od->optValue))
781
0
                continue;
782
783
0
            l = strlen(od->pz_Name);
784
0
            if (l > nmlen)  nmlen = l;
785
0
        } while (od++, (--ct > 0));
786
787
0
        snprintf(vfmt, sizeof(vfmt), vfmtfmt, (unsigned int)nmlen + 4);
788
0
    }
789
790
0
    if (tab_skip_ct > 0)
791
0
        tab_skip_ct--;
792
793
0
    ct    = opts->presetOptCt;
794
0
    od    = opts->pOptDesc;
795
796
0
    do  {
797
0
        if (  ((od->fOptState & not_vended_mask) != 0)
798
0
           || IS_GRAPHIC_CHAR(od->optValue))
799
0
            continue;
800
801
0
        prt_one_vendor(opts, od, &argTypes, vfmt);
802
0
        prt_extd_usage(opts, od, title);
803
804
0
    } while (od++, (--ct > 0));
805
806
    /* no need to restore "tab_skip_ct" - options are done now */
807
0
}
808
809
/**
810
 * Print extended usage.  Usage/help was requested.
811
 *
812
 * @param opts  the program option descriptor
813
 * @param od   the option descriptor
814
 * @param title the title for the options
815
 */
816
static void
817
prt_extd_usage(tOptions * opts, tOptDesc * od, char const * title)
818
0
{
819
0
    if (  ((opts->fOptSet & OPTPROC_VENDOR_OPT) != 0)
820
0
       && (od->optActualValue == VENDOR_OPTION_VALUE)) {
821
0
        prt_vendor_opts(opts, title);
822
0
        return;
823
0
    }
824
825
    /*
826
     *  IF there are option conflicts or dependencies,
827
     *  THEN print them here.
828
     */
829
0
    if ((od->pOptMust != NULL) || (od->pOptCant != NULL))
830
0
        prt_conflicts(opts, od);
831
832
    /*
833
     *  IF there is a disablement string
834
     *  THEN print the disablement info
835
     */
836
0
    if (od->pz_DisableName != NULL )
837
0
        fprintf(option_usage_fp, zDis + tab_skip_ct, od->pz_DisableName);
838
839
    /*
840
     *  Check for argument types that have callbacks with magical properties
841
     */
842
0
    switch (OPTST_GET_ARGTYPE(od->fOptState)) {
843
0
    case OPARG_TYPE_NUMERIC:
844
        /*
845
         *  IF the numeric option has a special callback,
846
         *  THEN call it, requesting the range or other special info
847
         */
848
0
        if (  (od->pOptProc != NULL)
849
0
           && (od->pOptProc != optionNumericVal) ) {
850
0
            (*(od->pOptProc))(OPTPROC_EMIT_USAGE, od);
851
0
        }
852
0
        break;
853
854
0
    case OPARG_TYPE_FILE:
855
0
        (*(od->pOptProc))(OPTPROC_EMIT_USAGE, od);
856
0
        break;
857
0
    }
858
859
    /*
860
     *  IF the option defaults to being enabled,
861
     *  THEN print that out
862
     */
863
0
    if (od->fOptState & OPTST_INITENABLED)
864
0
        fputs(zEnab + tab_skip_ct, option_usage_fp);
865
866
    /*
867
     *  IF  the option is in an equivalence class
868
     *        AND not the designated lead
869
     *  THEN print equivalence and leave it at that.
870
     */
871
0
    if (  (od->optEquivIndex != NO_EQUIVALENT)
872
0
       && (od->optEquivIndex != od->optActualIndex )  )  {
873
0
        fprintf(option_usage_fp, zalt_opt + tab_skip_ct,
874
0
                 opts->pOptDesc[ od->optEquivIndex ].pz_Name);
875
0
        return;
876
0
    }
877
878
    /*
879
     *  IF this particular option can NOT be preset
880
     *    AND some form of presetting IS allowed,
881
     *    AND it is not an auto-managed option (e.g. --help, et al.)
882
     *  THEN advise that this option may not be preset.
883
     */
884
0
    if (  ((od->fOptState & OPTST_NO_INIT) != 0)
885
0
       && (  (opts->papzHomeList != NULL)
886
0
          || (opts->pzPROGNAME != NULL)
887
0
          )
888
0
       && (od->optIndex < opts->presetOptCt)
889
0
       )
890
891
0
        fputs(zNoPreset + tab_skip_ct, option_usage_fp);
892
893
    /*
894
     *  Print the appearance requirements.
895
     */
896
0
    if (OPTST_GET_ARGTYPE(od->fOptState) == OPARG_TYPE_MEMBERSHIP)
897
0
        fputs(zMembers + tab_skip_ct, option_usage_fp);
898
899
0
    else switch (od->optMinCt) {
900
0
    case 1:
901
0
    case 0:
902
0
        switch (od->optMaxCt) {
903
0
        case 0:       fputs(zPreset + tab_skip_ct, option_usage_fp); break;
904
0
        case NOLIMIT: fputs(zNoLim  + tab_skip_ct, option_usage_fp); break;
905
0
        case 1:       break;
906
            /*
907
             * IF the max is more than one but limited, print "UP TO" message
908
             */
909
0
        default:
910
0
            fprintf(option_usage_fp, zUpTo + tab_skip_ct, od->optMaxCt); break;
911
0
        }
912
0
        break;
913
914
0
    default:
915
        /*
916
         *  More than one is required.  Print the range.
917
         */
918
0
        fprintf(option_usage_fp, zMust + tab_skip_ct,
919
0
                od->optMinCt, od->optMaxCt);
920
0
    }
921
922
0
    if (  NAMED_OPTS(opts)
923
0
       && (opts->specOptIdx.default_opt == od->optIndex))
924
0
        fputs(zDefaultOpt + tab_skip_ct, option_usage_fp);
925
0
}
926
927
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
928
/**
929
 * Figure out where all the initialization files might live.  This requires
930
 * translating some environment variables and testing to see if a name is a
931
 * directory or a file.  It's squishy, but important to tell users how to
932
 * find these files.
933
 *
934
 * @param[in]  papz        search path
935
 * @param[out] ini_file    an output buffer of AG_PATH_MAX+1 bytes
936
 * @param[in]  path_nm     the name of the file we're hunting for
937
 */
938
static void
939
prt_ini_list(char const * const * papz, char const * ini_file,
940
             char const * path_nm)
941
0
{
942
0
    char pth_buf[AG_PATH_MAX+1];
943
944
0
    fputs(zPresetIntro, option_usage_fp);
945
946
0
    for (;;) {
947
0
        char const * path   = *(papz++);
948
0
        char const * nm_buf = pth_buf;
949
950
0
        if (path == NULL)
951
0
            break;
952
953
        /*
954
         * Ignore any invalid paths
955
         */
956
0
        if (! optionMakePath(pth_buf, (int)sizeof(pth_buf), path, path_nm))
957
0
            nm_buf = path;
958
959
        /*
960
         * Expand paths that are relative to the executable or installation
961
         * directories.  Leave alone paths that use environment variables.
962
         */
963
0
        else if ((*path == '$')
964
0
                 && ((path[1] == '$') || (path[1] == '@')))
965
0
            path = nm_buf;
966
967
        /*
968
         *  Print the name of the "homerc" file.  If the "rcfile" name is
969
         *  not empty, we may or may not print that, too...
970
         */
971
0
        fprintf(option_usage_fp, zPathFmt, path);
972
0
        if (*ini_file != NUL) {
973
0
            struct stat sb;
974
975
            /*
976
             *  IF the "homerc" file is a directory,
977
             *  then append the "rcfile" name.
978
             */
979
0
            if ((stat(nm_buf, &sb) == 0) && S_ISDIR(sb.st_mode)) {
980
0
                fputc(DIRCH,    option_usage_fp);
981
0
                fputs(ini_file, option_usage_fp);
982
0
            }
983
0
        }
984
985
0
        fputc(NL, option_usage_fp);
986
0
    }
987
0
}
988
989
/**
990
 *  Print the usage line preamble text
991
 *
992
 * @param opts  the program option descriptor
993
 * @param od    the option descriptor
994
 * @param at    names of the option argument types
995
 */
996
static void
997
prt_preamble(tOptions * opts, tOptDesc * od, arg_types_t * at)
998
0
{
999
    /*
1000
     *  Flag prefix: IF no flags at all, then omit it.  If not printable
1001
     *  (not allowed for this option), then blank, else print it.
1002
     *  Follow it with a comma if we are doing GNU usage and long
1003
     *  opts are to be printed too.
1004
     */
1005
0
    if ((opts->fOptSet & OPTPROC_SHORTOPT) == 0)
1006
0
        fputs(at->pzSpc, option_usage_fp);
1007
1008
0
    else if (! IS_GRAPHIC_CHAR(od->optValue)) {
1009
0
        if (  (opts->fOptSet & (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT))
1010
0
           == (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT))
1011
0
            fputc(' ', option_usage_fp);
1012
0
        fputs(at->pzNoF, option_usage_fp);
1013
1014
0
    } else {
1015
0
        fprintf(option_usage_fp, "   -%c", od->optValue);
1016
0
        if (  (opts->fOptSet & (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT))
1017
0
           == (OPTPROC_GNUUSAGE|OPTPROC_LONGOPT))
1018
0
            fputs(", ", option_usage_fp);
1019
0
    }
1020
0
}
1021
1022
/**
1023
 *  Print the usage information for a single option.
1024
 *
1025
 * @param opts  the program option descriptor
1026
 * @param od    the option descriptor
1027
 * @param at    names of the option argument types
1028
 */
1029
static void
1030
prt_one_usage(tOptions * opts, tOptDesc * od, arg_types_t * at)
1031
0
{
1032
0
    prt_preamble(opts, od, at);
1033
1034
0
    {
1035
0
        char z[80];
1036
0
        char const * atyp;
1037
1038
        /*
1039
         *  Determine the argument type string first on its usage, then,
1040
         *  when the option argument is required, base the type string on the
1041
         *  argument type.
1042
         */
1043
0
        if (od->fOptState & OPTST_ARG_OPTIONAL) {
1044
0
            atyp = at->pzOpt;
1045
1046
0
        } else switch (OPTST_GET_ARGTYPE(od->fOptState)) {
1047
0
        case OPARG_TYPE_NONE:        atyp = at->pzNo;   break;
1048
0
        case OPARG_TYPE_ENUMERATION: atyp = at->pzKey;  break;
1049
0
        case OPARG_TYPE_FILE:        atyp = at->pzFile; break;
1050
0
        case OPARG_TYPE_MEMBERSHIP:  atyp = at->pzKeyL; break;
1051
0
        case OPARG_TYPE_BOOLEAN:     atyp = at->pzBool; break;
1052
0
        case OPARG_TYPE_NUMERIC:     atyp = at->pzNum;  break;
1053
0
        case OPARG_TYPE_HIERARCHY:   atyp = at->pzNest; break;
1054
0
        case OPARG_TYPE_STRING:      atyp = at->pzStr;  break;
1055
0
        case OPARG_TYPE_TIME:        atyp = at->pzTime; break;
1056
0
        default:                     goto bogus_desc;
1057
0
        }
1058
1059
#ifdef _WIN32
1060
        if (at->pzOptFmt == zGnuOptFmt)
1061
            snprintf(z, sizeof(z), "--%s%s", od->pz_Name, atyp);
1062
        else if (at->pzOptFmt == zGnuOptFmt + 2)
1063
            snprintf(z, sizeof(z), "%s%s", od->pz_Name, atyp);
1064
        else
1065
#endif
1066
0
        snprintf(z, sizeof(z), at->pzOptFmt, atyp, od->pz_Name,
1067
0
                 (od->optMinCt != 0) ? at->pzReq : at->pzOpt);
1068
1069
0
        fprintf(option_usage_fp, line_fmt_buf, z, od->pzText);
1070
1071
0
        switch (OPTST_GET_ARGTYPE(od->fOptState)) {
1072
0
        case OPARG_TYPE_ENUMERATION:
1073
0
        case OPARG_TYPE_MEMBERSHIP:
1074
0
            displayEnum = (od->pOptProc != NULL) ? true : displayEnum;
1075
0
        }
1076
0
    }
1077
1078
0
    return;
1079
1080
0
 bogus_desc:
1081
0
    fprintf(stderr, zbad_od, opts->pzProgName, od->pz_Name);
1082
0
    option_exits(EX_SOFTWARE);
1083
0
}
1084
1085
/**
1086
 *  Print out the usage information for just the options.
1087
 */
1088
static void
1089
prt_opt_usage(tOptions * opts, int ex_code, char const * title)
1090
0
{
1091
0
    int         ct     = opts->optCt;
1092
0
    int         optNo  = 0;
1093
0
    tOptDesc *  od     = opts->pOptDesc;
1094
0
    int         docCt  = 0;
1095
1096
0
    do  {
1097
        /*
1098
         * no usage --> disallowed on command line (OPTST_NO_COMMAND), or
1099
         * deprecated -- strongly discouraged (OPTST_DEPRECATED), or
1100
         * compiled out of current object code (OPTST_OMITTED)
1101
         */
1102
0
        if ((od->fOptState & OPTST_NO_USAGE_MASK) != 0) {
1103
1104
            /*
1105
             * IF      this is a compiled-out option
1106
             *   *AND* usage was requested with "omitted-usage"
1107
             *   *AND* this is NOT abbreviated usage
1108
             * THEN display this option.
1109
             */
1110
0
            if (  (od->fOptState == (OPTST_OMITTED | OPTST_NO_INIT))
1111
0
               && (od->pz_Name != NULL)
1112
0
               && (ex_code == EXIT_SUCCESS))  {
1113
1114
0
                char const * why_pz =
1115
0
                    (od->pzText == NULL) ? zDisabledWhy : od->pzText;
1116
0
                prt_preamble(opts, od, &argTypes);
1117
0
                fprintf(option_usage_fp, zDisabledOpt, od->pz_Name, why_pz);
1118
0
            }
1119
1120
0
            continue;
1121
0
        }
1122
1123
0
        if ((od->fOptState & OPTST_DOCUMENT) != 0) {
1124
0
            if (ex_code == EXIT_SUCCESS) {
1125
0
                fprintf(option_usage_fp, argTypes.pzBrk, od->pzText,
1126
0
                        title);
1127
0
                docCt++;
1128
0
            }
1129
1130
0
            continue;
1131
0
        }
1132
1133
        /* Skip name only options when we have a vendor option */
1134
0
        if (  ((opts->fOptSet & OPTPROC_VENDOR_OPT) != 0)
1135
0
           && (! IS_GRAPHIC_CHAR(od->optValue)))
1136
0
            continue;
1137
1138
        /*
1139
         *  IF       this is the first auto-opt maintained option
1140
         *    *AND*  we are doing a full help
1141
         *    *AND*  there are documentation options
1142
         *    *AND*  the last one was not a doc option,
1143
         *  THEN document that the remaining options are not user opts
1144
         */
1145
0
        if ((docCt > 0) && (ex_code == EXIT_SUCCESS)) {
1146
0
            if (opts->presetOptCt == optNo) {
1147
0
                if ((od[-1].fOptState & OPTST_DOCUMENT) == 0)
1148
0
                    fprintf(option_usage_fp, argTypes.pzBrk, zAuto, title);
1149
1150
0
            } else if ((ct == 1) &&
1151
0
                       (opts->fOptSet & OPTPROC_VENDOR_OPT))
1152
0
                fprintf(option_usage_fp, argTypes.pzBrk, zVendIntro, title);
1153
0
        }
1154
1155
0
        prt_one_usage(opts, od, &argTypes);
1156
1157
        /*
1158
         *  IF we were invoked because of the --help option,
1159
         *  THEN print all the extra info
1160
         */
1161
0
        if (ex_code == EXIT_SUCCESS)
1162
0
            prt_extd_usage(opts, od, title);
1163
1164
0
    } while (od++, optNo++, (--ct > 0));
1165
1166
0
    fputc(NL, option_usage_fp);
1167
0
}
1168
1169
1170
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1171
/**
1172
 *  Print program details.
1173
 * @param[in] opts  the program option descriptor
1174
 */
1175
static void
1176
prt_prog_detail(tOptions * opts)
1177
0
{
1178
0
    bool need_intro = (opts->papzHomeList == NULL);
1179
1180
    /*
1181
     *  Display all the places we look for config files, if we have
1182
     *  a list of directories to search.
1183
     */
1184
0
    if (! need_intro)
1185
0
        prt_ini_list(opts->papzHomeList, opts->pzRcName, opts->pzProgPath);
1186
1187
    /*
1188
     *  Let the user know about environment variable settings
1189
     */
1190
0
    if ((opts->fOptSet & OPTPROC_ENVIRON) != 0) {
1191
0
        if (need_intro)
1192
0
            fputs(zPresetIntro, option_usage_fp);
1193
1194
0
        fprintf(option_usage_fp, zExamineFmt, opts->pzPROGNAME);
1195
0
    }
1196
1197
    /*
1198
     *  IF we found an enumeration,
1199
     *  THEN hunt for it again.  Call the handler proc with a NULL
1200
     *       option struct pointer.  That tells it to display the keywords.
1201
     */
1202
0
    if (displayEnum) {
1203
0
        int        ct     = opts->optCt;
1204
0
        int        optNo  = 0;
1205
0
        tOptDesc * od     = opts->pOptDesc;
1206
1207
0
        fputc(NL, option_usage_fp);
1208
0
        fflush(option_usage_fp);
1209
0
        do  {
1210
0
            switch (OPTST_GET_ARGTYPE(od->fOptState)) {
1211
0
            case OPARG_TYPE_ENUMERATION:
1212
0
            case OPARG_TYPE_MEMBERSHIP:
1213
0
                (*(od->pOptProc))(OPTPROC_EMIT_USAGE, od);
1214
0
            }
1215
0
        } while (od++, optNo++, (--ct > 0));
1216
0
    }
1217
1218
    /*
1219
     *  If there is a detail string, now is the time for that.
1220
     */
1221
0
    if (opts->pzDetail != NULL)
1222
0
        fputs(opts->pzDetail, option_usage_fp);
1223
0
}
1224
1225
1226
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
1227
 *
1228
 *   OPTION LINE FORMATTING SETUP
1229
 *
1230
 *  The "OptFmt" formats receive three arguments:
1231
 *  1.  the type of the option's argument
1232
 *  2.  the long name of the option
1233
 *  3.  "YES" or "no ", depending on whether or not the option must appear
1234
 *      on the command line.
1235
 *  These formats are used immediately after the option flag (if used) has
1236
 *  been printed.
1237
 *
1238
 *  Set up the formatting for GNU-style output
1239
 */
1240
static int
1241
setGnuOptFmts(tOptions * opts, char const ** ptxt)
1242
0
{
1243
0
    static char const zOneSpace[] = " ";
1244
0
    int  flen = 22;
1245
0
    *ptxt = zNoRq_ShrtTtl;
1246
1247
0
    argTypes.pzStr  = zGnuStrArg;
1248
0
    argTypes.pzReq  = zOneSpace;
1249
0
    argTypes.pzNum  = zGnuNumArg;
1250
0
    argTypes.pzKey  = zGnuKeyArg;
1251
0
    argTypes.pzKeyL = zGnuKeyLArg;
1252
0
    argTypes.pzTime = zGnuTimeArg;
1253
0
    argTypes.pzFile = zGnuFileArg;
1254
0
    argTypes.pzBool = zGnuBoolArg;
1255
0
    argTypes.pzNest = zGnuNestArg;
1256
0
    argTypes.pzOpt  = zGnuOptArg;
1257
0
    argTypes.pzNo   = zOneSpace;
1258
0
    argTypes.pzBrk  = zGnuBreak;
1259
0
    argTypes.pzNoF  = zSixSpaces;
1260
0
    argTypes.pzSpc  = zThreeSpaces;
1261
1262
0
    switch (opts->fOptSet & OPTPROC_L_N_S) {
1263
0
    case OPTPROC_L_N_S:    argTypes.pzOptFmt = zGnuOptFmt;     break;
1264
0
    case OPTPROC_LONGOPT:  argTypes.pzOptFmt = zGnuOptFmt;     break;
1265
0
    case 0:                argTypes.pzOptFmt = zGnuOptFmt + 2; break;
1266
0
    case OPTPROC_SHORTOPT:
1267
0
        argTypes.pzOptFmt = zShrtGnuOptFmt;
1268
0
        zGnuStrArg[0] = zGnuNumArg[0] = zGnuKeyArg[0] = zGnuBoolArg[0] = ' ';
1269
0
        argTypes.pzOpt = " [arg]";
1270
0
        flen = 8;
1271
0
        break;
1272
0
    }
1273
1274
0
    return flen;
1275
0
}
1276
1277
1278
/*
1279
 *  Standard (AutoOpts normal) option line formatting
1280
 */
1281
static int
1282
setStdOptFmts(tOptions * opts, char const ** ptxt)
1283
0
{
1284
0
    int  flen = 0;
1285
1286
0
    argTypes.pzStr  = zStdStrArg;
1287
0
    argTypes.pzReq  = zStdReqArg;
1288
0
    argTypes.pzNum  = zStdNumArg;
1289
0
    argTypes.pzKey  = zStdKeyArg;
1290
0
    argTypes.pzKeyL = zStdKeyLArg;
1291
0
    argTypes.pzTime = zStdTimeArg;
1292
0
    argTypes.pzFile = zStdFileArg;
1293
0
    argTypes.pzBool = zStdBoolArg;
1294
0
    argTypes.pzNest = zStdNestArg;
1295
0
    argTypes.pzOpt  = zStdOptArg;
1296
0
    argTypes.pzNo   = zStdNoArg;
1297
0
    argTypes.pzBrk  = zStdBreak;
1298
0
    argTypes.pzNoF  = zFiveSpaces;
1299
0
    argTypes.pzSpc  = zTwoSpaces;
1300
1301
0
    switch (opts->fOptSet & (OPTPROC_NO_REQ_OPT | OPTPROC_SHORTOPT)) {
1302
0
    case (OPTPROC_NO_REQ_OPT | OPTPROC_SHORTOPT):
1303
0
        *ptxt = zNoRq_ShrtTtl;
1304
0
        argTypes.pzOptFmt = zNrmOptFmt;
1305
0
        flen = 19;
1306
0
        break;
1307
1308
0
    case OPTPROC_NO_REQ_OPT:
1309
0
        *ptxt = zNoRq_NoShrtTtl;
1310
0
        argTypes.pzOptFmt = zNrmOptFmt;
1311
0
        flen = 19;
1312
0
        break;
1313
1314
0
    case OPTPROC_SHORTOPT:
1315
0
        *ptxt = zReq_ShrtTtl;
1316
0
        argTypes.pzOptFmt = zReqOptFmt;
1317
0
        flen = 24;
1318
0
        break;
1319
1320
0
    case 0:
1321
0
        *ptxt = zReq_NoShrtTtl;
1322
0
        argTypes.pzOptFmt = zReqOptFmt;
1323
0
        flen = 24;
1324
0
    }
1325
1326
0
    return flen;
1327
0
}
1328
1329
/** @}
1330
 *
1331
 * Local Variables:
1332
 * mode: C
1333
 * c-file-style: "stroustrup"
1334
 * indent-tabs-mode: nil
1335
 * End:
1336
 * end of autoopts/usage.c */