Coverage Report

Created: 2026-02-26 06:20

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